summaryrefslogtreecommitdiff
path: root/platform/default
diff options
context:
space:
mode:
Diffstat (limited to 'platform/default')
-rw-r--r--platform/default/default_file_source.cpp13
-rw-r--r--platform/default/mbgl/storage/offline_database.cpp53
-rw-r--r--platform/default/mbgl/storage/offline_database.hpp3
3 files changed, 68 insertions, 1 deletions
diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp
index 93f10eea72..99e5c4dff3 100644
--- a/platform/default/default_file_source.cpp
+++ b/platform/default/default_file_source.cpp
@@ -55,6 +55,11 @@ public:
callback(offlineDatabase->createRegion(definition, metadata));
}
+ void mergeOfflineRegions(const std::string& sideDatabasePath,
+ std::function<void (expected<OfflineRegions, std::exception_ptr>)> callback) {
+ callback(offlineDatabase->mergeDatabase(sideDatabasePath));
+ }
+
void updateMetadata(const int64_t regionID,
const OfflineRegionMetadata& metadata,
std::function<void (expected<OfflineRegionMetadata, std::exception_ptr>)> callback) {
@@ -258,9 +263,15 @@ void DefaultFileSource::createOfflineRegion(const OfflineRegionDefinition& defin
impl->actor().invoke(&Impl::createRegion, definition, metadata, callback);
}
+void DefaultFileSource::mergeOfflineRegions(const std::string& sideDatabasePath,
+ std::function<void (expected<OfflineRegions, std::exception_ptr>)> callback) {
+ impl->actor().invoke(&Impl::mergeOfflineRegions, sideDatabasePath, callback);
+}
+
void DefaultFileSource::updateOfflineMetadata(const int64_t regionID,
const OfflineRegionMetadata& metadata,
- std::function<void (expected<OfflineRegionMetadata, std::exception_ptr>)> callback) {
+ std::function<void (expected<OfflineRegionMetadata,
+ std::exception_ptr>)> callback) {
impl->actor().invoke(&Impl::updateMetadata, regionID, metadata, callback);
}
diff --git a/platform/default/mbgl/storage/offline_database.cpp b/platform/default/mbgl/storage/offline_database.cpp
index 79bc3c8f27..30b76d1666 100644
--- a/platform/default/mbgl/storage/offline_database.cpp
+++ b/platform/default/mbgl/storage/offline_database.cpp
@@ -7,6 +7,7 @@
#include <mbgl/util/logging.hpp>
#include "offline_schema.hpp"
+#include "merge_sideloaded.hpp"
#include "sqlite3.hpp"
@@ -637,6 +638,58 @@ OfflineDatabase::createRegion(const OfflineRegionDefinition& definition,
return unexpected<std::exception_ptr>(std::current_exception());
}
+expected<OfflineRegions, std::exception_ptr>
+OfflineDatabase::mergeDatabase(const std::string& sideDatabasePath) {
+ try {
+ // clang-format off
+ mapbox::sqlite::Query query{ getStatement("ATTACH DATABASE ?1 AS side") };
+ // clang-format on
+
+ query.bind(1, sideDatabasePath);
+ query.run();
+ } catch (const mapbox::sqlite::Exception& ex) {
+ handleError(ex, "merge databse attach");
+ return unexpected<std::exception_ptr>(std::current_exception());
+ }
+ try {
+ // Attaching an accessible path without a db file creates a new temporary
+ //database and attaches it. Check for matching schema version.
+ auto sideUserVersion = static_cast<int>(getPragma<int64_t>("PRAGMA side.user_version"));
+ if (sideUserVersion != 6) {
+ Log::Warning(Event::Database, "Merge database does not match user_version of main database");
+ throw std::runtime_error("merge database does not match schema or has incorrect user_version");
+ }
+
+ mapbox::sqlite::Transaction transaction(*db);
+ db->exec(mergeSideloadedDatabaseSQL);
+ transaction.commit();
+
+ // clang-format off
+ mapbox::sqlite::Query query{ getStatement(
+ "SELECT r.id, r.definition, r.description "
+ "FROM side.regions sr "
+ "JOIN regions r ON sr.definition = r.definition") };
+ // clang-format on
+
+ OfflineRegions result;
+ while (query.run()) {
+ // Construct, then move because this constructor is private.
+ OfflineRegion region(query.get<int64_t>(0),
+ decodeOfflineRegionDefinition(query.get<std::string>(1)),
+ query.get<std::vector<uint8_t>>(2));
+ result.emplace_back(std::move(region));
+ }
+ db->exec("DETACH DATABASE side");
+ // Explicit move to avoid triggering the copy constructor.
+ return { std::move(result) };
+ } catch (const mapbox::sqlite::Exception& ex) {
+ db->exec("DETACH DATABASE side");
+ handleError(ex, "merge databse post merge sql");
+ return unexpected<std::exception_ptr>(std::current_exception());
+ }
+ return {};
+}
+
expected<OfflineRegionMetadata, std::exception_ptr>
OfflineDatabase::updateMetadata(const int64_t regionID, const OfflineRegionMetadata& metadata) try {
// clang-format off
diff --git a/platform/default/mbgl/storage/offline_database.hpp b/platform/default/mbgl/storage/offline_database.hpp
index fbe6c707e1..993f36a606 100644
--- a/platform/default/mbgl/storage/offline_database.hpp
+++ b/platform/default/mbgl/storage/offline_database.hpp
@@ -53,6 +53,9 @@ public:
expected<OfflineRegion, std::exception_ptr> createRegion(const OfflineRegionDefinition&,
const OfflineRegionMetadata&);
+ expected<OfflineRegions, std::exception_ptr>
+ mergeDatabase(const std::string& sideDatabasePath);
+
expected<OfflineRegionMetadata, std::exception_ptr>
updateMetadata(const int64_t regionID, const OfflineRegionMetadata&);