Osmium
0.1
|
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