Skip to content

Commit 2c9f881

Browse files
author
Greg Soltis
authored
Save schema version on downgrade, add test to verify (#2153)
* Save schema version on downgrade, add test to verify
1 parent 313f9f6 commit 2c9f881

File tree

3 files changed

+39
-17
lines changed

3 files changed

+39
-17
lines changed

Firestore/Example/Tests/Local/FSTLevelDBMigrationsTests.mm

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -95,20 +95,14 @@ - (void)testAddsTargetGlobal {
9595
}
9696

9797
- (void)testSetsVersionNumber {
98-
{
99-
LevelDbTransaction transaction(_db.get(), "testSetsVersionNumber before");
100-
SchemaVersion initial = LevelDbMigrations::ReadSchemaVersion(&transaction);
101-
XCTAssertEqual(0, initial, "No version should be equivalent to 0");
102-
}
98+
SchemaVersion initial = LevelDbMigrations::ReadSchemaVersion(_db.get());
99+
XCTAssertEqual(0, initial, "No version should be equivalent to 0");
103100

104-
{
105-
// Pick an arbitrary high migration number and migrate to it.
106-
LevelDbMigrations::RunMigrations(_db.get());
101+
// Pick an arbitrary high migration number and migrate to it.
102+
LevelDbMigrations::RunMigrations(_db.get());
107103

108-
LevelDbTransaction transaction(_db.get(), "testSetsVersionNumber after");
109-
SchemaVersion actual = LevelDbMigrations::ReadSchemaVersion(&transaction);
110-
XCTAssertGreaterThan(actual, 0, @"Expected to migrate to a schema version > 0");
111-
}
104+
SchemaVersion actual = LevelDbMigrations::ReadSchemaVersion(_db.get());
105+
XCTAssertGreaterThan(actual, 0, @"Expected to migrate to a schema version > 0");
112106
}
113107

114108
#define ASSERT_NOT_FOUND(transaction, key) \
@@ -366,6 +360,25 @@ - (void)testRemovesMutationBatches {
366360
}
367361
}
368362

363+
- (void)testCanDowngrade {
364+
// First, run all of the migrations
365+
LevelDbMigrations::RunMigrations(_db.get());
366+
367+
LevelDbMigrations::SchemaVersion latestVersion = LevelDbMigrations::ReadSchemaVersion(_db.get());
368+
369+
// Downgrade to an early version.
370+
LevelDbMigrations::SchemaVersion downgradeVersion = 1;
371+
LevelDbMigrations::RunMigrations(_db.get(), downgradeVersion);
372+
LevelDbMigrations::SchemaVersion postDowngradeVersion =
373+
LevelDbMigrations::ReadSchemaVersion(_db.get());
374+
XCTAssertEqual(downgradeVersion, postDowngradeVersion);
375+
376+
// Verify that we can upgrade again to the latest version.
377+
LevelDbMigrations::RunMigrations(_db.get());
378+
LevelDbMigrations::SchemaVersion finalVersion = LevelDbMigrations::ReadSchemaVersion(_db.get());
379+
XCTAssertEqual(finalVersion, latestVersion);
380+
}
381+
369382
/**
370383
* Creates the name of a dummy entry to make sure the iteration is correctly bounded.
371384
*/

Firestore/core/src/firebase/firestore/local/leveldb_migrations.cc

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,11 @@ void EnsureSentinelRows(leveldb::DB* db) {
244244
} // namespace
245245

246246
LevelDbMigrations::SchemaVersion LevelDbMigrations::ReadSchemaVersion(
247-
LevelDbTransaction* transaction) {
247+
leveldb::DB* db) {
248+
LevelDbTransaction transaction(db, "Read schema version");
248249
std::string key = LevelDbVersionKey::Key();
249250
std::string version_string;
250-
Status status = transaction->Get(key, &version_string);
251+
Status status = transaction.Get(key, &version_string);
251252
if (status.IsNotFound()) {
252253
return 0;
253254
} else {
@@ -261,8 +262,16 @@ void LevelDbMigrations::RunMigrations(leveldb::DB* db) {
261262

262263
void LevelDbMigrations::RunMigrations(leveldb::DB* db,
263264
SchemaVersion to_version) {
264-
LevelDbTransaction transaction{db, "Read schema version"};
265-
SchemaVersion from_version = ReadSchemaVersion(&transaction);
265+
SchemaVersion from_version = ReadSchemaVersion(db);
266+
// If this is a downgrade, just save the downgrade version so we can
267+
// detect it when we go to upgrade again, allowing us to rerun the
268+
// data migrations.
269+
if (from_version > to_version) {
270+
LevelDbTransaction transaction(db, "Save downgrade version");
271+
SaveVersion(to_version, &transaction);
272+
transaction.Commit();
273+
return;
274+
}
266275

267276
// This must run unconditionally because schema migrations were added to iOS
268277
// after the first release. There may be clients that have never run any

Firestore/core/src/firebase/firestore/local/leveldb_migrations.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class LevelDbMigrations {
3434
/**
3535
* Returns the current version of the schema for the given database
3636
*/
37-
static SchemaVersion ReadSchemaVersion(LevelDbTransaction* transaction);
37+
static SchemaVersion ReadSchemaVersion(leveldb::DB* db);
3838

3939
/**
4040
* Runs any migrations needed to bring the given database up to the current

0 commit comments

Comments
 (0)