Osmium  0.1
include/osmium/utils/sqlite.hpp
Go to the documentation of this file.
00001 #ifndef OSMIUM_UTILS_SQLITE_HPP
00002 #define OSMIUM_UTILS_SQLITE_HPP
00003 
00004 /*
00005 
00006 Copyright 2011 Jochen Topf <jochen@topf.org> and others (see README).
00007 
00008 This file is part of Osmium (https://github.com/joto/osmium).
00009 
00010 Osmium is free software: you can redistribute it and/or modify it under the
00011 terms of the GNU Lesser General Public License or (at your option) the GNU
00012 General Public License as published by the Free Software Foundation, either
00013 version 3 of the Licenses, or (at your option) any later version.
00014 
00015 Osmium is distributed in the hope that it will be useful, but WITHOUT ANY
00016 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
00017 PARTICULAR PURPOSE. See the GNU Lesser General Public License and the GNU
00018 General Public License for more details.
00019 
00020 You should have received a copy of the Licenses along with Osmium. If not, see
00021 <http://www.gnu.org/licenses/>.
00022 
00023 */
00024 
00025 #include <stdexcept>
00026 #include <string>
00027 #include <iostream>
00028 
00029 #include <sqlite3.h>
00030 
00031 namespace Osmium {
00032 
00036     namespace Sqlite {
00037 
00041         class Exception : public std::runtime_error {
00042 
00043         public:
00044 
00045             Exception(const std::string &msg, const std::string &error) : std::runtime_error(msg + ": " + error + '\n') {
00046             }
00047 
00048         };
00049 
00050         class Statement;
00051 
00055         class Database {
00056 
00057         private:
00058 
00059             sqlite3* db;
00060 
00061         public:
00062 
00063             Database(const char* filename) {
00064                 if (sqlite3_open_v2(filename, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0)) {
00065                     sqlite3_close(db);
00066                     throw Sqlite::Exception("Can't open database", errmsg());
00067                 }
00068             }
00069 
00070             ~Database() {
00071                 sqlite3_close(db);
00072             }
00073 
00074             const std::string &errmsg() const {
00075                 static std::string error = std::string(sqlite3_errmsg(db));
00076                 return error;
00077             }
00078 
00079             sqlite3* get_sqlite3() {
00080                 return db;
00081             }
00082 
00083             void begin_transaction() {
00084                 if (SQLITE_OK != sqlite3_exec(db, "BEGIN TRANSACTION;", 0, 0, 0)) {
00085                     std::cerr << "Database error: " << sqlite3_errmsg(db) << "\n";
00086                     sqlite3_close(db);
00087                     exit(1);
00088                 }
00089             }
00090 
00091             void commit() {
00092                 if (SQLITE_OK != sqlite3_exec(db, "COMMIT;", 0, 0, 0)) {
00093                     std::cerr << "Database error: " << sqlite3_errmsg(db) << "\n";
00094                     sqlite3_close(db);
00095                     exit(1);
00096                 }
00097             }
00098 
00099             Statement* prepare(const char* sql);
00100 
00101         }; // class Database
00102 
00106         class Statement {
00107 
00108         private:
00109 
00110             Database* db_;
00111             sqlite3_stmt* statement;
00112 
00113             int bindnum;
00114 
00115         public:
00116 
00117             Statement(Database* db, const char* sql) : db_(db), statement(0), bindnum(1) {
00118                 sqlite3_prepare_v2(db->get_sqlite3(), sql, -1, &statement, 0);
00119                 if (statement == 0) {
00120                     throw Sqlite::Exception("Can't prepare statement", db_->errmsg());
00121                 }
00122             }
00123 
00124             ~Statement() {
00125                 sqlite3_finalize(statement);
00126             }
00127 
00128             Statement* bind_null() {
00129                 if (SQLITE_OK != sqlite3_bind_null(statement, bindnum++)) {
00130                     throw Sqlite::Exception("Can't bind null value", db_->errmsg());
00131                 }
00132                 return this;
00133             }
00134 
00135             Statement* bind_text(const char* value) {
00136                 if (SQLITE_OK != sqlite3_bind_text(statement, bindnum++, value, -1, SQLITE_STATIC)) {
00137                     throw Sqlite::Exception("Can't bind text value", db_->errmsg());
00138                 }
00139                 return this;
00140             }
00141 
00142             Statement* bind_text(const std::string& value) {
00143                 if (SQLITE_OK != sqlite3_bind_text(statement, bindnum++, value.c_str(), -1, SQLITE_STATIC)) {
00144                     throw Sqlite::Exception("Can't bind text value", db_->errmsg());
00145                 }
00146                 return this;
00147             }
00148 
00149             Statement* bind_int(int value) {
00150                 if (SQLITE_OK != sqlite3_bind_int(statement, bindnum++, value)) {
00151                     throw Sqlite::Exception("Can't bind int value", db_->errmsg());
00152                 }
00153                 return this;
00154             }
00155 
00156             Statement* bind_int64(int64_t value) {
00157                 if (SQLITE_OK != sqlite3_bind_int64(statement, bindnum++, value)) {
00158                     throw Sqlite::Exception("Can't bind int64 value", db_->errmsg());
00159                 }
00160                 return this;
00161             }
00162 
00163             Statement* bind_double(double value) {
00164                 if (SQLITE_OK != sqlite3_bind_double(statement, bindnum++, value)) {
00165                     throw Sqlite::Exception("Can't bind double value", db_->errmsg());
00166                 }
00167                 return this;
00168             }
00169 
00170             Statement* bind_blob(const void* value, int length) {
00171                 if (SQLITE_OK != sqlite3_bind_blob(statement, bindnum++, value, length, 0)) {
00172                     throw Sqlite::Exception("Can't bind blob value", db_->errmsg());
00173                 }
00174                 return this;
00175             }
00176 
00177             void execute() {
00178                 sqlite3_step(statement);
00179                 if (SQLITE_OK != sqlite3_reset(statement)) {
00180                     throw Sqlite::Exception("Can't execute statement", db_->errmsg());
00181                 }
00182                 bindnum = 1;
00183             }
00184 
00185         }; // class Statement
00186 
00187         inline Statement* Database::prepare(const char* sql) {
00188             return new Statement(this, sql);
00189         }
00190 
00191     } // namespace Sqlite
00192 
00193 } // namespace Osmium
00194 
00195 #endif // OSMIUM_UTILS_SQLITE_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines