Просмотр исходного кода

Checkpoint tweaks

1. If we're going to expose `sqlite3_wal_checkpoint_v2` wrapper, I'd suggest a `typedef` for the checkpoint modes rather than `int`. Swift 2/3 users don't have easy access to `sqlite3.h`, so we want to show them their options. It leads to more natural, less cryptic Swift code.

2. In the checkpoint method, I might suggest `name` instead of `dbName`.

3. If we're providing access to `sqlite3_wal_checkpoint_v2`, we might as well provide access to those last two parameters, too. Let's provide a version with fewer parameters so not everyone is encumbered with that.

4. In the checkpoint method, the name is `_Nullable` (as are the two additional parameters).
Robert M. Ryan 8 лет назад
Родитель
Сommit
577e4f2c22
4 измененных файлов с 71 добавлено и 11 удалено
  1. 26 1
      src/fmdb/FMDatabase.h
  2. 10 2
      src/fmdb/FMDatabase.m
  3. 21 4
      src/fmdb/FMDatabaseQueue.h
  4. 14 4
      src/fmdb/FMDatabaseQueue.m

+ 26 - 1
src/fmdb/FMDatabase.h

@@ -41,6 +41,12 @@ NS_ASSUME_NONNULL_BEGIN
 
 typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary);
 
+typedef NS_ENUM(int, FMDBCheckpointMode) {
+    FMDBCheckpointModePassive  = 0, // SQLITE_CHECKPOINT_PASSIVE,
+    FMDBCheckpointModeFull     = 1, // SQLITE_CHECKPOINT_FULL,
+    FMDBCheckpointModeRestart  = 2, // SQLITE_CHECKPOINT_RESTART,
+    FMDBCheckpointModeTruncate = 3  // SQLITE_CHECKPOINT_TRUNCATE
+};
 
 /** A SQLite ([http://sqlite.org/](http://sqlite.org/)) Objective-C wrapper.
  
@@ -1005,13 +1011,32 @@ typedef int(^FMDBExecuteStatementsCallbackBlock)(NSDictionary *resultsDictionary
 ///-----------------
 
 /** Performs a WAL checkpoint
+ 
+ @param checkpointMode The checkpoint mode for sqlite3_wal_checkpoint_v2
+ @param error The NSError corresponding to the error, if any.
+ @return YES on success, otherwise NO.
+ */
+- (BOOL)checkpoint:(FMDBCheckpointMode)checkpointMode error:(NSError * _Nullable *)error;
+
+/** Performs a WAL checkpoint
+ 
+ @param checkpointMode The checkpoint mode for sqlite3_wal_checkpoint_v2
+ @param name The db name for sqlite3_wal_checkpoint_v2
+ @param error The NSError corresponding to the error, if any.
+ @return YES on success, otherwise NO.
+ */
+- (BOOL)checkpoint:(FMDBCheckpointMode)checkpointMode name:(NSString * _Nullable)name error:(NSError * _Nullable *)error;
 
+/** Performs a WAL checkpoint
+ 
  @param checkpointMode The checkpoint mode for sqlite3_wal_checkpoint_v2
  @param name The db name for sqlite3_wal_checkpoint_v2
  @param error The NSError corresponding to the error, if any.
+ @param logFrameCount If not NULL, then this is set to the total number of frames in the log file or to -1 if the checkpoint could not run because of an error or because the database is not in WAL mode.
+ @param checkpointCount If not NULL, then this is set to the total number of checkpointed frames in the log file (including any that were already checkpointed before the function was called) or to -1 if the checkpoint could not run due to an error or because the database is not in WAL mode.
  @return YES on success, otherwise NO.
  */
-- (BOOL)checkpoint:(int)checkpointMode dbName:(NSString *)name error:(NSError * _Nullable *)error;
+- (BOOL)checkpoint:(FMDBCheckpointMode)checkpointMode name:(NSString * _Nullable)name logFrameCount:(int * _Nullable)logFrameCount checkpointCount:(int * _Nullable)checkpointCount error:(NSError * _Nullable *)error;
 
 ///----------------------------
 /// @name SQLite library status

+ 10 - 2
src/fmdb/FMDatabase.m

@@ -1433,11 +1433,19 @@ - (NSError*)inSavePoint:(void (^)(BOOL *rollback))block {
 #endif
 }
 
-- (BOOL)checkpoint:(int)checkpointMode dbName:(NSString *)name error:(NSError * __autoreleasing *)error
+- (BOOL)checkpoint:(FMDBCheckpointMode)checkpointMode error:(NSError * __autoreleasing *)error {
+    return [self checkpoint:checkpointMode name:nil logFrameCount:NULL checkpointCount:NULL error:error];
+}
+
+- (BOOL)checkpoint:(FMDBCheckpointMode)checkpointMode name:(NSString *)name error:(NSError * __autoreleasing *)error {
+    return [self checkpoint:checkpointMode name:name logFrameCount:NULL checkpointCount:NULL error:error];
+}
+
+- (BOOL)checkpoint:(FMDBCheckpointMode)checkpointMode name:(NSString *)name logFrameCount:(int *)logFrameCount checkpointCount:(int *)checkpointCount error:(NSError * __autoreleasing *)error
 {
     const char* dbName = [name UTF8String];
 #if SQLITE_VERSION_NUMBER >= 3007006
-    int err = sqlite3_wal_checkpoint_v2(_db, dbName, checkpointMode, NULL, NULL);
+    int err = sqlite3_wal_checkpoint_v2(_db, dbName, checkpointMode, logFrameCount, checkpointCount);
 #else
     NSLog(@"sqlite3_wal_checkpoint_v2 unavailable before sqlite 3.7.6. Ignoring checkpoint mode: %d", mode);
     int err = sqlite3_wal_checkpoint(_db, dbName);

+ 21 - 4
src/fmdb/FMDatabaseQueue.h

@@ -7,11 +7,10 @@
 //
 
 #import <Foundation/Foundation.h>
+#import "FMDatabase.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
-@class FMDatabase;
-
 /** To perform queries and updates on multiple threads, you'll want to use `FMDatabaseQueue`.
 
  Using a single instance of `<FMDatabase>` from multiple threads at once is a bad idea.  It has always been OK to make a `<FMDatabase>` object *per thread*.  Just don't share a single instance across threads, and definitely not across multiple threads at the same time.
@@ -241,15 +240,33 @@ NS_ASSUME_NONNULL_BEGIN
 /// @name Checkpoint
 ///-----------------
 
-/** Synchronously performs a WAL checkpoint
+/** Performs a WAL checkpoint
+ 
+ @param checkpointMode The checkpoint mode for sqlite3_wal_checkpoint_v2
+ @param error The NSError corresponding to the error, if any.
+ @return YES on success, otherwise NO.
+ */
+- (BOOL)checkpoint:(FMDBCheckpointMode)checkpointMode error:(NSError * _Nullable *)error;
 
+/** Performs a WAL checkpoint
+ 
  @param checkpointMode The checkpoint mode for sqlite3_wal_checkpoint_v2
  @param name The db name for sqlite3_wal_checkpoint_v2
  @param error The NSError corresponding to the error, if any.
  @return YES on success, otherwise NO.
  */
+- (BOOL)checkpoint:(FMDBCheckpointMode)checkpointMode name:(NSString * _Nullable)name error:(NSError * _Nullable *)error;
 
-- (BOOL)checkpoint:(int)checkpointMode dbName:(NSString *)name error:(NSError * _Nullable *)error;
+/** Performs a WAL checkpoint
+ 
+ @param checkpointMode The checkpoint mode for sqlite3_wal_checkpoint_v2
+ @param name The db name for sqlite3_wal_checkpoint_v2
+ @param error The NSError corresponding to the error, if any.
+ @param logFrameCount If not NULL, then this is set to the total number of frames in the log file or to -1 if the checkpoint could not run because of an error or because the database is not in WAL mode.
+ @param checkpointCount If not NULL, then this is set to the total number of checkpointed frames in the log file (including any that were already checkpointed before the function was called) or to -1 if the checkpoint could not run due to an error or because the database is not in WAL mode.
+ @return YES on success, otherwise NO.
+ */
+- (BOOL)checkpoint:(FMDBCheckpointMode)checkpointMode name:(NSString * _Nullable)name logFrameCount:(int * _Nullable)logFrameCount checkpointCount:(int * _Nullable)checkpointCount error:(NSError * _Nullable *)error;
 
 @end
 

+ 14 - 4
src/fmdb/FMDatabaseQueue.m

@@ -282,17 +282,27 @@ - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block {
 #endif
 }
 
-- (BOOL)checkpoint:(int)mode dbName:(NSString *)name error:(NSError * __autoreleasing *)error
+- (BOOL)checkpoint:(FMDBCheckpointMode)mode error:(NSError * __autoreleasing *)error
+{
+    return [self checkpoint:mode name:nil logFrameCount:NULL checkpointCount:NULL error:error];
+}
+
+- (BOOL)checkpoint:(FMDBCheckpointMode)mode name:(NSString *)name error:(NSError * __autoreleasing *)error
+{
+    return [self checkpoint:mode name:name logFrameCount:NULL checkpointCount:NULL error:error];
+}
+
+- (BOOL)checkpoint:(FMDBCheckpointMode)mode name:(NSString *)name logFrameCount:(int * _Nullable)logFrameCount checkpointCount:(int * _Nullable)checkpointCount error:(NSError * __autoreleasing _Nullable * _Nullable)error
 {
     __block BOOL result;
     __block NSError *blockError;
-
+    
     FMDBRetain(self);
     dispatch_sync(_queue, ^() {
-        result = [self.database checkpoint:mode dbName:name error:&blockError];
+        result = [self.database checkpoint:mode name:name logFrameCount:NULL checkpointCount:NULL error:&blockError];
     });
     FMDBRelease(self);
-
+    
     if (error) {
         *error = blockError;
     }