فهرست منبع

Modified to support using framework

To use FMDB in framework, one should eliminate all non-modular headers. The main culprit here is `#import <sqlite3.h>`. The thing is, FMDB uses SQLite types and constants in these headers, so they had to be removed.

1. Removed `#import <sqlite3.h>` from all of the headers.

2. Moved `sqlite3` and `sqlite3_stmt` declarations in `FMDatabase.h` into `FMDatabasePrivate.h`. FMDB source that needs these will now `#import "FMDatabasePrivate.h" and will have access to them.

3. Removed `#if SQLITE_VERSION_NUMBER >= xxx` logic from the headers.

4. `lastInsertRowId` now returns `long long int`, not `sqlite3_int64`.

5. `sqliteHandle` now returns `void *` not `sqlite3 *`.

6. The `savepoint` and `release savepoint` and `rollback` now always compile regardless of SQLite version (but you'll get SQLite errors if you try those commands with earlier SQLite versions).

7. `makeFunctionNamed` has changed the block parameter type.

8. The FMDatabaseAdditions routines for `applicationID`, much like the `savepoint` routines, will be compiled regardless of SQLite version.

9. Some random usage of deferencing ivars from another class have been replaced with accessor methods.

Note, with all of these changes, in order to conform to modular headers, this is not entirely backward compatible. They'll have to make changes if

 - If they referenced the `_db` variable themselves (which they shouldn't be doing anyway; this never should have been in the public interface to start with);

 - If they referenced `_statement` variable of `FMStatement` (which is even less likely); or

 - If they used `makeFunctionNamed`, the signature of the block has changed (now uses `void` instead of SQLite types).

See issue https://github.com/ccgus/fmdb/issues/309.
Robert M. Ryan 10 سال پیش
والد
کامیت
11f6701599

+ 1 - 0
FMDB.podspec

@@ -12,6 +12,7 @@ Pod::Spec.new do |s|
 
   s.subspec 'common' do |ss|
     ss.source_files = 'src/fmdb/FM*.{h,m}'
+    ss.private_header_files = 'src/fmdb/*Private.h'
     ss.exclude_files = 'src/fmdb.m'
   end
 

+ 6 - 0
fmdb.xcodeproj/project.pbxproj

@@ -16,6 +16,7 @@
 		6290CBB7188FE836009790F8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6290CBB6188FE836009790F8 /* Foundation.framework */; };
 		67CB1E3019AD27D000A3CA7F /* FMDatabaseFTS3Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 67CB1E2F19AD27D000A3CA7F /* FMDatabaseFTS3Tests.m */; };
 		8314AF3318CD73D600EC0E25 /* FMDB.h in Headers */ = {isa = PBXBuildFile; fileRef = 8314AF3218CD73D600EC0E25 /* FMDB.h */; };
+		83D9D8CF1B6E7DC50083E17F /* FMDatabase+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D9D8CE1B6E7DC50083E17F /* FMDatabase+Private.h */; };
 		8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; };
 		8DD76F9F0486AA7600D96B5E /* fmdb.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859EA3029092ED04C91782 /* fmdb.1 */; };
 		BF5D041918416BB2008C5AA9 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF5D041818416BB2008C5AA9 /* XCTest.framework */; };
@@ -99,6 +100,8 @@
 		831DE6FD175B7C9C001F7317 /* README.markdown */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.markdown; sourceTree = "<group>"; };
 		832F502419EC4C6B0087DCBF /* FMDatabaseVariadic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FMDatabaseVariadic.swift; path = "src/extra/Swift extensions/FMDatabaseVariadic.swift"; sourceTree = "<group>"; };
 		8352D5AC1A73DCEA003A8E09 /* FMDatabaseAdditionsVariadic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FMDatabaseAdditionsVariadic.swift; path = "src/extra/Swift extensions/FMDatabaseAdditionsVariadic.swift"; sourceTree = "<group>"; };
+		83D9D8CE1B6E7DC50083E17F /* FMDatabase+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "FMDatabase+Private.h"; path = "src/fmdb/FMDatabase+Private.h"; sourceTree = "<group>"; };
+		83D9D8D01B6E7F6D0083E17F /* FMDB.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = FMDB.podspec; sourceTree = "<group>"; };
 		8DD76FA10486AA7600D96B5E /* fmdb */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fmdb; sourceTree = BUILT_PRODUCTS_DIR; };
 		BF5D041618416BB2008C5AA9 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
 		BF5D041818416BB2008C5AA9 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
@@ -187,6 +190,7 @@
 				CC8C138B0E3135C400FBE1E7 /* LICENSE.txt */,
 				CC8C138A0E3135C400FBE1E7 /* CHANGES_AND_TODO_LIST.txt */,
 				CC8C138C0E3135C400FBE1E7 /* CONTRIBUTORS.txt */,
+				83D9D8D01B6E7F6D0083E17F /* FMDB.podspec */,
 				08FB7795FE84155DC02AAC07 /* Source */,
 				C6859EA2029092E104C91782 /* Documentation */,
 				08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */,
