diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | platform/default/mbgl/storage/offline_database.cpp | 39 | ||||
-rw-r--r-- | platform/default/mbgl/storage/offline_database.hpp | 2 | ||||
-rw-r--r-- | test/fixtures/offline/v2.db | bin | 0 -> 43008 bytes | |||
-rw-r--r-- | test/storage/offline_database.cpp | 28 |
5 files changed, 53 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore index 1b6ed5386b..68e242a31b 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ offline.db /test/fixtures/api/1.png /test/fixtures/api/2.png /test/fixtures/database/*.db +/test/fixtures/offline/v3.db /test/fixtures/**/actual.png /test/fixtures/**/diff.png /test/output diff --git a/platform/default/mbgl/storage/offline_database.cpp b/platform/default/mbgl/storage/offline_database.cpp index a42591d60e..e1cd693662 100644 --- a/platform/default/mbgl/storage/offline_database.cpp +++ b/platform/default/mbgl/storage/offline_database.cpp @@ -14,9 +14,6 @@ namespace mbgl { using namespace mapbox::sqlite; -// If you change the schema you must write a migration from the previous version. -static const uint32_t schemaVersion = 2; - OfflineDatabase::Statement::~Statement() { stmt.reset(); stmt.clearBindings(); @@ -50,15 +47,12 @@ void OfflineDatabase::ensureSchema() { try { connect(ReadWrite); - { - auto userVersionStmt = db->prepare("PRAGMA user_version"); - userVersionStmt.run(); - switch (userVersionStmt.get<int>(0)) { - case 0: break; // cache-only database; ok to delete - case 1: break; // cache-only database; ok to delete - case 2: return; - default: throw std::runtime_error("unknown schema version"); - } + switch (userVersion()) { + case 0: break; // cache-only database; ok to delete + case 1: break; // cache-only database; ok to delete + case 2: migrateToVersion3(); // fall through + case 3: return; + default: throw std::runtime_error("unknown schema version"); } removeExisting(); @@ -76,8 +70,17 @@ void OfflineDatabase::ensureSchema() { #include "offline_schema.cpp.include" connect(ReadWrite | Create); + + // If you change the schema you must write a migration from the previous version. + db->exec("PRAGMA auto_vacuum = INCREMENTAL"); db->exec(schema); - db->exec("PRAGMA user_version = " + util::toString(schemaVersion)); + db->exec("PRAGMA user_version = 3"); +} + +int OfflineDatabase::userVersion() { + auto stmt = db->prepare("PRAGMA user_version"); + stmt.run(); + return stmt.get<int>(0); } void OfflineDatabase::removeExisting() { @@ -92,6 +95,11 @@ void OfflineDatabase::removeExisting() { } } +void OfflineDatabase::migrateToVersion3() { + db->exec("PRAGMA auto_vacuum = INCREMENTAL"); + db->exec("VACUUM"); +} + OfflineDatabase::Statement OfflineDatabase::getStatement(const char * sql) { auto it = statements.find(sql); @@ -458,6 +466,7 @@ void OfflineDatabase::deleteRegion(OfflineRegion&& region) { stmt->run(); evict(0); + db->exec("PRAGMA incremental_vacuum"); // Ensure that the cached offlineTileCount value is recalculated. offlineMapboxTileCount = {}; @@ -614,10 +623,6 @@ bool OfflineDatabase::evict(uint64_t neededFreeSize) { uint64_t pageSize = getPragma<int64_t>("PRAGMA page_size"); uint64_t pageCount = getPragma<int64_t>("PRAGMA page_count"); - if (pageSize * pageCount > maximumCacheSize) { - Log::Warning(mbgl::Event::Database, "Current size is larger than the maximum size. Database won't get truncated."); - } - auto usedSize = [&] { return pageSize * (pageCount - getPragma<int64_t>("PRAGMA freelist_count")); }; diff --git a/platform/default/mbgl/storage/offline_database.hpp b/platform/default/mbgl/storage/offline_database.hpp index eb18cc18d2..1e77d560d4 100644 --- a/platform/default/mbgl/storage/offline_database.hpp +++ b/platform/default/mbgl/storage/offline_database.hpp @@ -58,8 +58,10 @@ public: private: void connect(int flags); + int userVersion(); void ensureSchema(); void removeExisting(); + void migrateToVersion3(); class Statement { public: diff --git a/test/fixtures/offline/v2.db b/test/fixtures/offline/v2.db Binary files differnew file mode 100644 index 0000000000..8fadec4abe --- /dev/null +++ b/test/fixtures/offline/v2.db diff --git a/test/storage/offline_database.cpp b/test/storage/offline_database.cpp index 23269a98ed..11d56c237b 100644 --- a/test/storage/offline_database.cpp +++ b/test/storage/offline_database.cpp @@ -7,6 +7,7 @@ #include <mbgl/util/string.hpp> #include <gtest/gtest.h> +#include <sqlite3.hpp> #include <sqlite3.h> #include <thread> #include <random> @@ -660,3 +661,30 @@ TEST(OfflineDatabase, OfflineMapboxTileCount) { db.deleteRegion(std::move(region1)); EXPECT_EQ(0, db.getOfflineMapboxTileCount()); } + +static int databasePageCount(const std::string& path) { + mapbox::sqlite::Database db(path, mapbox::sqlite::ReadOnly); + mapbox::sqlite::Statement stmt = db.prepare("pragma page_count"); + stmt.run(); + return stmt.get<int>(0); +} + +TEST(OfflineDatabase, MigrateFromV2Schema) { + using namespace mbgl; + + // v2.db is a v2 database containing a single offline region with a small number of resources. + + deleteFile("test/fixtures/offline/v3.db"); + writeFile("test/fixtures/offline/v3.db", util::read_file("test/fixtures/offline/v2.db")); + + { + OfflineDatabase db("test/fixtures/offline/v3.db", 0); + auto regions = db.listRegions(); + for (auto& region : regions) { + db.deleteRegion(std::move(region)); + } + } + + EXPECT_LT(databasePageCount("test/fixtures/offline/v3.db"), + databasePageCount("test/fixtures/offline/v2.db")); +} |