libsqlite3x 2007.10.18
sqlite3x_command.cpp
00001 /*
00002   Copyright (C) 2004-2005 Cory Nelson
00003   Copyright (C) 2006 stephan beal
00004 
00005   This software is provided 'as-is', without any express or implied
00006   warranty.  In no event will the authors be held liable for any damages
00007   arising from the use of this software.
00008 
00009   Permission is granted to anyone to use this software for any purpose,
00010   including commercial applications, and to alter it and redistribute it
00011   freely, subject to the following restrictions:
00012 
00013   1. The origin of this software must not be misrepresented; you must not
00014   claim that you wrote the original software. If you use this software
00015   in a product, an acknowledgment in the product documentation would be
00016   appreciated but is not required.
00017   2. Altered source versions must be plainly marked as such, and must not be
00018   misrepresented as being the original software.
00019   3. This notice may not be removed or altered from any source distribution.
00020     
00021 */
00022 
00023 #include <sqlite3.h>
00024 #include "sqlite3x.hpp"
00025 #include <cstring> // strlen()
00026 #include <iostream> // only for debuggin
00027 namespace sqlite3x {
00028 
00029     sqlite3_command::sqlite3_command(sqlite3_connection &con)
00030         : con(con),stmt(0),refs(0),argc(0)
00031     {
00032     }
00033 
00034 
00035     sqlite3_command::sqlite3_command(sqlite3_connection &con, const std::string &sql)
00036         : con(con),stmt(0),refs(0),argc(0)
00037     {
00038         this->prepare( sql );
00039     }
00040 
00041     sqlite3_command::sqlite3_command(sqlite3_connection &con, char const * sql, size_t len )
00042         : con(con),stmt(0),refs(0),argc(0)
00043     {
00044         this->prepare( sql, static_cast<int>( len ) );
00045     }
00046 
00047 #if SQLITE3X_USE_WCHAR
00048     sqlite3_command::sqlite3_command(sqlite3_connection &con, const std::wstring &sql) : con(con),stmt(0),refs(0),argc(0) {
00049         const void *tail=NULL;
00050         int rc =
00051 #if (SQLITE_VERSION_NUMBER >= 3003009)
00052                         sqlite3_prepare16_v2
00053 #else
00054                         sqlite3_prepare16
00055 #endif
00056             (con.db(), sql.data(), (int)sql.length()*2, &this->stmt, &tail);
00057         if( SQLITE_OK != rc )
00058         {
00059             throw database_error("sqlite3_command::prepare failed. Reason=[%s]",
00060                          sqlite3_errmsg( this->con.db() ) );
00061         }
00062         this->argc=sqlite3_column_count(this->stmt);
00063     }
00064 #endif
00065 
00066     void sqlite3_command::prepare( char const * sql, int len )
00067     {
00068         if( this->stmt ) this->finalize();
00069         const char *tail=NULL;
00070         int rc =
00071 #if (SQLITE_VERSION_NUMBER >= 3003009)
00072                         sqlite3_prepare_v2
00073 #else
00074                         sqlite3_prepare
00075 #endif
00076             ( this->con.db(), sql, len, &(this->stmt), &tail );
00077         if( SQLITE_OK != rc )
00078         {
00079             throw database_error("sqlite3_command::prepare([%s]) failed. Reason=[%s]",
00080                          sql, sqlite3_errmsg( this->con.db() ) );
00081         }
00082         this->argc=sqlite3_column_count(this->stmt);
00083     }
00084 
00085     void sqlite3_command::prepare( std::string const & sql )
00086     {
00087         this->prepare( sql.c_str(),  static_cast<int>(  sql.size()) );
00088     }
00089 
00090 
00091     sqlite3_command::~sqlite3_command() {
00092         try
00093         {
00094             this->finalize();
00095         }
00096         catch(...)
00097         {
00098             // std::cout << "sqlite3_command::~sqlite3_command() ignoring an exception!\n";
00099             // silently ignore
00100         }
00101     }
00102 
00103     void sqlite3_command::finalize()
00104     {
00105         if( this->stmt )
00106         {
00107             if(sqlite3_finalize(this->stmt)!=SQLITE_OK)
00108                 throw database_error(this->con);
00109             this->stmt = 0;
00110         }
00111     }
00112 
00113     void sqlite3_command::bind(int index) {
00114         if(sqlite3_bind_null(this->stmt, index)!=SQLITE_OK)
00115             throw database_error(this->con);
00116     }
00117 
00118     void sqlite3_command::bind(int index, int data) {
00119         if(sqlite3_bind_int(this->stmt, index, data)!=SQLITE_OK)
00120             throw database_error(this->con);
00121     }
00122 
00123     void sqlite3_command::bind(int index, int64_t data) {
00124         if(sqlite3_bind_int64(this->stmt, index, data)!=SQLITE_OK)
00125             throw database_error(this->con);
00126     }
00127 
00128     void sqlite3_command::bind(int index, double data) {
00129         if(sqlite3_bind_double(this->stmt, index, data)!=SQLITE_OK)
00130             throw database_error(this->con);
00131     }
00132 
00133     void sqlite3_command::bind(int index, const char *data, int datalen) {
00134         if(sqlite3_bind_text(this->stmt, index, data,
00135             static_cast<int>(
00136             ((-1==datalen)
00137             ? std::strlen(data)
00138             : datalen)
00139             ),
00140             SQLITE_TRANSIENT)!=SQLITE_OK)
00141             throw database_error(this->con);
00142     }
00143 
00144 #if SQLITE3X_USE_WCHAR
00145     void sqlite3_command::bind(int index, const wchar_t *data, int datalen) {
00146         if(sqlite3_bind_text16(this->stmt, index, data, datalen, SQLITE_TRANSIENT)!=SQLITE_OK)
00147             throw database_error(this->con);
00148     }
00149 #endif
00150 
00151     void sqlite3_command::bind(int index, const void *data, int datalen) {
00152         if(sqlite3_bind_blob(this->stmt, index, data, datalen, SQLITE_TRANSIENT)!=SQLITE_OK)
00153             throw database_error(this->con);
00154     }
00155 
00156     void sqlite3_command::bind(int index, const std::string &data) {
00157         if(sqlite3_bind_text(this->stmt, index, data.data(), (int)data.length(), SQLITE_TRANSIENT)!=SQLITE_OK)
00158             throw database_error(this->con);
00159     }
00160 
00161 #if SQLITE3X_USE_WCHAR
00162     void sqlite3_command::bind(int index, const std::wstring &data) {
00163         if(sqlite3_bind_text16(this->stmt, index, data.data(), (int)data.length()*2, SQLITE_TRANSIENT)!=SQLITE_OK)
00164             throw database_error(this->con);
00165     }
00166 #endif
00167 
00168     sqlite3_cursor sqlite3_command::executecursor() {
00169         return sqlite3_cursor(*this);
00170     }
00171 
00172     void sqlite3_command::executenonquery() {
00173         this->executecursor().step();
00174     }
00175 
00176     int sqlite3_command::executeint() {
00177         sqlite3_cursor reader=this->executecursor();
00178         if(!reader.step()) throw database_error("nothing to read");
00179         return reader.getint(0);
00180     }
00181 
00182     int64_t sqlite3_command::executeint64() {
00183         sqlite3_cursor reader=this->executecursor();
00184         if(!reader.step()) throw database_error("nothing to read");
00185         return reader.getint64(0);
00186     }
00187 
00188     double sqlite3_command::executedouble() {
00189         sqlite3_cursor reader=this->executecursor();
00190         if(!reader.step()) throw database_error("nothing to read");
00191         return reader.getdouble(0);
00192     }
00193 
00194     char const * sqlite3_command::executestring( int & size ) {
00195         sqlite3_cursor reader=this->executecursor();
00196         if(!reader.step()) throw database_error("nothing to read");
00197             return reader.getstring( 0, size );
00198     }
00199 
00200     std::string sqlite3_command::executestring() {
00201         sqlite3_cursor reader=this->executecursor();
00202         if(!reader.step()) throw database_error("nothing to read");
00203         return reader.getstring(0);
00204     }
00205 
00206 #if SQLITE3X_USE_WCHAR
00207     std::wstring sqlite3_command::executestring16() {
00208         sqlite3_cursor reader=this->executecursor();
00209         if(!reader.step()) throw database_error("nothing to read");
00210         return reader.getstring16(0);
00211     }
00212 #endif
00213 
00214     std::string sqlite3_command::executeblob() {
00215         sqlite3_cursor reader=this->executecursor();
00216         if(!reader.step()) throw database_error("nothing to read");
00217         return reader.getblob(0);
00218     }
00219 
00220     void const * sqlite3_command::executeblob( int & size ) {
00221         sqlite3_cursor reader=this->executecursor();
00222         if(!reader.step()) throw database_error("nothing to read");
00223         return reader.getblob(0, size);
00224     }
00225 
00226     int sqlite3_command::colcount()
00227     {
00228         if( ! this->stmt )
00229         {
00230             throw database_error("sqlite3_command::colcount(): statement has not been prepared");
00231         }
00232         return sqlite3_column_count( this->stmt );
00233     }
00234 
00235 
00236     bool sqlite3_command::reset()
00237     {
00238         int rc = SQLITE_OK;
00239         if( this->stmt )
00240         {
00241             rc = sqlite3_reset( this->stmt );
00242         }
00243         return rc == SQLITE_OK;
00244     }
00245 
00246     sqlite3_stmt * sqlite3_command::handle()
00247     {
00248         return this->stmt;
00249     }
00250 
00251 
00252 }