@@ -247,6 +251,7 @@
 				8314AF3218CD73D600EC0E25 /* FMDB.h */,
 				CCC24EBA0A13E34D00A6D3E3 /* FMDatabase.h */,
 				CCC24EBB0A13E34D00A6D3E3 /* FMDatabase.m */,
+				83D9D8CE1B6E7DC50083E17F /* FMDatabase+Private.h */,
 				CCC24EBF0A13E34D00A6D3E3 /* FMResultSet.h */,
 				CCC24EC00A13E34D00A6D3E3 /* FMResultSet.m */,
 				CC47A00D148581E9002CCDAB /* FMDatabaseQueue.h */,
@@ -351,6 +356,7 @@
 				EE42910712B42FC90088BD94 /* FMDatabase.h in Headers */,
 				EE42910612B42FC30088BD94 /* FMDatabaseAdditions.h in Headers */,
 				EE42910912B42FD00088BD94 /* FMResultSet.h in Headers */,
+				83D9D8CF1B6E7DC50083E17F /* FMDatabase+Private.h in Headers */,
 				8314AF3318CD73D600EC0E25 /* FMDB.h in Headers */,
 				CC9E4EBA13B31188005F9210 /* FMDatabasePool.h in Headers */,
 				CC47A00F148581E9002CCDAB /* FMDatabaseQueue.h in Headers */,

+ 39 - 0
src/fmdb/FMDatabase+Private.h

@@ -0,0 +1,39 @@
+//
+//  FMDatabase+Private.h
+//  deleteme2
+//
+//  Created by Robert Ryan on 8/2/15.
+//  Copyright (c) 2015 Robert Ryan. All rights reserved.
+//
+
+#ifndef deleteme2_FMDatabase_Private_h
+#define deleteme2_FMDatabase_Private_h
+
+#import <sqlite3.h>
+
+@class FMDatabase;
+@class FMStatement;
+
+@interface FMDatabase (Private)
+
+/** SQLite sqlite3
+ 
+ @see [`sqlite3`](http://www.sqlite.org/c3ref/sqlite3.html)
+ */
+
+@property (nonatomic, assign, readonly) sqlite3 *db;
+
+@end
+
+@interface FMStatement (Private)
+
+/** SQLite sqlite3_stmt
+ 
+ @see [`sqlite3_stmt`](http://www.sqlite.org/c3ref/stmt.html)
+ */
+
+@property (nonatomic, assign) sqlite3_stmt *statement;
+
+@end
+
+#endif

+ 6 - 12
src/fmdb/FMDatabase.h

@@ -1,5 +1,4 @@
 #import <Foundation/Foundation.h>
-#import "sqlite3.h"
 #import "FMResultSet.h"
 #import "FMDatabasePool.h"
 
