summaryrefslogtreecommitdiff
path: root/src/mbgl/storage/sqlite_store.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/storage/sqlite_store.cpp')
-rw-r--r--src/mbgl/storage/sqlite_store.cpp228
1 files changed, 0 insertions, 228 deletions
diff --git a/src/mbgl/storage/sqlite_store.cpp b/src/mbgl/storage/sqlite_store.cpp
deleted file mode 100644
index d382921dec..0000000000
--- a/src/mbgl/storage/sqlite_store.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-#include <mbgl/storage/sqlite_store.hpp>
-#include <mbgl/util/compression.hpp>
-#include <mbgl/util/sqlite3.hpp>
-#include <mbgl/util/std.hpp>
-
-#include <mbgl/util/uv-worker.h>
-
-#include <cassert>
-
-using namespace mapbox::sqlite;
-
-std::string removeAccessTokenFromURL(const std::string &url) {
- const size_t token_start = url.find("access_token=");
- // Ensure that token exists, isn't at the front and is preceded by either & or ?.
- if (token_start == std::string::npos || token_start == 0 || !(url[token_start - 1] == '&' || url[token_start - 1] == '?')) {
- return url;
- }
-
- const size_t token_end = url.find_first_of('&', token_start);
- if (token_end == std::string::npos) {
- // The token is the last query argument. We slice away the "&access_token=..." part
- return url.substr(0, token_start - 1);
- } else {
- // We slice away the "access_token=...&" part.
- return url.substr(0, token_start) + url.substr(token_end + 1);
- }
-}
-
-std::string convertMapboxDomainsToProtocol(const std::string &url) {
- const size_t protocol_separator = url.find("://");
- if (protocol_separator == std::string::npos) {
- return url;
- }
-
- const std::string protocol = url.substr(0, protocol_separator);
- if (!(protocol == "http" || protocol == "https")) {
- return url;
- }
-
- const size_t domain_begin = protocol_separator + 3;
- const size_t path_separator = url.find("/", domain_begin);
- if (path_separator == std::string::npos) {
- return url;
- }
-
- const std::string domain = url.substr(domain_begin, path_separator - domain_begin);
- if (domain.find(".tiles.mapbox.com") != std::string::npos) {
- return "mapbox://" + url.substr(path_separator + 1);
- } else {
- return url;
- }
-}
-
-std::string unifyMapboxURLs(const std::string &url) {
- return removeAccessTokenFromURL(convertMapboxDomainsToProtocol(url));
-}
-
-namespace mbgl {
-
-SQLiteStore::SQLiteStore(uv_loop_t *loop, const std::string &path)
- : thread_id(std::this_thread::get_id()),
- db(std::make_shared<Database>(path.c_str(), ReadWrite | Create)) {
- createSchema();
- worker = new uv_worker_t;
- uv_worker_init(worker, loop, 1, "SQLite");
-}
-
-SQLiteStore::~SQLiteStore() {
- // Nothing to do. This function needs to be here because we're forward-declaring
- // Database, so we need the actual definition here to be able to properly destruct it.
- if (worker) {
- uv_worker_close(worker, [](uv_worker_t *worker_handle) {
- delete worker_handle;
- });
- }
-}
-
-void SQLiteStore::createSchema() {
- if (!db || !*db) {
- return;
- }
-
- db->exec("CREATE TABLE IF NOT EXISTS `http_cache` ("
- " `url` TEXT PRIMARY KEY NOT NULL,"
- " `code` INTEGER NOT NULL,"
- " `type` INTEGER NOT NULL,"
- " `modified` INTEGER,"
- " `etag` TEXT,"
- " `expires` INTEGER,"
- " `data` BLOB,"
- " `compressed` INTEGER NOT NULL DEFAULT 0"
- ");"
- "CREATE INDEX IF NOT EXISTS `http_cache_type_idx` ON `http_cache` (`type`);");
-}
-
-struct GetBaton {
- util::ptr<Database> db;
- std::string path;
- ResourceType type;
- void *ptr = nullptr;
- SQLiteStore::GetCallback callback = nullptr;
- std::unique_ptr<Response> response;
-};
-
-void SQLiteStore::get(const std::string &path, GetCallback callback, void *ptr) {
- assert(std::this_thread::get_id() == thread_id);
- if (!db || !*db) {
- if (callback) {
- callback(nullptr, ptr);
- }
- return;
- }
-
- GetBaton *get_baton = new GetBaton;
- get_baton->db = db;
- get_baton->path = path;
- get_baton->ptr = ptr;
- get_baton->callback = callback;
-
- uv_worker_send(worker, get_baton, [](void *data) {
- GetBaton *baton = (GetBaton *)data;
- const std::string url = unifyMapboxURLs(baton->path);
- // 0 1 2
- Statement stmt = baton->db->prepare("SELECT `code`, `type`, `modified`, "
- // 3 4 5 6
- "`etag`, `expires`, `data`, `compressed` FROM `http_cache` WHERE `url` = ?");
-
- stmt.bind(1, url.c_str());
- if (stmt.run()) {
- // There is data.
- baton->response = util::make_unique<Response>();
-
- baton->response->code = stmt.get<int>(0);
- baton->type = ResourceType(stmt.get<int>(1));
- baton->response->modified = stmt.get<int64_t>(2);
- baton->response->etag = stmt.get<std::string>(3);
- baton->response->expires = stmt.get<int64_t>(4);
- baton->response->data = stmt.get<std::string>(5);
- if (stmt.get<int>(6)) { // == compressed
- baton->response->data = util::decompress(baton->response->data);
- }
- } else {
- // There is no data.
- // This is a noop.
- }
- }, [](void *data) {
- std::unique_ptr<GetBaton> baton { (GetBaton *)data };
- if (baton->callback) {
- baton->callback(std::move(baton->response), baton->ptr);
- }
- });
-}
-
-
-struct PutBaton {
- util::ptr<Database> db;
- std::string path;
- ResourceType type;
- Response response;
-};
-
-void SQLiteStore::put(const std::string &path, ResourceType type, const Response &response) {
- assert(std::this_thread::get_id() == thread_id);
- if (!db) return;
-
- PutBaton *put_baton = new PutBaton;
- put_baton->db = db;
- put_baton->path = path;
- put_baton->type = type;
- put_baton->response = response;
-
- uv_worker_send(worker, put_baton, [](void *data) {
- PutBaton *baton = (PutBaton *)data;
- const std::string url = unifyMapboxURLs(baton->path);
- Statement stmt = baton->db->prepare("REPLACE INTO `http_cache` ("
- // 1 2 3 4 5 6 7 8
- "`url`, `code`, `type`, `modified`, `etag`, `expires`, `data`, `compressed`"
- ") VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
- stmt.bind(1, url.c_str());
- stmt.bind(2, int(baton->response.code));
- stmt.bind(3, int(baton->type));
- stmt.bind(4, baton->response.modified);
- stmt.bind(5, baton->response.etag.c_str());
- stmt.bind(6, baton->response.expires);
-
- if (baton->type == ResourceType::Image) {
- stmt.bind(7, baton->response.data, false); // do not retain the string internally.
- stmt.bind(8, false);
- } else {
- stmt.bind(7, util::compress(baton->response.data), true); // retain the string internally.
- stmt.bind(8, true);
- }
-
- stmt.run();
- }, [](void *data) {
- delete (PutBaton *)data;
- });
-}
-
-struct ExpirationBaton {
- util::ptr<Database> db;
- std::string path;
- int64_t expires;
-};
-
-void SQLiteStore::updateExpiration(const std::string &path, int64_t expires) {
- assert(std::this_thread::get_id() == thread_id);
- if (!db || !*db) return;
-
- ExpirationBaton *expiration_baton = new ExpirationBaton;
- expiration_baton->db = db;
- expiration_baton->path = path;
- expiration_baton->expires = expires;
-
- uv_worker_send(worker, expiration_baton, [](void *data) {
- ExpirationBaton *baton = (ExpirationBaton *)data;
- const std::string url = unifyMapboxURLs(baton->path);
- Statement stmt = // 1 2
- baton->db->prepare("UPDATE `http_cache` SET `expires` = ? WHERE `url` = ?");
- stmt.bind<int64_t>(1, baton->expires);
- stmt.bind(2, url.c_str());
- stmt.run();
- }, [](void *data) {
- delete (ExpirationBaton *)data;
- });
-}
-
-}