summaryrefslogtreecommitdiff
path: root/platform/default/mbgl/storage/offline_database.cpp
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-02-05 17:10:13 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-02-10 15:40:20 -0800
commitc3c4c7b9a695ad1dbebe57242ba071103fe9a567 (patch)
treee205ecdc6a2f6318c6ba6308b5aa8baacc42f481 /platform/default/mbgl/storage/offline_database.cpp
parente9302c797f68c7e48b908b87b126045c8c5e5209 (diff)
downloadqtlocation-mapboxgl-c3c4c7b9a695ad1dbebe57242ba071103fe9a567.tar.gz
[core] Interface and implementation for offline
Diffstat (limited to 'platform/default/mbgl/storage/offline_database.cpp')
-rw-r--r--platform/default/mbgl/storage/offline_database.cpp171
1 files changed, 161 insertions, 10 deletions
diff --git a/platform/default/mbgl/storage/offline_database.cpp b/platform/default/mbgl/storage/offline_database.cpp
index 67fcc435c6..c6510157bc 100644
--- a/platform/default/mbgl/storage/offline_database.cpp
+++ b/platform/default/mbgl/storage/offline_database.cpp
@@ -100,17 +100,17 @@ optional<Response> OfflineDatabase::get(const Resource& resource) {
}
}
-void OfflineDatabase::put(const Resource& resource, const Response& response) {
+uint64_t OfflineDatabase::put(const Resource& resource, const Response& response) {
// Don't store errors in the cache.
if (response.error) {
- return;
+ return 0;
}
if (resource.kind == Resource::Kind::Tile) {
assert(resource.tileData);
- putTile(*resource.tileData, response);
+ return putTile(*resource.tileData, response);
} else {
- putResource(resource, response);
+ return putResource(resource, response);
}
}
@@ -145,7 +145,7 @@ optional<Response> OfflineDatabase::getResource(const Resource& resource) {
return response;
}
-void OfflineDatabase::putResource(const Resource& resource, const Response& response) {
+uint64_t OfflineDatabase::putResource(const Resource& resource, const Response& response) {
if (response.notModified) {
mapbox::sqlite::Statement& stmt = getStatement(
// 1 2 3
@@ -155,6 +155,7 @@ void OfflineDatabase::putResource(const Resource& resource, const Response& resp
stmt.bind(2, response.expires);
stmt.bind(3, resource.url);
stmt.run();
+ return 0;
} else {
mapbox::sqlite::Statement& stmt = getStatement(
// 1 2 3 4 5 6 7 8
@@ -169,6 +170,7 @@ void OfflineDatabase::putResource(const Resource& resource, const Response& resp
stmt.bind(6 /* accessed */, SystemClock::now());
std::string data;
+ uint64_t size = 0;
if (response.noContent) {
stmt.bind(7 /* data */, nullptr);
@@ -176,15 +178,18 @@ void OfflineDatabase::putResource(const Resource& resource, const Response& resp
} else {
data = util::compress(*response.data);
if (data.size() < response.data->size()) {
- stmt.bind(7 /* data */, data, false); // do not retain the string internally.
+ size = data.size();
+ stmt.bindBlob(7 /* data */, data.data(), size, false);
stmt.bind(8 /* compressed */, true);
} else {
- stmt.bind(7 /* data */, *response.data, false); // do not retain the string internally.
+ size = response.data->size();
+ stmt.bindBlob(7 /* data */, response.data->data(), size, false);
stmt.bind(8 /* compressed */, false);
}
}
stmt.run();
+ return size;
}
}
@@ -228,7 +233,7 @@ optional<Response> OfflineDatabase::getTile(const Resource::TileData& tile) {
return response;
}
-void OfflineDatabase::putTile(const Resource::TileData& tile, const Response& response) {
+uint64_t OfflineDatabase::putTile(const Resource::TileData& tile, const Response& response) {
if (response.notModified) {
mapbox::sqlite::Statement& stmt = getStatement(
"UPDATE tiles SET accessed = ?1, expires = ?2 "
@@ -248,6 +253,7 @@ void OfflineDatabase::putTile(const Resource::TileData& tile, const Response& re
stmt.bind(6, tile.y);
stmt.bind(7, tile.z);
stmt.run();
+ return 0;
} else {
mapbox::sqlite::Statement& stmt1 = getStatement(
"REPLACE INTO tilesets (url_template, pixel_ratio) "
@@ -275,6 +281,7 @@ void OfflineDatabase::putTile(const Resource::TileData& tile, const Response& re
stmt2.bind(9 /* accessed */, SystemClock::now());
std::string data;
+ uint64_t size = 0;
if (response.noContent) {
stmt2.bind(10 /* data */, nullptr);
@@ -282,16 +289,160 @@ void OfflineDatabase::putTile(const Resource::TileData& tile, const Response& re
} else {
data = util::compress(*response.data);
if (data.size() < response.data->size()) {
- stmt2.bind(10 /* data */, data, false); // do not retain the string internally.
+ size = data.size();
+ stmt2.bindBlob(10 /* data */, data.data(), size, false);
stmt2.bind(11 /* compressed */, true);
} else {
- stmt2.bind(10 /* data */, *response.data, false); // do not retain the string internally.
+ size = response.data->size();
+ stmt2.bindBlob(10 /* data */, response.data->data(), size, false);
stmt2.bind(11 /* compressed */, false);
}
}
stmt2.run();
+ return size;
}
}
+std::vector<OfflineRegion> OfflineDatabase::listRegions() {
+ mapbox::sqlite::Statement& stmt = getStatement(
+ "SELECT id, definition, description FROM regions");
+
+ std::vector<OfflineRegion> result;
+
+ while (stmt.run()) {
+ result.push_back(OfflineRegion(
+ stmt.get<int64_t>(0),
+ decodeOfflineRegionDefinition(stmt.get<std::string>(1)),
+ stmt.get<std::vector<uint8_t>>(2)));
+ }
+
+ return std::move(result);
+}
+
+OfflineRegion OfflineDatabase::createRegion(const OfflineRegionDefinition& definition,
+ const OfflineRegionMetadata& metadata) {
+ mapbox::sqlite::Statement& stmt = getStatement(
+ "INSERT INTO regions (definition, description) "
+ "VALUES (?1, ?2) ");
+
+ stmt.bind(1, encodeOfflineRegionDefinition(definition));
+ stmt.bindBlob(2, metadata);
+ stmt.run();
+
+ return OfflineRegion(db->lastInsertRowid(), definition, metadata);
+}
+
+void OfflineDatabase::deleteRegion(OfflineRegion&& region) {
+ mapbox::sqlite::Statement& stmt = getStatement(
+ "DELETE FROM regions WHERE id = ?");
+
+ stmt.bind(1, region.getID());
+ stmt.run();
+}
+
+optional<Response> OfflineDatabase::getRegionResource(int64_t regionID, const Resource& resource) {
+ auto response = get(resource);
+
+ if (response) {
+ markUsed(regionID, resource);
+ }
+
+ return response;
+}
+
+uint64_t OfflineDatabase::putRegionResource(int64_t regionID, const Resource& resource, const Response& response) {
+ uint64_t result = put(resource, response);
+ markUsed(regionID, resource);
+ return result;
+}
+
+void OfflineDatabase::markUsed(int64_t regionID, const Resource& resource) {
+ if (resource.kind == Resource::Kind::Tile) {
+ mapbox::sqlite::Statement& stmt1 = getStatement(
+ "REPLACE INTO region_tiles (region_id, tileset_id, x, y, z) "
+ "SELECT ?1, tilesets.id, ?4, ?5, ?6 "
+ "FROM tilesets "
+ "WHERE url_template = ?2 "
+ "AND pixel_ratio = ?3 ");
+
+ stmt1.bind(1, regionID);
+ stmt1.bind(2, (*resource.tileData).urlTemplate);
+ stmt1.bind(3, (*resource.tileData).pixelRatio);
+ stmt1.bind(4, (*resource.tileData).x);
+ stmt1.bind(5, (*resource.tileData).y);
+ stmt1.bind(6, (*resource.tileData).z);
+ stmt1.run();
+ } else {
+ mapbox::sqlite::Statement& stmt1 = getStatement(
+ "REPLACE INTO region_resources (region_id, resource_url) "
+ "VALUES (?1, ?2) ");
+
+ stmt1.bind(1, regionID);
+ stmt1.bind(2, resource.url);
+ stmt1.run();
+ }
+}
+
+OfflineRegionDefinition OfflineDatabase::getRegionDefinition(int64_t regionID) {
+ mapbox::sqlite::Statement& stmt = getStatement(
+ "SELECT definition FROM regions WHERE id = ?1");
+
+ stmt.bind(1, regionID);
+ stmt.run();
+
+ return decodeOfflineRegionDefinition(stmt.get<std::string>(0));
+}
+
+OfflineRegionStatus OfflineDatabase::getRegionCompletedStatus(int64_t regionID) {
+ OfflineRegionStatus result;
+
+ mapbox::sqlite::Statement& stmt = getStatement(
+ "SELECT COUNT(*), SUM(size) FROM ( "
+ " SELECT LENGTH(data) as size "
+ " FROM region_resources, resources "
+ " WHERE region_id = ?1 "
+ " AND resources.url = region_resources.resource_url "
+ " UNION ALL "
+ " SELECT LENGTH(data) as size "
+ " FROM region_tiles, tiles "
+ " WHERE region_id = ?1 "
+ " AND tiles.tileset_id = region_tiles.tileset_id "
+ " AND tiles.z = region_tiles.z "
+ " AND tiles.x = region_tiles.x "
+ " AND tiles.y = region_tiles.y "
+ ") ");
+
+ stmt.bind(1, regionID);
+ stmt.run();
+
+ result.completedResourceCount = stmt.get<int64_t>(0);
+ result.completedResourceSize = stmt.get<int64_t>(1);
+
+ return result;
+}
+
+void OfflineDatabase::removeUnusedResources() {
+ mapbox::sqlite::Statement& stmt1 = getStatement(
+ "DELETE FROM resources "
+ "WHERE ROWID NOT IN ( "
+ " SELECT resources.ROWID "
+ " FROM resources, region_resources "
+ " WHERE resources.url = region_resources.resource_url "
+ ") ");
+ stmt1.run();
+
+ mapbox::sqlite::Statement& stmt2 = getStatement(
+ "DELETE FROM tiles "
+ "WHERE ROWID NOT IN ( "
+ " SELECT tiles.ROWID "
+ " FROM tiles, region_tiles "
+ " AND tiles.tileset_id = region_tiles.tileset_id "
+ " AND tiles.z = region_tiles.z "
+ " AND tiles.x = region_tiles.x "
+ " AND tiles.y = region_tiles.y "
+ ") ");
+ stmt2.run();
+}
+
} // namespace mbgl