diff options
author | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2018-08-21 14:11:44 -0700 |
---|---|---|
committer | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2018-08-28 07:14:54 -0700 |
commit | 065f5ca87e96f2280959b9fd3ad3d6e63a99bae6 (patch) | |
tree | 0054ce9c196bd270ca997caddc99e80148aed897 /platform/default | |
parent | 48381efa11f4b352c25ff2f24ef44b972b6eb5ba (diff) | |
download | qtlocation-mapboxgl-065f5ca87e96f2280959b9fd3ad3d6e63a99bae6.tar.gz |
[core] Add DefaultFileSource::mergeRegions API and CLI support in the mbgl-offline tool.
Diffstat (limited to 'platform/default')
-rw-r--r-- | platform/default/default_file_source.cpp | 13 | ||||
-rw-r--r-- | platform/default/mbgl/storage/offline_database.cpp | 53 | ||||
-rw-r--r-- | platform/default/mbgl/storage/offline_database.hpp | 3 |
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&); |