summaryrefslogtreecommitdiff
path: root/platform/default/mbgl/storage/offline_database.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/default/mbgl/storage/offline_database.cpp')
-rw-r--r--platform/default/mbgl/storage/offline_database.cpp116
1 files changed, 62 insertions, 54 deletions
diff --git a/platform/default/mbgl/storage/offline_database.cpp b/platform/default/mbgl/storage/offline_database.cpp
index 2c4ee2da31..24fc0f2335 100644
--- a/platform/default/mbgl/storage/offline_database.cpp
+++ b/platform/default/mbgl/storage/offline_database.cpp
@@ -28,67 +28,70 @@ OfflineDatabase::~OfflineDatabase() {
}
void OfflineDatabase::ensureSchema() {
- if (path != ":memory:") {
- auto result = mapbox::sqlite::Database::tryOpen(path, mapbox::sqlite::ReadWrite);
- if (result.is<mapbox::sqlite::Exception>()) {
- const auto& ex = result.get<mapbox::sqlite::Exception>();
- if (ex.code == mapbox::sqlite::ResultCode::NotADB) {
- // Corrupted; blow it away.
- removeExisting();
- } else if (ex.code == mapbox::sqlite::ResultCode::CantOpen) {
- // Doesn't exist yet.
- } else {
- Log::Error(Event::Database, "Unexpected error connecting to database: %s", ex.what());
- throw ex;
- }
+ auto result = mapbox::sqlite::Database::tryOpen(path, mapbox::sqlite::ReadWriteCreate);
+ if (result.is<mapbox::sqlite::Exception>()) {
+ const auto& ex = result.get<mapbox::sqlite::Exception>();
+ if (ex.code == mapbox::sqlite::ResultCode::NotADB) {
+ // Corrupted; blow it away.
+ removeExisting();
+ result = mapbox::sqlite::Database::open(path, mapbox::sqlite::ReadWriteCreate);
} else {
- try {
- db = std::make_unique<mapbox::sqlite::Database>(std::move(result.get<mapbox::sqlite::Database>()));
- db->setBusyTimeout(Milliseconds::max());
- db->exec("PRAGMA foreign_keys = ON");
-
- switch (userVersion()) {
- case 0:
- case 1:
- // cache-only database; ok to delete
- removeExisting();
- break;
- case 2:
- migrateToVersion3();
- // fall through
- case 3:
- case 4:
- migrateToVersion5();
- // fall through
- case 5:
- migrateToVersion6();
- // fall through
- case 6:
- // happy path; we're done
- return;
- default:
- // downgrade, delete the database
- removeExisting();
- break;
- }
- } catch (const mapbox::sqlite::Exception& ex) {
- // Unfortunately, SQLITE_NOTADB is not always reported upon opening the database.
- // Apparently sometimes it is delayed until the first read operation.
- if (ex.code == mapbox::sqlite::ResultCode::NotADB) {
- removeExisting();
- } else {
- throw;
- }
- }
+ Log::Error(Event::Database, "Unexpected error connecting to database: %s", ex.what());
+ throw ex;
}
}
try {
- #include "offline_schema.cpp.include"
-
- db = std::make_unique<mapbox::sqlite::Database>(mapbox::sqlite::Database::open(path, mapbox::sqlite::ReadWrite | mapbox::sqlite::Create));
+ assert(result.is<mapbox::sqlite::Database>());
+ db = std::make_unique<mapbox::sqlite::Database>(std::move(result.get<mapbox::sqlite::Database>()));
db->setBusyTimeout(Milliseconds::max());
db->exec("PRAGMA foreign_keys = ON");
+
+ switch (userVersion()) {
+ case 0:
+ case 1:
+ // Newly created database, or old cache-only database; remove old table if it exists.
+ removeOldCacheTable();
+ break;
+ case 2:
+ migrateToVersion3();
+ // fall through
+ case 3:
+ case 4:
+ migrateToVersion5();
+ // fall through
+ case 5:
+ migrateToVersion6();
+ // fall through
+ case 6:
+ // happy path; we're done
+ return;
+ default:
+ // downgrade, delete the database
+ removeExisting();
+ break;
+ }
+ } catch (const mapbox::sqlite::Exception& ex) {
+ // Unfortunately, SQLITE_NOTADB is not always reported upon opening the database.
+ // Apparently sometimes it is delayed until the first read operation.
+ if (ex.code == mapbox::sqlite::ResultCode::NotADB) {
+ removeExisting();
+ } else {
+ throw;
+ }
+ }
+
+ try {
+ #include "offline_schema.cpp.include"
+
+ // When downgrading the database, or when the database is corrupt, we've deleted the old database handle,
+ // so we need to reopen it.
+ if (!db) {
+ db = std::make_unique<mapbox::sqlite::Database>(mapbox::sqlite::Database::open(path, mapbox::sqlite::ReadWriteCreate));
+ db->setBusyTimeout(Milliseconds::max());
+ db->exec("PRAGMA foreign_keys = ON");
+ }
+
db->exec("PRAGMA auto_vacuum = INCREMENTAL");
db->exec("PRAGMA journal_mode = DELETE");
db->exec("PRAGMA synchronous = FULL");
@@ -117,6 +120,11 @@ void OfflineDatabase::removeExisting() {
}
}
+void OfflineDatabase::removeOldCacheTable() {
+ db->exec("DROP TABLE IF EXISTS http_cache");
+ db->exec("VACUUM");
+}
+
void OfflineDatabase::migrateToVersion3() {
db->exec("PRAGMA auto_vacuum = INCREMENTAL");
db->exec("VACUUM");