/*
SQLiteAdaptor.m
- Copyright (C) 2003 SKYRIX Software AG
+ Copyright (C) 2003-2005 SKYRIX Software AG
Author: Helge Hess (helge.hess@skyrix.com)
If not, write to the Free Software Foundation,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-// $Id: SQLiteAdaptor.m,v 1.1 2004/06/14 14:27:44 helge Exp $
#import "common.h"
#import "SQLiteAdaptor.h"
@implementation SQLiteAdaptor
+- (NSDictionary *)connectionDictionaryForNSURL:(NSURL *)_url {
+ /*
+ "Database URLs"
+
+ We use the schema:
+ SQLite3://localhost/dbpath/foldername
+ */
+ NSMutableDictionary *md;
+ NSString *p;
+
+ if ((p = [_url path]) == nil)
+ return nil;
+
+ p = [p stringByDeletingLastPathComponent];
+ if ([p length] == 0) p = [_url path];
+
+ md = [NSMutableDictionary dictionaryWithCapacity:8];
+ [md setObject:p forKey:@"databaseName"];
+ return md;
+}
+
- (id)initWithName:(NSString *)_name {
if ((self = [super initWithName:_name])) {
}
}
- (BOOL)openChannel {
+ const unsigned char *cDBName;
SQLiteAdaptor *adaptor;
int rc;
}
adaptor = (SQLiteAdaptor *)[adaptorContext adaptor];
-
+
if (![super openChannel])
return NO;
format:@"cannot open a additional connection !"];
return NO;
}
+
+ cDBName = [[adaptor databaseName] UTF8String];
- rc = sqlite3_open([[adaptor databaseName] UTF8String],
- (void *)&(self->_connection));
+ rc = sqlite3_open(cDBName, (void *)&(self->_connection));
if (rc != SQLITE_OK) {
// could not login ..
// Note: connection *is* set! (might be required to deallocate)
#endif
if (isDebuggingEnabled) {
- NSLog(@"SQLite channel 0x%08X opened (connection=0x%08X)",
- (unsigned)self, self->_connection);
+ NSLog(@"SQLite channel 0x%08X opened (connection=0x%08X,%s)",
+ (unsigned)self, self->_connection, cDBName);
}
return YES;
}
- (NSException *)_makeSQLiteStep {
NSString *r;
+ const char *em;
int rc;
rc = sqlite3_step(self->statement);
+#if 0
+ NSLog(@"STEP: %i (row=%i, done=%i, mis=%i)", rc,
+ SQLITE_ROW, SQLITE_DONE, SQLITE_MISUSE);
+#endif
if (rc == SQLITE_ROW) {
self->hasPendingRow = YES;
+ self->isDone = NO;
return nil /* no error */;
}
if (rc == SQLITE_DONE) {
self->hasPendingRow = NO;
+ self->isDone = YES;
return nil /* no error */;
}
if (rc == SQLITE_ERROR)
r = [NSString stringWithUTF8String:sqlite3_errmsg(self->_connection)];
else if (rc == SQLITE_MISUSE)
- r = @"Somehow the SQLite method was called in an incorrect way.";
+ r = @"The SQLite step function was called in an incorrect way";
else if (rc == SQLITE_BUSY)
r = @"The SQLite is busy.";
else
r = [NSString stringWithFormat:@"Unexpected SQLite error: %i", rc];
+
+ if ((em = sqlite3_errmsg(self->_connection)) != NULL)
+ r = [r stringByAppendingFormat:@": %s", em];
return [SQLiteException exceptionWithName:@"FetchFailed"
reason:r userInfo:nil];
sqlite3_finalize(self->statement);
self->statement = NULL;
}
+ self->isDone = NO;
+ self->hasPendingRow = NO;
[super cancelFetch];
}
return nil;
}
- if (!self->hasPendingRow) {
+ if (!self->hasPendingRow && !self->isDone) {
if ((error = [self _makeSQLiteStep]) != nil) {
[self cancelFetch];
[error raise]; // raise error, TODO: make exception-less method
return nil;
}
}
- if (!self->hasPendingRow) { /* step was fine, but we are at the end */
+ if (self->isDone) { /* step was fine, but we are at the end */
[self cancelFetch];
return nil;
}
- (NSException *)evaluateExpressionX:(NSString *)_expression {
NSMutableString *sql;
NSException *error;
- char *zErrMsg = NULL;
BOOL result;
const char *s;
const char *tails = NULL;
}
sql = [[_expression mutableCopy] autorelease];
+ [sql appendString:@";"];
/* ask delegate */
/* reset environment */
self->isFetchInProgress = NO;
+ self->isDone = NO;
+ self->hasPendingRow = NO;
s = [sql UTF8String];
rc = sqlite3_prepare(self->_connection, s, strlen(s),
(void *)&(self->statement), &tails);
if (rc != SQLITE_OK) {
+ NSString *r;
+
[self cancelFetch];
// TODO: improve error
+
+ r = [NSString stringWithFormat:@"could not parse SQL statement: %s",
+ sqlite3_errmsg(self->_connection)];
return [SQLiteException exceptionWithName:@"ExecutionFailed"
- reason:@"could not parse SQL statement"
- userInfo:nil];
+ reason:r userInfo:nil];
}
/* step to first row */
}
}
- /* check whether there are pending errors */
-
- if (zErrMsg != NULL) {
- NSLog(@"WARNING(%s): %@ pending error message: '%s'",
- __PRETTY_FUNCTION__, self, zErrMsg);
- free(zErrMsg);
- }
-
/* only on empty results? */
if (delegateRespondsTo.didEvaluateExpression)
[delegate adaptorChannel:self didEvaluateExpression:sql];