void SQLiteStore::get(const std::string &path, GetCallback callback, void *ptr) {
    assert(uv_thread_self() == 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 = std::unique_ptr<Response>(new 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);
        }
    });
}
void SQLiteStore::updateExpiration(const std::string &path, int64_t expires) {
    assert(uv_thread_self() == 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;
    });
}