1919#import " sqlite3.h"
2020#endif
2121
22+
23+ static const NSUInteger kMaxErrorRetryCount = 8 ;
24+ static const NSTimeInterval kMinRetryTimeInterval = 2.0 ;
2225static const int kPathLengthMax = PATH_MAX - 64 ;
2326static NSString *const kDBFileName = @" manifest.sqlite" ;
2427static NSString *const kDBShmFileName = @" manifest.sqlite-shm" ;
2528static NSString *const kDBWalFileName = @" manifest.sqlite-wal" ;
2629static NSString *const kDataDirectoryName = @" data" ;
2730static NSString *const kTrashDirectoryName = @" trash" ;
2831
32+
2933/*
3034 File:
3135 /path/
@@ -81,6 +85,8 @@ @implementation YYKVStorage {
8185
8286 sqlite3 *_db;
8387 CFMutableDictionaryRef _dbStmtCache;
88+ NSTimeInterval _dbLastOpenErrorTime;
89+ NSUInteger _dbOpenErrorCount;
8490}
8591
8692
@@ -94,13 +100,19 @@ - (BOOL)_dbOpen {
94100 CFDictionaryKeyCallBacks keyCallbacks = kCFCopyStringDictionaryKeyCallBacks ;
95101 CFDictionaryValueCallBacks valueCallbacks = {0 };
96102 _dbStmtCache = CFDictionaryCreateMutable (CFAllocatorGetDefault (), 0 , &keyCallbacks, &valueCallbacks);
103+ _dbLastOpenErrorTime = 0 ;
104+ _dbOpenErrorCount = 0 ;
97105 return YES ;
98106 } else {
99107 _db = NULL ;
100108 if (_dbStmtCache) CFRelease (_dbStmtCache);
101109 _dbStmtCache = NULL ;
110+ _dbLastOpenErrorTime = CACurrentMediaTime ();
111+ _dbOpenErrorCount++;
102112
103- NSLog (@" %s line:%d sqlite open failed (%d )." , __FUNCTION__, __LINE__, result);
113+ if (_errorLogsEnabled) {
114+ NSLog (@" %s line:%d sqlite open failed (%d )." , __FUNCTION__, __LINE__, result);
115+ }
104116 return NO ;
105117 }
106118}
@@ -128,15 +140,25 @@ - (BOOL)_dbClose {
128140 }
129141 }
130142 } else if (result != SQLITE_OK) {
131- NSLog (@" %s line:%d sqlite close failed (%d )." , __FUNCTION__, __LINE__, result);
143+ if (_errorLogsEnabled) {
144+ NSLog (@" %s line:%d sqlite close failed (%d )." , __FUNCTION__, __LINE__, result);
145+ }
132146 }
133147 } while (retry);
134148 _db = NULL ;
135149 return YES ;
136150}
137151
138- - (BOOL )_dbIsReady {
139- return (_db);
152+ - (BOOL )_dbCheck {
153+ if (!_db) {
154+ if (_dbOpenErrorCount < kMaxErrorRetryCount &&
155+ CACurrentMediaTime () - _dbLastOpenErrorTime > kMinRetryTimeInterval ) {
156+ return [self _dbOpen ] && [self _dbInitialize ];
157+ } else {
158+ return NO ;
159+ }
160+ }
161+ return YES ;
140162}
141163
142164- (BOOL )_dbInitialize {
@@ -145,14 +167,14 @@ - (BOOL)_dbInitialize {
145167}
146168
147169- (void )_dbCheckpoint {
148- if (![self _dbIsReady ]) return ;
170+ if (![self _dbCheck ]) return ;
149171 // Cause a checkpoint to occur, merge `sqlite-wal` file to `sqlite` file.
150172 sqlite3_wal_checkpoint (_db, NULL );
151173}
152174
153175- (BOOL )_dbExecute : (NSString *)sql {
154176 if (sql.length == 0 ) return NO ;
155- if (![self _dbIsReady ]) return NO ;
177+ if (![self _dbCheck ]) return NO ;
156178
157179 char *error = NULL ;
158180 int result = sqlite3_exec (_db, sql.UTF8String , NULL , NULL , &error);
@@ -165,7 +187,7 @@ - (BOOL)_dbExecute:(NSString *)sql {
165187}
166188
167189- (sqlite3_stmt *)_dbPrepareStmt : (NSString *)sql {
168- if (![self _dbIsReady ] || sql.length == 0 || !_dbStmtCache) return NULL ;
190+ if (![self _dbCheck ] || sql.length == 0 || !_dbStmtCache) return NULL ;
169191 sqlite3_stmt *stmt = (sqlite3_stmt *)CFDictionaryGetValue (_dbStmtCache, (__bridge const void *)(sql));
170192 if (!stmt) {
171193 int result = sqlite3_prepare_v2 (_db, sql.UTF8String , -1 , &stmt, NULL );
@@ -239,7 +261,7 @@ - (BOOL)_dbUpdateAccessTimeWithKey:(NSString *)key {
239261}
240262
241263- (BOOL )_dbUpdateAccessTimeWithKeys : (NSArray *)keys {
242- if (![self _dbIsReady ]) return NO ;
264+ if (![self _dbCheck ]) return NO ;
243265 int t = (int )time (NULL );
244266 NSString *sql = [NSString stringWithFormat: @" update manifest set last_access_time = %d where key in (%@ );" , t, [self _dbJoinedKeys: keys]];
245267
@@ -275,7 +297,7 @@ - (BOOL)_dbDeleteItemWithKey:(NSString *)key {
275297}
276298
277299- (BOOL )_dbDeleteItemWithKeys : (NSArray *)keys {
278- if (![self _dbIsReady ]) return NO ;
300+ if (![self _dbCheck ]) return NO ;
279301 NSString *sql = [NSString stringWithFormat: @" delete from manifest where key in (%@ );" , [self _dbJoinedKeys: keys]];
280302 sqlite3_stmt *stmt = NULL ;
281303 int result = sqlite3_prepare_v2 (_db, sql.UTF8String , -1 , &stmt, NULL );
@@ -362,7 +384,7 @@ - (YYKVStorageItem *)_dbGetItemWithKey:(NSString *)key excludeInlineData:(BOOL)e
362384}
363385
364386- (NSMutableArray *)_dbGetItemWithKeys : (NSArray *)keys excludeInlineData : (BOOL )excludeInlineData {
365- if (![self _dbIsReady ]) return nil ;
387+ if (![self _dbCheck ]) return nil ;
366388 NSString *sql;
367389 if (excludeInlineData) {
368390 sql = [NSString stringWithFormat: @" select key, filename, size, modification_time, last_access_time, extended_data from manifest where key in (%@ );" , [self _dbJoinedKeys: keys]];
@@ -436,7 +458,7 @@ - (NSString *)_dbGetFilenameWithKey:(NSString *)key {
436458}
437459
438460- (NSMutableArray *)_dbGetFilenameWithKeys : (NSArray *)keys {
439- if (![self _dbIsReady ]) return nil ;
461+ if (![self _dbCheck ]) return nil ;
440462 NSString *sql = [NSString stringWithFormat: @" select filename from manifest where key in (%@ );" , [self _dbJoinedKeys: keys]];
441463 sqlite3_stmt *stmt = NULL ;
442464 int result = sqlite3_prepare_v2 (_db, sql.UTF8String , -1 , &stmt, NULL );
0 commit comments