/home/martin/workspace/OpenStreetNav/src/sqlite/Statement.cpp
Go to the documentation of this file.
00001 /*
00002  * Statement.cpp
00003  *
00004  *  Created on: Nov 2, 2011
00005  *      Author: martin
00006  */
00007 
00008 #include "Statement.h"
00009 #include "SqliteException.h"
00010 #include "InvalidUseException.h"
00011 #include <utility>
00012 #include <tuple>
00013 
00014 namespace sqlite
00015 {
00016 
00017 Statement::Statement():
00018     stmt(NULL),
00019     db(NULL),
00020     cols(0),
00021     hrow(false),
00022     dn(false)
00023 {
00024 }
00025 
00026 Statement::Statement(const std::string& sql, Database& db):
00027     stmt(NULL),
00028     db(&db),
00029     hrow(false),
00030     dn(false)
00031 {
00032     const char* a;
00033     throw_sqlite_status(sqlite3_prepare_v2(db.cobj(), sql.c_str(), -1, &stmt, &a), db.cobj());
00034     if (stmt == NULL)
00035     {
00036         cols = 0;
00037     }
00038     else
00039     {
00040         cols = sqlite3_column_count(stmt);
00041         db.register_statement(*this);
00042     }
00043 }
00044 
00045 Statement::~Statement()
00046 {
00047     finalize();
00048 }
00049 
00050 Statement& Statement::operator =(Statement && other)
00051 {
00052     finalize();
00053     stmt = other.stmt;
00054     dn = other.dn;
00055     hrow = other.hrow;
00056     db = other.db;
00057     cols = other.cols;
00058     db->unregister_statement(other);
00059     other.stmt = NULL;
00060     if (stmt != NULL)
00061         db->register_statement(*this);
00062     return *this;
00063 }
00064 
00065 Statement::Statement(Statement && other)
00066     : stmt(NULL),
00067       db(NULL)
00068 {
00069     *this = std::move(other);
00070 }
00071 
00072 bool Statement::done()
00073 {
00074     if (stmt == NULL)
00075         throw InvalidUseException("Call for done after finalization");
00076     return dn;
00077 }
00078 
00079 bool Statement::has_row()
00080 {
00081     if (stmt == NULL)
00082         throw InvalidUseException("Call for has_row after finalization");
00083     return hrow;
00084 }
00085 
00086 void Statement::step()
00087 {
00088     if (stmt == NULL)
00089         throw InvalidUseException("Call for step after finalization");
00090     dn = false;
00091     hrow = false;
00092     int status = sqlite3_step(stmt);
00093     if (status == SQLITE_ROW)
00094     {
00095         hrow = true;
00096         dn = false;
00097         return;
00098     }
00099     if (status == SQLITE_DONE)
00100     {
00101         reset_internal();
00102         hrow = false;
00103         dn = true;
00104         return;
00105     }
00106     if (status == SQLITE_BUSY)
00107     {
00108         std::string msg(sqlite3_errmsg(db->cobj()));
00109         reset_nothrow();
00110         throw SqliteException(status, msg);
00111     }
00112     if (status == SQLITE_MISUSE)
00113     {
00114         reset_nothrow();
00115         throw_sqlite_status(status, db->cobj());
00116     }
00117     reset_internal();
00118 }
00119 
00120 void Statement::reset()
00121 {
00122     if (stmt == NULL)
00123         throw InvalidUseException("Call for reset after finalization");
00124     if (dn)
00125     {
00126         dn = false;
00127         hrow = false;
00128     }
00129     else if (hrow)
00130     {
00131         reset_internal();
00132         hrow = false;
00133         dn = false;
00134     }
00135 }
00136 
00137 void Statement::reset_internal()
00138 {
00139     throw_sqlite_status(sqlite3_reset(stmt), db->cobj());
00140 }
00141 
00142 void Statement::reset_nothrow()
00143 {
00144     sqlite3_reset(stmt);
00145 }
00146 
00147 double Statement::val_double(int col_index)
00148 {
00149     check_value_conditions(col_index);
00150     return sqlite3_column_double(stmt, col_index);
00151 }
00152 
00153 int64_t Statement::val_int64(int col_index)
00154 {
00155     check_value_conditions(col_index);
00156     return sqlite3_column_int64(stmt, col_index);
00157 }
00158 
00159 int Statement::val_int(int col_index)
00160 {
00161     check_value_conditions(col_index);
00162     return sqlite3_column_int(stmt, col_index);
00163 }
00164 
00165 std::string Statement::val_string(int col_index)
00166 {
00167     check_value_conditions(col_index);
00168     const unsigned char* ptr = sqlite3_column_text(stmt, col_index);
00169     const char* cptr = reinterpret_cast<const char*>(ptr);
00170     return std::string(cptr);
00171 }
00172 
00173 void Statement::bind_double(int param_index, double value)
00174 {
00175     throw_sqlite_status(sqlite3_bind_double(stmt, param_index, value), db->cobj());
00176 }
00177 
00178 void Statement::bind_int(int param_index, int value)
00179 {
00180     throw_sqlite_status(sqlite3_bind_int(stmt, param_index, value), db->cobj());
00181 }
00182 
00183 void Statement::bind_int64(int param_index, int64_t value)
00184 {
00185     throw_sqlite_status(sqlite3_bind_int64(stmt, param_index, value), db->cobj());
00186 }
00187 
00188 void Statement::bind_string(int param_index, const std::string& value)
00189 {
00190     throw_sqlite_status(sqlite3_bind_text(stmt, param_index, value.c_str(), value.size(), SQLITE_TRANSIENT), db->cobj());
00191 }
00192 
00193 Statement::ColType<double> coldouble()
00194 {
00195     return Statement::coldouble;
00196 }
00197 
00198 Statement::ColType<int> colint()
00199 {
00200     return Statement::colint;
00201 }
00202 
00203 Statement::ColType<int64_t> colint64()
00204 {
00205     return Statement::colint64;
00206 }
00207 
00208 Statement::ColType<std::string> colstr()
00209 {
00210     return Statement::colstring;
00211 }
00212 
00213 void Statement::check_value_conditions(int col)
00214 {
00215     if (stmt == NULL)
00216         throw InvalidUseException("Call for value after finalization");
00217     if (!hrow)
00218         throw InvalidUseException("Asking for row data with no row available");
00219     if (col < 0 || col >= cols)
00220         throw InvalidUseException("Column index out of bounds");
00221 }
00222 
00223 void Statement::finalize()
00224 {
00225     if (stmt == NULL)
00226         return;
00227     sqlite3_finalize(stmt);
00228     db->unregister_statement(*this);
00229     stmt = NULL;
00230 }
00231 
00232 void execute_sql(std::string sql, Database& db)
00233 {
00234     Statement st(sql, db);
00235     st.step();
00236 }
00237 
00238 }
00239 
00240 
00241 
00242 
00243 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines