Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ccgus/fmdb.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAugust Mueller <gus@flyingmeat.com>2016-05-09 22:22:43 +0300
committerAugust Mueller <gus@flyingmeat.com>2016-05-09 22:22:43 +0300
commitd9dd0aff1b3fa5522397dde24ab7ac1b6c3275d3 (patch)
treef5197c8824e0519141d937d9af6bf65f2fdfc194
parent05780fb3918a399f63b4750cfb003fad24ee8a54 (diff)
Sketching out some ideas.
-rw-r--r--src/fmdb/FMDatabase.h33
-rw-r--r--src/fmdb/FMDatabase.m152
-rw-r--r--src/sample/main.m64
3 files changed, 242 insertions, 7 deletions
diff --git a/src/fmdb/FMDatabase.h b/src/fmdb/FMDatabase.h
index 9f11bda..21484f1 100644
--- a/src/fmdb/FMDatabase.h
+++ b/src/fmdb/FMDatabase.h
@@ -2,7 +2,6 @@
#import "FMResultSet.h"
#import "FMDatabasePool.h"
-
#if ! __has_feature(objc_arc)
#define FMDBAutorelease(__v) ([__v autorelease]);
#define FMDBReturnAutoreleased FMDBAutorelease
@@ -37,6 +36,7 @@
#define instancetype id
#endif
+@class FMDBQ;
typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary);
@@ -329,6 +329,9 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
- (BOOL)executeUpdate:(NSString*)sql, ...;
+- (void)executeUpdateInBackground:(FMDBQ*)q completion:(void (^)(NSError *error))callback;
+
+
/** Execute single update statement
@@ -1045,6 +1048,15 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
- (NSString *)stringFromDate:(NSDate *)date;
+
+
+
+/////////// 33333333333333333333333333333333
+
+- (FMDBQ*)u:(NSString*)sql, ...;
+
+
+
@end
@@ -1105,3 +1117,22 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
#pragma clang diagnostic pop
+
+#pragma message "FIXME: This name is temporary"
+@interface FMDBQ : NSObject {
+
+}
+
+
+@property (atomic, weak) FMDatabase *db;
+@property (atomic, assign) void *statement;
+@property (atomic, strong) NSString *query;
+@property (atomic, strong) NSArray *arguments;
+
+
+- (BOOL)executeUpdate:(NSError * __autoreleasing *)outErr;
+- (void)executeUpdateInBackground:(void (^)(NSError *error))callback;
+
+@end
+
+
diff --git a/src/fmdb/FMDatabase.m b/src/fmdb/FMDatabase.m
index b7250e5..187c994 100644
--- a/src/fmdb/FMDatabase.m
+++ b/src/fmdb/FMDatabase.m
@@ -811,6 +811,8 @@ static int FMDBDatabaseBusyHandler(void *f, int count) {
_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 FMDBBlockSQLiteCallBackFunction(sqlite3_context *context, int argc, sqlite3
#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 @@ void FMDBBlockSQLiteCallBackFunction(sqlite3_context *context, int argc, sqlite3
@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
+
diff --git a/src/sample/main.m b/src/sample/main.m
index ea2e407..1649fef 100644
--- a/src/sample/main.m
+++ b/src/sample/main.m
@@ -47,6 +47,68 @@ int main (int argc, const char * argv[]) {
// kind of experimentalish.
[db setShouldCacheStatements:YES];
+
+
+
+
+
+
+
+
+ ////////////////////////////////////////////// 3
+
+ {
+
+
+
+ NSError *err = nil;
+ FMDBQuickCheck([[db u:@"create table test3 (a text, b text, c integer, d double, e double)"] executeUpdate:&err]);
+ FMDBQuickCheck(err == nil);
+
+
+
+ __block BOOL allGood = NO;
+
+ [[db u:@"create table test3 (a text, b text, c integer, d double, e double)"] executeUpdateInBackground:^(NSError *error) {
+
+
+ FMDBQuickCheck(error != nil);
+
+ allGood = YES;
+ }];
+
+
+
+ sleep(2);
+
+ FMDBQuickCheck(allGood);
+
+
+ NSLog(@"yay");
+
+
+
+
+
+ return 0;
+
+
+
+
+
+
+ }
+
+
+
+
+
+
+
+
+
+
+
// create a bad statement, just to test the error code.
[db executeUpdate:@"blah blah blah"];
@@ -62,8 +124,6 @@ int main (int argc, const char * argv[]) {
FMDBQuickCheck([err code] == SQLITE_ERROR);
NSLog(@"err: '%@'", err);
-
-
// empty strings should still return a value.
FMDBQuickCheck(([db boolForQuery:@"SELECT ? not null", @""]));