@@ -73,7 +72,6 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
 
 @interface FMDatabase : NSObject  {
     
-    sqlite3*            _db;
     NSString*           _databasePath;
     BOOL                _logsErrors;
     BOOL                _crashOnErrors;
@@ -217,12 +215,12 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
  @see [sqlite3_open_v2()](http://sqlite.org/c3ref/open.html)
  @see open
  @see close
+ 
+ @warning Requires SQLite 3.5
  */
 
-#if SQLITE_VERSION_NUMBER >= 3005000
 - (BOOL)openWithFlags:(int)flags;
 - (BOOL)openWithFlags:(int)flags vfs:(NSString *)vfsName;
-#endif
 
 /** Closing a database connection
  
@@ -440,7 +438,7 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
 
  */
 
-- (sqlite_int64)lastInsertRowId;
+- (long long int)lastInsertRowId;
 
 /** The number of rows changed by prior SQL statement.
  
@@ -730,7 +728,7 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
  
  */
 
-- (sqlite3*)sqliteHandle;
+- (void*)sqliteHandle;
 
 
 ///-----------------------------
@@ -794,8 +792,6 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
 - (NSTimeInterval)maxBusyRetryTimeInterval;
 
 
-#if SQLITE_VERSION_NUMBER >= 3007000
-
 ///------------------
 /// @name Save points
 ///------------------
@@ -857,7 +853,6 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
 
 - (NSError*)inSavePoint:(void (^)(BOOL *rollback))block;
 
-#endif
 
 ///----------------------------
 /// @name SQLite library status
@@ -935,7 +930,7 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
  @see [sqlite3_create_function()](http://sqlite.org/c3ref/create_function.html)
  */
 
-- (void)makeFunctionNamed:(NSString*)name maximumArguments:(int)count withBlock:(void (^)(sqlite3_context *context, int argc, sqlite3_value **argv))block;
+- (void)makeFunctionNamed:(NSString*)name maximumArguments:(int)count withBlock:(void (^)(void *context, int argc, void **argv))block;
 
 
 ///---------------------
@@ -1039,7 +1034,6 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
  */
 
 @interface FMStatement : NSObject {
-    sqlite3_stmt *_statement;
     NSString *_query;
     long _useCount;
     BOOL _inUse;
@@ -1062,7 +1056,7 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
  @see [`sqlite3_stmt`](http://www.sqlite.org/c3ref/stmt.html)
  */
 
-@property (atomic, assign) sqlite3_stmt *statement;
+@property (atomic, assign) void *statement;
 
 /** Indication of whether the statement is in use */
 

+ 11 - 4
src/fmdb/FMDatabase.m

@@ -1,9 +1,12 @@
 #import "FMDatabase.h"
 #import "unistd.h"
 #import <objc/runtime.h>
+#import "FMDatabase+Private.h"
 
 @interface FMDatabase ()
 
+@property (nonatomic, assign) sqlite3 *db;
+
 - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args;
 - (BOOL)executeUpdate:(NSString*)sql error:(NSError**)outErr withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args;
 
@@ -109,7 +112,7 @@ + (BOOL)isSQLiteThreadSafe {
     return sqlite3_threadsafe() != 0;
 }
 
-- (sqlite3*)sqliteHandle {
+- (void*)sqliteHandle {
     return _db;
 }
 
@@ -149,11 +152,11 @@ - (BOOL)open {
     return YES;
 }
 
-#if SQLITE_VERSION_NUMBER >= 3005000
 - (BOOL)openWithFlags:(int)flags {
     return [self openWithFlags:flags vfs:nil];
 }
 - (BOOL)openWithFlags:(int)flags vfs:(NSString *)vfsName; {
+#if SQLITE_VERSION_NUMBER >= 3005000
     if (_db) {
         return YES;
     }
@@ -170,9 +173,13 @@ - (BOOL)openWithFlags:(int)flags vfs:(NSString *)vfsName; {
     }
     
     return YES;
-}
+#else 
+    NSLog(@"Requires SQLite 3.5; will just open");
+    return [self open];
 #endif
 
+}
+
 
 - (BOOL)close {
     
@@ -1364,7 +1371,7 @@ void FMDBBlockSQLiteCallBackFunction(sqlite3_context *context, int argc, sqlite3
 }
 
 
-- (void)makeFunctionNamed:(NSString*)name maximumArguments:(int)count withBlock:(void (^)(sqlite3_context *context, int argc, sqlite3_value **argv))block {
+- (void)makeFunctionNamed:(NSString*)name maximumArguments:(int)count withBlock:(void (^)(void *context, int argc, void **argv))block {
     
     if (!_openFunctions) {
         _openFunctions = [NSMutableSet new];

+ 2 - 1
src/fmdb/FMDatabaseAdditions.m

@@ -9,6 +9,7 @@
 #import "FMDatabase.h"
 #import "FMDatabaseAdditions.h"
 #import "TargetConditionals.h"
+#import "FMDatabase+Private.h"
 
 @interface FMDatabase (PrivateStuff)
 - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args;
@@ -205,7 +206,7 @@ - (BOOL)validateSQL:(NSString*)sql error:(NSError**)error {
     sqlite3_stmt *pStmt = NULL;
     BOOL validationSucceeded = YES;
     
-    int rc = sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0);
+    int rc = sqlite3_prepare_v2(self.db, [sql UTF8String], -1, &pStmt, 0);
     if (rc != SQLITE_OK) {
         validationSucceeded = NO;
         if (error) {

+ 0 - 1
src/fmdb/FMDatabasePool.h

@@ -7,7 +7,6 @@
 //
 
 #import <Foundation/Foundation.h>
-#import "sqlite3.h"
 
 @class FMDatabase;
 

+ 1 - 0
src/fmdb/FMDatabasePool.m

@@ -8,6 +8,7 @@
 
 #import "FMDatabasePool.h"
 #import "FMDatabase.h"
+#import "FMDatabase+Private.h"
 
 @interface FMDatabasePool()
 

+ 0 - 1
src/fmdb/FMDatabaseQueue.h

@@ -7,7 +7,6 @@
 //
 
 #import <Foundation/Foundation.h>
-#import "sqlite3.h"
 
 @class FMDatabase;
 

+ 1 - 0
src/fmdb/FMDatabaseQueue.m

@@ -8,6 +8,7 @@
 
 #import "FMDatabaseQueue.h"
 #import "FMDatabase.h"
+#import "FMDatabase+Private.h"
 
 /*
  

+ 0 - 1
src/fmdb/FMResultSet.h

@@ -1,5 +1,4 @@
 #import <Foundation/Foundation.h>
-#import "sqlite3.h"
 
 #ifndef __has_feature      // Optional.
 #define __has_feature(x) 0 // Compatibility with non-clang compilers.

+ 1 - 0
src/fmdb/FMResultSet.m

@@ -1,6 +1,7 @@
 #import "FMResultSet.h"
 #import "FMDatabase.h"
 #import "unistd.h"
+#import "FMDatabase+Private.h"
 
 @interface FMDatabase ()
 - (void)resultSetDidClose:(FMResultSet *)resultSet;