diff options
-rw-r--r-- | Example/Database/Tests/Unit/FLevelDBStorageEngineTests.m | 10 | ||||
-rw-r--r-- | Firebase/Database/Persistence/FLevelDBStorageEngine.h | 2 | ||||
-rw-r--r-- | Firebase/Database/Persistence/FLevelDBStorageEngine.m | 40 |
3 files changed, 40 insertions, 12 deletions
diff --git a/Example/Database/Tests/Unit/FLevelDBStorageEngineTests.m b/Example/Database/Tests/Unit/FLevelDBStorageEngineTests.m index 99665a0..7f1f272 100644 --- a/Example/Database/Tests/Unit/FLevelDBStorageEngineTests.m +++ b/Example/Database/Tests/Unit/FLevelDBStorageEngineTests.m @@ -70,6 +70,16 @@ #define MERGE_RECORD(__path, __merge, __writeId) \ ([[FWriteRecord alloc] initWithPath:[FPath pathWithString:__path] merge:__merge writeId:__writeId]) +- (void)testRecocversFromBadCache { + NSString *dbPath = @"corrupted-db"; + NSString *serverData = [[FLevelDBStorageEngine firebaseDir] stringByAppendingPathComponent:@"corrupted-db/server_data/CURRENT"]; + [@"Corrupted" writeToFile:serverData atomically:YES encoding:NSUTF8StringEncoding error:nil]; + NSString *userData = [[FLevelDBStorageEngine firebaseDir] stringByAppendingPathComponent:@"corrupted-db/writes/CURRENT"]; + [@"Corrupted" writeToFile:userData atomically:YES encoding:NSUTF8StringEncoding error:nil]; + FLevelDBStorageEngine *db = [[FLevelDBStorageEngine alloc] initWithPath:dbPath]; + XCTAssertNotNil(db); +} + - (void)testUserWriteIsPersisted { FLevelDBStorageEngine *engine = [self cleanStorageEngine]; [engine saveUserOverwrite:SAMPLE_NODE atPath:[FPath pathWithString:@"foo/bar"] writeId:1]; diff --git a/Firebase/Database/Persistence/FLevelDBStorageEngine.h b/Firebase/Database/Persistence/FLevelDBStorageEngine.h index 059a071..84f3864 100644 --- a/Firebase/Database/Persistence/FLevelDBStorageEngine.h +++ b/Firebase/Database/Persistence/FLevelDBStorageEngine.h @@ -29,6 +29,8 @@ @interface FLevelDBStorageEngine : NSObject<FStorageEngine> ++ (NSString *) firebaseDir; + - (id)initWithPath:(NSString *)path; - (void)runLegacyMigration:(FRepoInfo *)info; diff --git a/Firebase/Database/Persistence/FLevelDBStorageEngine.m b/Firebase/Database/Persistence/FLevelDBStorageEngine.m index 22d67ad..3a63319 100644 --- a/Firebase/Database/Persistence/FLevelDBStorageEngine.m +++ b/Firebase/Database/Persistence/FLevelDBStorageEngine.m @@ -180,17 +180,21 @@ static NSString* trackedQueryKeysKey(NSUInteger trackedQueryId, NSString *key) { self.writesDB = [self createDB:kFWritesDBPath]; } +- (void)purgeDatabase:(NSString*) dbPath { + NSString *path = [self.basePath stringByAppendingPathComponent:dbPath]; + NSError *error; + FFWarn(@"I-RDB076009", @"Deleting database at path %@", path); + BOOL success = [[NSFileManager defaultManager] removeItemAtPath:path error:&error]; + if (!success) { + [NSException raise:NSInternalInconsistencyException format:@"Failed to delete database files: %@", error]; + } +} + - (void)purgeEverything { [self close]; [@[kFServerDBPath, kFWritesDBPath] enumerateObjectsUsingBlock:^(NSString *dbPath, NSUInteger idx, BOOL *stop) { - NSString *path = [self.basePath stringByAppendingPathComponent:dbPath]; - NSError *error; - FFDebug(@"I-RDB076009", @"Deleting database at path %@", path); - BOOL success = [[NSFileManager defaultManager] removeItemAtPath:path error:&error]; - if (!success) { - [NSException raise:NSInternalInconsistencyException format:@"Failed to delete database files: %@", error]; - } + [self purgeDatabase:dbPath]; }]; [self openDatabases]; @@ -216,14 +220,26 @@ static NSString* trackedQueryKeysKey(NSUInteger trackedQueryId, NSString *key) { #endif } -- (APLevelDB *)createDB:(NSString *)name { +- (APLevelDB *)createDB:(NSString *)dbName { NSError *err = nil; - NSString *path = [self.basePath stringByAppendingPathComponent:name]; + NSString *path = [self.basePath stringByAppendingPathComponent:dbName]; APLevelDB *db = [APLevelDB levelDBWithPath:path error:&err]; - if(err) { - NSString *reason = [NSString stringWithFormat:@"Error initializing persistence: %@", [err description]]; - @throw [NSException exceptionWithName:@"FirebaseDatabasePersistenceFailure" reason:reason userInfo:nil]; + + if (err) { + FFWarn(@"I-RDB076036", @"Failed to read database persistence file '%@': %@", + dbName, [err localizedDescription]); + err = nil; + + // Delete the database and try again. + [self purgeDatabase:dbName]; + db = [APLevelDB levelDBWithPath:path error:&err]; + + if (err) { + NSString *reason = [NSString stringWithFormat:@"Error initializing persistence: %@", [err description]]; + @throw [NSException exceptionWithName:@"FirebaseDatabasePersistenceFailure" reason:reason userInfo:nil]; + } } + return db; } |