diff options
Diffstat (limited to 'src/mbgl/storage/sqlite_store.cpp')
-rw-r--r-- | src/mbgl/storage/sqlite_store.cpp | 228 |
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; - }); -} - -} |