diff options
author | Thiago Marcos P. Santos <thiago@mapbox.com> | 2016-01-05 16:28:59 +0200 |
---|---|---|
committer | Thiago Marcos P. Santos <thiago@mapbox.com> | 2016-01-05 17:32:46 +0200 |
commit | a5987afeb92715a342d77c04a3f29808fa7f0c02 (patch) | |
tree | 20d2278e6e79640b0698a4b04a7853e409acb0cc | |
parent | f80673b15c9961f089c7f341a577517f2d2aaa6c (diff) | |
download | qtlocation-mapboxgl-a5987afeb92715a342d77c04a3f29808fa7f0c02.tar.gz |
[core] Added versioning to the cache database
Force drop the table when the version doesn't match. Previously
it was assumed (my bad) that CREATE TABLE IF NOT EXISTS would
compare the table schema, which is not true.
-rw-r--r-- | platform/default/sqlite_cache.cpp | 38 | ||||
-rw-r--r-- | platform/default/sqlite_cache_impl.hpp | 3 |
2 files changed, 39 insertions, 2 deletions
diff --git a/platform/default/sqlite_cache.cpp b/platform/default/sqlite_cache.cpp index 4d8cb8180c..74aecc4e8d 100644 --- a/platform/default/sqlite_cache.cpp +++ b/platform/default/sqlite_cache.cpp @@ -4,6 +4,7 @@ #include <mbgl/util/compression.hpp> #include <mbgl/util/io.hpp> +#include <mbgl/util/string.hpp> #include <mbgl/util/thread.hpp> #include <mbgl/util/mapbox.hpp> #include <mbgl/platform/log.hpp> @@ -63,6 +64,12 @@ void SQLiteCache::Impl::createDatabase() { db = std::make_unique<Database>(path.c_str(), ReadWrite | Create); } +int SQLiteCache::Impl::schemaVersion() const { + // WARNING: Bump the version when changing the cache + // scheme to force the table to be recreated. + return 1; +} + void SQLiteCache::Impl::createSchema() { constexpr const char *const sql = "" "CREATE TABLE IF NOT EXISTS `http_cache` (" @@ -77,10 +84,13 @@ void SQLiteCache::Impl::createSchema() { " `compressed` INTEGER NOT NULL DEFAULT 0" // Whether the data is compressed. ");" "CREATE INDEX IF NOT EXISTS `http_cache_kind_idx` ON `http_cache` (`kind`);" - "CREATE INDEX IF NOT EXISTS `http_cache_accessed_idx` ON `http_cache` (`modified`);"; + "CREATE INDEX IF NOT EXISTS `http_cache_accessed_idx` ON `http_cache` (`accessed`);"; + + ensureSchemaVersion(); try { db->exec(sql); + db->exec("PRAGMA user_version = " + util::toString(schemaVersion())); schema = true; } catch (mapbox::sqlite::Exception &ex) { if (ex.code == SQLITE_NOTADB) { @@ -97,9 +107,33 @@ void SQLiteCache::Impl::createSchema() { } // Creating the database table + index failed. That means there may already be one, likely - // with different columsn. Drop it and try to create a new one. + // with different columns. Drop it and try to create a new one. db->exec("DROP TABLE IF EXISTS `http_cache`"); db->exec(sql); + db->exec("PRAGMA user_version = " + util::toString(schemaVersion())); + } +} + +void SQLiteCache::Impl::ensureSchemaVersion() { + try { + Statement userVersionStmt(db->prepare("PRAGMA user_version")); + if (userVersionStmt.run() && userVersionStmt.get<int>(0) == schemaVersion()) { + return; + } + } catch (mapbox::sqlite::Exception& ex) { + if (ex.code == SQLITE_NOTADB) { + return; + } + + Log::Error(Event::Database, ex.code, ex.what()); + } + + // Version mismatch, drop the table so it will + // get recreated by `createSchema()`. + try { + db->exec("DROP TABLE IF EXISTS `http_cache`"); + } catch (mapbox::sqlite::Exception& ex) { + Log::Error(Event::Database, ex.code, ex.what()); } } diff --git a/platform/default/sqlite_cache_impl.hpp b/platform/default/sqlite_cache_impl.hpp index be2db5df43..8ad22d79fc 100644 --- a/platform/default/sqlite_cache_impl.hpp +++ b/platform/default/sqlite_cache_impl.hpp @@ -42,6 +42,9 @@ private: void createDatabase(); void createSchema(); + int schemaVersion() const; + void ensureSchemaVersion(); + int pageSize = 0; uint64_t maximumCacheSize; |