|
|
@@ -811,6 +811,8 @@ - (BOOL)executeUpdate:(NSString*)sql error:(NSError* __autoreleasing*)outErr wit
|
|
|
|
|
|
_isExecutingStatement = YES;
|
|
|
|
|
|
+ #pragma message "FIXME: chagne all the 0x00's to nils."
|
|
|
+
|
|
|
int rc = 0x00;
|
|
|
sqlite3_stmt *pStmt = 0x00;
|
|
|
FMStatement *cachedStmt = 0x00;
|
|
|
@@ -1288,16 +1290,60 @@ - (void)makeFunctionNamed:(NSString*)name maximumArguments:(int)count withBlock:
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+- (FMDBQ*)u:(NSString*)sql, ... {
|
|
|
+ FMDBQ *q = [FMDBQ new];
|
|
|
+
|
|
|
+
|
|
|
+ va_list args;
|
|
|
+ va_start(args, sql);
|
|
|
+
|
|
|
+ sqlite3_stmt *pStmt = nil;
|
|
|
+
|
|
|
+ int rc = sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0);
|
|
|
+
|
|
|
+ if (SQLITE_OK != rc) {
|
|
|
+ if (_logsErrors) {
|
|
|
+ NSLog(@"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]);
|
|
|
+ NSLog(@"DB Query: %@", sql);
|
|
|
+ NSLog(@"DB Path: %@", _databasePath);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_crashOnErrors) {
|
|
|
+ NSAssert(false, @"DB Error: %d \"%@\"", [self lastErrorCode], [self lastErrorMessage]);
|
|
|
+ abort();
|
|
|
+ }
|
|
|
+
|
|
|
+ sqlite3_finalize(pStmt);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ int idx = 0;
|
|
|
+ int queryCount = sqlite3_bind_parameter_count(pStmt); // pointed out by Dominic Yu (thanks!)
|
|
|
+
|
|
|
+ while (idx < queryCount) {
|
|
|
+
|
|
|
+ id obj = va_arg(args, id);
|
|
|
+
|
|
|
+ idx++;
|
|
|
+
|
|
|
+ [self bindObject:obj toColumn:idx inStatement:pStmt];
|
|
|
+ }
|
|
|
+
|
|
|
+ va_end(args);
|
|
|
+
|
|
|
+ [q setStatement:pStmt];
|
|
|
+ [q setDb:self];
|
|
|
+
|
|
|
+ return q;
|
|
|
+}
|
|
|
+
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
@implementation FMStatement
|
|
|
-@synthesize statement=_statement;
|
|
|
-@synthesize query=_query;
|
|
|
-@synthesize useCount=_useCount;
|
|
|
-@synthesize inUse=_inUse;
|
|
|
|
|
|
+#pragma message "FIXME: kill all the finalizes"
|
|
|
- (void)finalize {
|
|
|
[self close];
|
|
|
[super finalize];
|
|
|
@@ -1335,3 +1381,101 @@ - (NSString*)description {
|
|
|
|
|
|
@end
|
|
|
|
|
|
+
|
|
|
+@implementation FMDBQ
|
|
|
+
|
|
|
+- (void)executeUpdateInBackground:(void (^)(NSError *error))callback {
|
|
|
+
|
|
|
+
|
|
|
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
|
+
|
|
|
+ NSError *outErr = nil;
|
|
|
+
|
|
|
+ if (![self executeUpdate:&outErr]) {
|
|
|
+ callback(outErr);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ callback(nil);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+- (BOOL)executeUpdate:(NSError * __autoreleasing *)outErr {
|
|
|
+
|
|
|
+ // FIXME: ref the db here instead of using an ivar.
|
|
|
+ BOOL _logsErrors = NO;
|
|
|
+ NSString *sql = nil;
|
|
|
+
|
|
|
+
|
|
|
+ /* Call sqlite3_step() to run the virtual machine. Since the SQL being
|
|
|
+ ** executed is not a SELECT statement, we assume no data will be returned.
|
|
|
+ */
|
|
|
+
|
|
|
+ int rc = sqlite3_step(_statement);
|
|
|
+
|
|
|
+ if (SQLITE_DONE == rc) {
|
|
|
+ // all is well, let's return.
|
|
|
+ }
|
|
|
+ else if (rc == SQLITE_ROW) {
|
|
|
+ NSString *message = [NSString stringWithFormat:@"A executeUpdate is being called with a query string '%@'", sql];
|
|
|
+ if (_logsErrors) {
|
|
|
+ NSLog(@"%@", message);
|
|
|
+ NSLog(@"DB Query: %@", sql);
|
|
|
+ }
|
|
|
+ if (outErr) {
|
|
|
+ *outErr = [[self db] errorWithMessage:message];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if (outErr) {
|
|
|
+ *outErr = [[self db] errorWithMessage:[NSString stringWithUTF8String:sqlite3_errmsg([[self db] sqliteHandle])]];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (SQLITE_ERROR == rc) {
|
|
|
+ if (_logsErrors) {
|
|
|
+ NSLog(@"Error calling sqlite3_step (%d: %s) SQLITE_ERROR", rc, sqlite3_errmsg([[self db] sqliteHandle]));
|
|
|
+ NSLog(@"DB Query: %@", sql);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (SQLITE_MISUSE == rc) {
|
|
|
+ // uh oh.
|
|
|
+ if (_logsErrors) {
|
|
|
+ NSLog(@"Error calling sqlite3_step (%d: %s) SQLITE_MISUSE", rc, sqlite3_errmsg([[self db] sqliteHandle]));
|
|
|
+ NSLog(@"DB Query: %@", sql);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // wtf?
|
|
|
+ if (_logsErrors) {
|
|
|
+ NSLog(@"Unknown error calling sqlite3_step (%d: %s) eu", rc, sqlite3_errmsg([[self db] sqliteHandle]));
|
|
|
+ NSLog(@"DB Query: %@", sql);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Finalize the virtual machine. This releases all memory and other
|
|
|
+ ** resources allocated by the sqlite3_prepare() call above.
|
|
|
+ */
|
|
|
+
|
|
|
+ int closeErrorCode = sqlite3_finalize(_statement);
|
|
|
+
|
|
|
+
|
|
|
+ if (closeErrorCode != SQLITE_OK) {
|
|
|
+ if (_logsErrors) {
|
|
|
+ #pragma message "FIXME: set something in the outErr here."
|
|
|
+ NSLog(@"Unknown error finalizing or resetting statement (%d: %s)", closeErrorCode, sqlite3_errmsg([[self db] sqliteHandle]));
|
|
|
+ NSLog(@"DB Query: %@", sql);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (rc == SQLITE_DONE || rc == SQLITE_OK);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+@end
|
|
|
+
|