FSTLevelDBMigrations.mm 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Copyright 2018 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "Firestore/Source/Local/FSTLevelDBMigrations.h"
  17. #include <leveldb/db.h>
  18. #include <leveldb/write_batch.h>
  19. #import "Firestore/Protos/objc/firestore/local/Target.pbobjc.h"
  20. #import "Firestore/Source/Local/FSTLevelDB.h"
  21. #import "Firestore/Source/Local/FSTLevelDBKey.h"
  22. #import "Firestore/Source/Local/FSTLevelDBQueryCache.h"
  23. #import "Firestore/Source/Local/FSTWriteGroup.h"
  24. NS_ASSUME_NONNULL_BEGIN
  25. // Current version of the schema defined in this file.
  26. static FSTLevelDBSchemaVersion kSchemaVersion = 1;
  27. using leveldb::DB;
  28. using leveldb::Status;
  29. using leveldb::Slice;
  30. using leveldb::WriteOptions;
  31. /**
  32. * Ensures that the global singleton target metadata row exists in LevelDB.
  33. * @param db The db in which to require the row.
  34. */
  35. static void EnsureTargetGlobal(std::shared_ptr<DB> db, FSTWriteGroup *group) {
  36. FSTPBTargetGlobal *targetGlobal = [FSTLevelDBQueryCache readTargetMetadataFromDB:db];
  37. if (!targetGlobal) {
  38. [group setMessage:[FSTPBTargetGlobal message] forKey:[FSTLevelDBTargetGlobalKey key]];
  39. }
  40. }
  41. /**
  42. * Save the given version number as the current version of the schema of the database.
  43. * @param version The version to save
  44. * @param group The transaction in which to save the new version number
  45. */
  46. static void SaveVersion(FSTLevelDBSchemaVersion version, FSTWriteGroup *group) {
  47. std::string key = [FSTLevelDBVersionKey key];
  48. std::string version_string = std::to_string(version);
  49. [group setData:version_string forKey:key];
  50. }
  51. @implementation FSTLevelDBMigrations
  52. + (FSTLevelDBSchemaVersion)schemaVersionForDB:(std::shared_ptr<DB>)db {
  53. std::string key = [FSTLevelDBVersionKey key];
  54. std::string version_string;
  55. Status status = db->Get([FSTLevelDB standardReadOptions], key, &version_string);
  56. if (status.IsNotFound()) {
  57. return 0;
  58. } else {
  59. return stoi(version_string);
  60. }
  61. }
  62. + (void)runMigrationsOnDB:(std::shared_ptr<DB>)db {
  63. FSTWriteGroup *group = [FSTWriteGroup groupWithAction:@"Migrations"];
  64. FSTLevelDBSchemaVersion currentVersion = [self schemaVersionForDB:db];
  65. // Each case in this switch statement intentionally falls through. This lets us
  66. // start at the current schema version and apply any migrations that have not yet
  67. // been applied, to bring us up to current, as defined by the kSchemaVersion constant.
  68. switch (currentVersion) {
  69. case 0:
  70. EnsureTargetGlobal(db, group);
  71. // Fallthrough
  72. default:
  73. if (currentVersion < kSchemaVersion) {
  74. SaveVersion(kSchemaVersion, group);
  75. }
  76. }
  77. if (!group.isEmpty) {
  78. [group writeToDB:db];
  79. }
  80. }
  81. @end
  82. NS_ASSUME_NONNULL_END