summaryrefslogtreecommitdiff
path: root/src/util/sqlite3.cpp
diff options
context:
space:
mode:
authorMike Morris <michael.patrick.morris@gmail.com>2014-10-10 12:24:45 -0400
committerMike Morris <michael.patrick.morris@gmail.com>2014-10-10 12:24:45 -0400
commit2d1219fa5154c489cd856bedd04b84573d45ac04 (patch)
treea8e42e6acd79f73aac228e0fe6876917067db8c4 /src/util/sqlite3.cpp
parent8f6e8eead12c6b2c2de0ce76fa7df39ca2445006 (diff)
parentf390dab0ea7d449bdd89855c84e47f4a07606fe4 (diff)
downloadqtlocation-mapboxgl-2d1219fa5154c489cd856bedd04b84573d45ac04.tar.gz
Merge branch 'master' into libuv-0.10-headless-display
Conflicts: common/curl_request.cpp common/glfw_view.cpp common/glfw_view.hpp include/mbgl/platform/request.hpp ios/mapbox-gl-cocoa setup-libraries.sh src/map/map.cpp src/platform/request.cpp test/fixtures/fixture_request.cpp
Diffstat (limited to 'src/util/sqlite3.cpp')
-rw-r--r--src/util/sqlite3.cpp166
1 files changed, 166 insertions, 0 deletions
diff --git a/src/util/sqlite3.cpp b/src/util/sqlite3.cpp
new file mode 100644
index 0000000000..19e0ce9c79
--- /dev/null
+++ b/src/util/sqlite3.cpp
@@ -0,0 +1,166 @@
+#include <mbgl/util/sqlite3.hpp>
+#include <sqlite3.h>
+
+#include <cassert>
+
+namespace mapbox {
+namespace sqlite {
+
+Database::Database(const std::string &filename, int flags) {
+ const int err = sqlite3_open_v2(filename.c_str(), &db, flags, nullptr);
+ if (err != SQLITE_OK) {
+ Exception ex { err, sqlite3_errmsg(db) };
+ db = nullptr;
+ throw ex;
+ }
+}
+
+Database::Database(Database &&other) {
+ *this = std::move(other);
+}
+
+Database &Database::operator=(Database &&other) {
+ std::swap(db, other.db);
+ return *this;
+}
+
+Database::~Database() {
+ if (db) {
+ const int err = sqlite3_close(db);
+ if (err != SQLITE_OK) {
+ throw Exception { err, sqlite3_errmsg(db) };
+ }
+ }
+}
+
+Database::operator bool() const {
+ return db != nullptr;
+}
+
+void Database::exec(const std::string &sql) {
+ assert(db);
+ char *msg = nullptr;
+ const int err = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &msg);
+ if (msg) {
+ Exception ex { err, msg };
+ sqlite3_free(msg);
+ throw ex;
+ } else if (err != SQLITE_OK) {
+ throw Exception { err, sqlite3_errmsg(db) };
+ }
+}
+
+Statement Database::prepare(const char *query) {
+ assert(db);
+ return std::move(Statement(db, query));
+}
+
+Statement::Statement(sqlite3 *db, const char *sql) {
+ const int err = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
+ if (err != SQLITE_OK) {
+ stmt = nullptr;
+ throw Exception { err, sqlite3_errmsg(db) };
+ }
+}
+
+#define CHECK_SQLITE_OK(err) \
+ if (err != SQLITE_OK) { \
+ throw Exception { err, sqlite3_errmsg(sqlite3_db_handle(stmt)) }; \
+ }
+
+Statement::Statement(Statement &&other) {
+ *this = std::move(other);
+}
+
+Statement &Statement::operator=(Statement &&other) {
+ std::swap(stmt, other.stmt);
+ return *this;
+}
+
+Statement::~Statement() {
+ if (stmt) {
+ const int err = sqlite3_finalize(stmt);
+ CHECK_SQLITE_OK(err)
+ }
+}
+
+Statement::operator bool() const {
+ return stmt != nullptr;
+}
+
+#define BIND_3(type, value) \
+ assert(stmt); \
+ const int err = sqlite3_bind_##type(stmt, offset, value); \
+ CHECK_SQLITE_OK(err)
+
+#define BIND_5(type, value, length, param) \
+ assert(stmt); \
+ const int err = sqlite3_bind_##type(stmt, offset, value, length, param); \
+ CHECK_SQLITE_OK(err)
+
+template <> void Statement::bind(int offset, int value) {
+ BIND_3(int, value)
+}
+
+template <> void Statement::bind(int offset, int64_t value) {
+ BIND_3(int64, value)
+}
+
+template <> void Statement::bind(int offset, double value) {
+ BIND_3(double, value)
+}
+
+template <> void Statement::bind(int offset, bool value) {
+ BIND_3(int, value)
+}
+
+template <> void Statement::bind(int offset, const char *value) {
+ BIND_5(text, value, -1, nullptr)
+}
+
+void Statement::bind(int offset, const std::string &value, bool retain) {
+ BIND_5(blob, value.data(), int(value.size()), retain ? SQLITE_TRANSIENT : SQLITE_STATIC)
+}
+
+bool Statement::run() {
+ assert(stmt);
+ const int err = sqlite3_step(stmt);
+ if (err == SQLITE_DONE) {
+ return false;
+ } else if (err == SQLITE_ROW) {
+ return true;
+ } else {
+ throw std::runtime_error("failed to run statement");
+ }
+}
+
+template <> int Statement::get(int offset) {
+ assert(stmt);
+ return sqlite3_column_int(stmt, offset);
+}
+
+template <> int64_t Statement::get(int offset) {
+ assert(stmt);
+ return sqlite3_column_int64(stmt, offset);
+}
+
+template <> double Statement::get(int offset) {
+ assert(stmt);
+ return sqlite3_column_double(stmt, offset);
+}
+
+template <> std::string Statement::get(int offset) {
+ assert(stmt);
+ return {
+ reinterpret_cast<const char *>(sqlite3_column_blob(stmt, offset)),
+ size_t(sqlite3_column_bytes(stmt, offset))
+ };
+}
+
+void Statement::reset() {
+ assert(stmt);
+ sqlite3_reset(stmt);
+}
+
+}
+}