view database/sqlite/src/driver.cpp @ 96:55300686bd78

CMake: check that vera++ is at least 1.3.0, closes #656
author David Demelier <markand@malikania.fr>
date Thu, 08 Jun 2017 11:27:32 +0200
parents b0593a3e2ca8
children
line wrap: on
line source

#include <boost/dll.hpp>

#include <unordered_map>
#include <string>

#include "driver.hpp"

/*
 * Global shared stuff for the driver
 * ------------------------------------------------------------------
 */

namespace sqlite {

std::unique_ptr<sqlite3, int (*)(sqlite3 *)> database{nullptr, nullptr};

statement prepare(const std::string& sql)
{
    sqlite3_stmt* stmt;

    if (sqlite3_prepare_v2(database.get(), sql.c_str(), sql.length(), &stmt, nullptr) != SQLITE_OK) {
        throw std::runtime_error(sqlite3_errmsg(database.get()));
    }

    return {stmt, &sqlite3_finalize};
}

} // !sqlite

/*
 * Local function to this file.
 * ------------------------------------------------------------------
 */

namespace {

const std::string verify_query(
    "select name "
    "from sqlite_master "
    "where type='table' "
    "and name='mk_info'"
);

bool is_initialized()
{
    auto stmt = sqlite::prepare(verify_query);

    if (sqlite3_step(stmt.get()) != SQLITE_ROW) {
        return false;
    }

    return strcmp((char*)sqlite3_column_text(stmt.get(), 0), "mk_info") == 0;
}

} // !namespace

/*
 * Driver API
 * ------------------------------------------------------------------
 */

extern "C" {

BOOST_SYMBOL_EXPORT void malikania_driver_load(const std::unordered_map<std::string, std::string>& params)
{
    auto path = params.find("path");

    if (path == params.end()) {
        throw std::runtime_error("missing 'path' parameter");
    }

    sqlite3* db;

    if (sqlite3_open(path->second.c_str(), &db) != SQLITE_OK) {
        throw std::runtime_error(sqlite3_errmsg(db));
    }

    sqlite::database = {db, &sqlite3_close};

    if (!is_initialized()) {
        throw std::runtime_error("database not initialized");
    }
}

BOOST_SYMBOL_EXPORT void malikania_driver_unload()
{
    // Explicit destruction, optional.
    sqlite::database = nullptr;
}

} // !C