summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <thiago@mapbox.com>2016-01-05 16:28:59 +0200
committerThiago Marcos P. Santos <thiago@mapbox.com>2016-01-05 17:32:46 +0200
commita5987afeb92715a342d77c04a3f29808fa7f0c02 (patch)
tree20d2278e6e79640b0698a4b04a7853e409acb0cc
parentf80673b15c9961f089c7f341a577517f2d2aaa6c (diff)
downloadqtlocation-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.cpp38
-rw-r--r--platform/default/sqlite_cache_impl.hpp3
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;