19
19
#import " sqlite3.h"
20
20
#endif
21
21
22
+
23
+ static const NSUInteger kMaxErrorRetryCount = 8 ;
24
+ static const NSTimeInterval kMinRetryTimeInterval = 2.0 ;
22
25
static const int kPathLengthMax = PATH_MAX - 64 ;
23
26
static NSString *const kDBFileName = @" manifest.sqlite" ;
24
27
static NSString *const kDBShmFileName = @" manifest.sqlite-shm" ;
25
28
static NSString *const kDBWalFileName = @" manifest.sqlite-wal" ;
26
29
static NSString *const kDataDirectoryName = @" data" ;
27
30
static NSString *const kTrashDirectoryName = @" trash" ;
28
31
32
+
29
33
/*
30
34
File:
31
35
/path/
@@ -81,6 +85,8 @@ @implementation YYKVStorage {
81
85
82
86
sqlite3 *_db;
83
87
CFMutableDictionaryRef _dbStmtCache;
88
+ NSTimeInterval _dbLastOpenErrorTime;
89
+ NSUInteger _dbOpenErrorCount;
84
90
}
85
91
86
92
@@ -94,13 +100,19 @@ - (BOOL)_dbOpen {
94
100
CFDictionaryKeyCallBacks keyCallbacks = kCFCopyStringDictionaryKeyCallBacks ;
95
101
CFDictionaryValueCallBacks valueCallbacks = {0 };
96
102
_dbStmtCache = CFDictionaryCreateMutable (CFAllocatorGetDefault (), 0 , &keyCallbacks, &valueCallbacks);
103
+ _dbLastOpenErrorTime = 0 ;
104
+ _dbOpenErrorCount = 0 ;
97
105
return YES ;
98
106
} else {
99
107
_db = NULL ;
100
108
if (_dbStmtCache) CFRelease (_dbStmtCache);
101
109
_dbStmtCache = NULL ;
110
+ _dbLastOpenErrorTime = CACurrentMediaTime ();
111
+ _dbOpenErrorCount++;
102
112
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
+ }
104
116
return NO ;
105
117
}
106
118
}
@@ -128,15 +140,25 @@ - (BOOL)_dbClose {
128
140
}
129
141
}
130
142
} 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
+ }
132
146
}
133
147
} while (retry);
134
148
_db = NULL ;
135
149
return YES ;
136
150
}
137
151
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 ;
140
162
}
141
163
142
164
- (BOOL )_dbInitialize {
@@ -145,14 +167,14 @@ - (BOOL)_dbInitialize {
145
167
}
146
168
147
169
- (void )_dbCheckpoint {
148
- if (![self _dbIsReady ]) return ;
170
+ if (![self _dbCheck ]) return ;
149
171
// Cause a checkpoint to occur, merge `sqlite-wal` file to `sqlite` file.
150
172
sqlite3_wal_checkpoint (_db, NULL );
151
173
}
152
174
153
175
- (BOOL )_dbExecute : (NSString *)sql {
154
176
if (sql.length == 0 ) return NO ;
155
- if (![self _dbIsReady ]) return NO ;
177
+ if (![self _dbCheck ]) return NO ;
156
178
157
179
char *error = NULL ;
158
180
int result = sqlite3_exec (_db, sql.UTF8String , NULL , NULL , &error);
@@ -165,7 +187,7 @@ - (BOOL)_dbExecute:(NSString *)sql {
165
187
}
166
188
167
189
- (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 ;
169
191
sqlite3_stmt *stmt = (sqlite3_stmt *)CFDictionaryGetValue (_dbStmtCache, (__bridge const void *)(sql));
170
192
if (!stmt) {
171
193
int result = sqlite3_prepare_v2 (_db, sql.UTF8String , -1 , &stmt, NULL );
@@ -239,7 +261,7 @@ - (BOOL)_dbUpdateAccessTimeWithKey:(NSString *)key {
239
261
}
240
262
241
263
- (BOOL )_dbUpdateAccessTimeWithKeys : (NSArray *)keys {
242
- if (![self _dbIsReady ]) return NO ;
264
+ if (![self _dbCheck ]) return NO ;
243
265
int t = (int )time (NULL );
244
266
NSString *sql = [NSString stringWithFormat: @" update manifest set last_access_time = %d where key in (%@ );" , t, [self _dbJoinedKeys: keys]];
245
267
@@ -275,7 +297,7 @@ - (BOOL)_dbDeleteItemWithKey:(NSString *)key {
275
297
}
276
298
277
299
- (BOOL )_dbDeleteItemWithKeys : (NSArray *)keys {
278
- if (![self _dbIsReady ]) return NO ;
300
+ if (![self _dbCheck ]) return NO ;
279
301
NSString *sql = [NSString stringWithFormat: @" delete from manifest where key in (%@ );" , [self _dbJoinedKeys: keys]];
280
302
sqlite3_stmt *stmt = NULL ;
281
303
int result = sqlite3_prepare_v2 (_db, sql.UTF8String , -1 , &stmt, NULL );
@@ -362,7 +384,7 @@ - (YYKVStorageItem *)_dbGetItemWithKey:(NSString *)key excludeInlineData:(BOOL)e
362
384
}
363
385
364
386
- (NSMutableArray *)_dbGetItemWithKeys : (NSArray *)keys excludeInlineData : (BOOL )excludeInlineData {
365
- if (![self _dbIsReady ]) return nil ;
387
+ if (![self _dbCheck ]) return nil ;
366
388
NSString *sql;
367
389
if (excludeInlineData) {
368
390
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 {
436
458
}
437
459
438
460
- (NSMutableArray *)_dbGetFilenameWithKeys : (NSArray *)keys {
439
- if (![self _dbIsReady ]) return nil ;
461
+ if (![self _dbCheck ]) return nil ;
440
462
NSString *sql = [NSString stringWithFormat: @" select filename from manifest where key in (%@ );" , [self _dbJoinedKeys: keys]];
441
463
sqlite3_stmt *stmt = NULL ;
442
464
int result = sqlite3_prepare_v2 (_db, sql.UTF8String , -1 , &stmt, NULL );
0 commit comments