libsq3 2007.10.18
sq3.cpp
00001 #if 0
00002 #  ifndef COUT
00003 #    include <iostream>
00004 #    define COUT std::cerr << "SQ3:"<<__FILE__ << ":" << std::dec<<__LINE__ << ": "
00005 #  endif
00006 #endif
00007 
00008 #include "sq3.hpp"
00009 #include <vector>
00010 #include <sstream>
00011 #include <cstring>
00012 
00013 #if SQ3_USE_WCHAR
00014 #include <cwchar>
00015 #endif
00016 
00017 namespace sq3 {
00018 
00019     void statement_reset_finalizer::operator()( ::sq3::statement * & st )
00020     {
00021         if( st )
00022         {
00023             st->reset();
00024             st = 0;
00025         }
00026     }
00027 
00028     void sqlite3_stmt_reset_finalizer::operator()( sqlite3_stmt * & st )
00029     {
00030         if( st )
00031         {
00032             sqlite3_reset( st );
00033             st = 0;
00034         }
00035     }
00036 
00037     void sqlite3_stmt_finalizer::operator()( sqlite3_stmt * & st )
00038     {
00039         if( st )
00040         {
00041             sqlite3_finalize( st );
00042             st = 0;
00043         }
00044     }
00045 
00046     void sqlite3_finalizer::operator()( sqlite3 * & s )
00047     {
00048         if( s )
00049         {
00050             sqlite3_close( s );
00051             s = 0;
00052         }
00053     }
00054 
00055 
00056     bool rc_is_okay( int rc )
00057     {
00058         return ((SQLITE_DONE==rc) || (SQLITE_OK==rc) || (SQLITE_ROW==rc));
00059     }
00060 
00061 
00062     int statement::prepare( std::string const & sql )
00063     {
00064         return this->prepare( sql.c_str(), static_cast<int>(sql.size()) );
00065     }
00066 
00067     int statement::prepare( char const * sql, int len )
00068     {
00069         // FIXME: make this function clean up any existing sqlite3_stmt.
00070         const char *tail=NULL;
00071         if( 0 > len ) len = static_cast<int>(strlen(sql));
00072         sqlite3_stmt * st = 0;
00073         
00074         int rc = 
00075 #if (SQLITE_VERSION_NUMBER >= 3003009)
00076             sqlite3_prepare_v2
00077 #else
00078             sqlite3_prepare
00079 #endif
00080             (this->m_db.handle(), sql, len, &st, &tail);
00081         
00082         if( SQLITE_OK == rc )
00083         {
00084             this->m_argc = sqlite3_column_count(st);
00085             this->m_stmt.take( st );
00086         }
00087         else
00088         {
00089             this->finalize();
00090         }
00091         return rc;
00092     }
00093 
00094 #if SQ3_USE_WCHAR
00095     int statement::prepare( sqlite3_wstring_t const sql, int byteCount )
00096     {
00097         void const * tail = NULL;
00098         if( 0 > byteCount ) byteCount = ????;
00099         sqlite3_stmt * st = 0;
00100         int rc = 
00101 #if SQLITE_VERSION_NUMBER >= 3003009
00102             sqlite3_prepare16_v2
00103 #else
00104             sqlite3_prepare16
00105 #endif
00106             (this->m_db.handle(), sql, byteCount, &st, &tail);
00107         if( SQLITE_OK == rc )
00108         {
00109             this->m_argc = sqlite3_column_count(st);
00110             this->m_stmt.take(st);
00111         }
00112         else
00113         {
00114             this->finalize();
00115         }
00116         return rc;
00117 
00118     }
00119 #endif // SQ3_USE_WCHAR
00120 
00121 
00122     int statement::finalize()
00123     {
00124         int rc = SQLITE_ERROR;
00125         if( this->m_stmt.get() )
00126         {
00127             rc = SQLITE_OK; // we'll fudge a bit here.
00128             //sqlite3_finalize(this->m_stmt.get());
00129             this->m_stmt.take(0); // give up ownership.
00130         }
00131         return rc;
00132     }
00133 
00134 
00135     statement::statement( database & db )
00136         : m_db(db), m_stmt(0), m_argc(0)
00137     {
00138     }
00139 
00140     statement::statement( database & db, std::string const & sql )
00141         : m_db(db), m_stmt(0), m_argc(0)
00142     {
00143         this->prepare( sql );
00144     }
00145     statement::statement( database & db, char const * sql, int byteCount )
00146         : m_db(db), m_stmt(0), m_argc(0)
00147     {
00148         this->prepare( sql, byteCount );
00149     }
00150 
00151 #if SQ3_USE_WCHAR
00152     statement::statement( database & db, std::wstring const & sql )
00153         : m_db(db), m_stmt(0), m_argc(0)
00154     {
00155         this->prepare( sql );
00156     }
00157     statement::statement( database & db, wchar_t const * sql, int byteCount )
00158         : m_db(db), m_stmt(0), m_argc(0)
00159     {
00160         this->prepare( sql, byteCount );
00161     }
00162 #endif // SQ3_USE_WCHAR
00163 
00164 
00165     bool statement::is_prepared() const
00166     {
00167         return 0 != this->m_stmt.get();
00168     }
00169     statement::~statement()
00170     {
00171         this->finalize();
00172     }
00173     int statement::bind( int index )
00174     {
00175         return sqlite3_bind_null( this->m_stmt.get(), index);
00176     }
00177     int statement::bind( int index, int data )
00178     {
00179         return sqlite3_bind_int( this->m_stmt.get(), index, data );
00180     }
00181     int statement::bind( int index, int64_t data )
00182     {
00183         return sqlite3_bind_int64( this->m_stmt.get(), index, data );
00184     }
00185     int statement::bind( int index, double data )
00186     {
00187         return sqlite3_bind_double( this->m_stmt.get(), index, data );
00188     }
00189     int statement::bind( int index, char const * data, int len )
00190     {
00191         if( 0 > len ) len = static_cast<int>(strlen(data));
00192         return sqlite3_bind_text( this->m_stmt.get(), index, data, len, SQLITE_TRANSIENT );
00193     }
00194     int statement::bind( int index, void const * data, int len )
00195     {
00196         return sqlite3_bind_blob( this->m_stmt.get(), index, data, len, SQLITE_TRANSIENT );
00197     }
00198     //int statement::bind( int index, wchar_t const * data, int len );
00199     int statement::bind( int index, std::string const & data )
00200     {
00201         return this->bind( index, data.c_str(), static_cast<int>(data.size() ) );
00202     }
00203     //int statement::bind( int index, std::wstring const & data );
00204 
00205     int statement::bind( char const * index )
00206     {
00207         return sqlite3_bind_null( this->m_stmt.get(),
00208                       sqlite3_bind_parameter_index( this->m_stmt.get(), index ) );
00209     }
00210     int statement::bind( char const * index, int data )
00211     {
00212         return sqlite3_bind_int( this->m_stmt.get(),
00213                      sqlite3_bind_parameter_index( this->m_stmt.get(), index ), data );
00214     }
00215     int statement::bind( char const * index, int64_t data )
00216     {
00217         return sqlite3_bind_int64( this->m_stmt.get(),
00218                        sqlite3_bind_parameter_index( this->m_stmt.get(), index ), data );
00219     }
00220     int statement::bind( char const * index, double data )
00221     {
00222         return sqlite3_bind_double( this->m_stmt.get(),
00223                         sqlite3_bind_parameter_index( this->m_stmt.get(), index ), data );
00224     }
00225     int statement::bind( char const * index, char const * data, int len )
00226     {
00227         if( 0 > len ) len = static_cast<int>(strlen(data) );
00228         return sqlite3_bind_text( this->m_stmt.get(),
00229                       sqlite3_bind_parameter_index( this->m_stmt.get(), index ) , data, len, SQLITE_TRANSIENT );
00230     }
00231     int statement::bind( char const * index, void const * data, int len )
00232     {
00233         return sqlite3_bind_blob( this->m_stmt.get(),
00234                       sqlite3_bind_parameter_index( this->m_stmt.get(), index ) , data, len, SQLITE_TRANSIENT );
00235     }
00236 
00237     int statement::bind( char const * index, std::string const & data )
00238     {
00239         return this->bind( index, data.c_str(), static_cast<int>(data.size() ) );
00240     }
00241 
00242 
00243 
00244 
00245 
00246     cursor statement::get_cursor()
00247     {
00248         return cursor(*this);
00249     }
00250     int statement::execute()
00251     {
00252         return this->get_cursor().step();
00253     }
00254 
00255 #define STATEMENT_EXECUTE_1ARG_IMPL \
00256         cursor rd( this->get_cursor() ); \
00257         int rc = rd.step(); \
00258         if( SQLITE_ROW == rc ) \
00259         { \
00260             rc = rd.get(0,tgt); \
00261         } \
00262         return rc;
00263 
00264     int statement::execute( int & tgt )
00265     {
00266         STATEMENT_EXECUTE_1ARG_IMPL;
00267     }
00268     int statement::execute( int64_t & tgt )
00269     {
00270         STATEMENT_EXECUTE_1ARG_IMPL;
00271     }
00272     int statement::execute( double & tgt )
00273     {
00274         STATEMENT_EXECUTE_1ARG_IMPL;
00275     }
00276     int statement::execute( std::string & tgt )
00277     {
00278         STATEMENT_EXECUTE_1ARG_IMPL;
00279     }
00280 #undef STATEMENT_EXECUTE_1ARG_IMPL
00281 
00282     int statement::execute( sqlite3_text_char_t const ** tgt, int & len )
00283     {
00284         cursor rd( this->get_cursor() );
00285         int rc = rd.step();
00286         if( SQLITE_ROW == rc )
00287         {
00288             rc = rd.get(0,tgt,len);
00289         }
00290         return rc;
00291     }
00292     int statement::execute( void const ** tgt, int & len )
00293     {
00294         cursor rd( this->get_cursor() );
00295         int rc = rd.step();
00296         if( SQLITE_ROW == rc )
00297         {
00298             rc = rd.get(0,tgt,len);
00299         }
00300         return rc;
00301     }
00302 
00303 
00304     int statement::reset()
00305     {
00306         return this->m_stmt.get()
00307             ? sqlite3_reset( this->m_stmt.get() )
00308             : SQLITE_ERROR;
00309     }
00310 
00311     int statement::colcount()
00312     {
00313         return this->m_stmt.get()
00314             ? this->m_argc
00315             : -1;
00316     }
00317 
00318     char const * statement::colname( int index )
00319     {
00320         int count = this->colcount();
00321         if( -1 == count ) return 0;
00322         if( (index < 0) || (index >= count) ) return 0;
00323         return sqlite3_column_name(this->m_stmt.get(), index);
00324     }
00325 
00326     int statement::colname( int index, char const ** cn )
00327     {
00328         char const * c = this->colname( index );
00329         if( c ) *cn = c;
00330         return c ? SQLITE_OK : SQLITE_ERROR;
00331     }
00332 
00333 
00334     cursor::cursor() : m_stmt(0),m_cn(0)
00335     {
00336     }
00337     cursor::cursor( cursor const & cp ) : m_stmt(cp.m_stmt),m_cn(0)
00338     {
00339         this->copy(cp);
00340     }
00341 
00342     cursor::cursor( statement & st ) : m_stmt(&st),m_cn(0)
00343     {
00344         this->m_stmt.take(&st);
00345     }
00346 
00347     cursor & cursor::operator=( cursor const & cp )
00348     {
00349         if( &cp == this ) return *this;
00350         this->copy(cp);
00351         return *this;
00352     }
00353 
00354     void cursor::copy( cursor const & rhs )
00355     {
00356         if( &rhs == this ) return;
00357         this->close();
00358         this->m_stmt = rhs.m_stmt;
00359         if( rhs.m_cn )
00360         {
00361             this->m_cn = new NameToIndexMap(*rhs.m_cn);
00362         }
00363     }
00364 
00365     cursor::~cursor()
00366     {
00367         this->close();
00368     }
00369 
00370     int cursor::step()
00371     {
00372         return this->m_stmt.get()
00373             ? sqlite3_step(this->m_stmt->m_stmt.get())
00374             : SQLITE_ERROR;
00375     }
00376 
00377     int cursor::reset()
00378     {
00379         delete this->m_cn;
00380         this->m_cn = 0;
00381         return this->m_stmt.get()
00382             ? this->m_stmt->reset()
00383             : SQLITE_ERROR;
00384     }
00385     void cursor::close()
00386     {
00387         this->m_stmt.take(0);
00388         if( this->m_cn )
00389         {
00390             delete this->m_cn;
00391             this->m_cn = 0;
00392         }
00393     }
00394 
00395     int cursor::colcount()
00396     {
00397         return this->m_stmt.get()
00398             ? this->m_stmt->colcount()
00399             : -1;
00400     }
00401 
00402 #define CURSOR_CHECK_INDEX \
00403     if( ! this->m_stmt.get() ) return SQLITE_ERROR;         \
00404     if( (index)>(this->m_stmt->m_argc-1)) return SQLITE_ERROR;
00405 
00406     int cursor::isnull( int index, bool & tgt )
00407     {
00408         CURSOR_CHECK_INDEX;
00409         tgt = sqlite3_column_type( this->m_stmt->m_stmt.get(), index) == SQLITE_NULL;
00410         return SQLITE_OK;
00411     }
00412 
00413     int cursor::get( int index, int & tgt )
00414     {
00415         CURSOR_CHECK_INDEX;
00416         tgt = sqlite3_column_int( this->m_stmt->m_stmt.get(), index );
00417         return SQLITE_OK;
00418     }
00419     int cursor::get( int index, int64_t & tgt )
00420     {
00421         CURSOR_CHECK_INDEX;
00422         tgt = sqlite3_column_int64( this->m_stmt->m_stmt.get(), index );
00423         return SQLITE_OK;
00424     }
00425     int cursor::get( int index, double & tgt )
00426     {
00427         CURSOR_CHECK_INDEX;
00428         tgt = sqlite3_column_double( this->m_stmt->m_stmt.get(), index );
00429         return SQLITE_OK;
00430     }
00431     int cursor::get( int index, std::string & tgt )
00432     {
00433         CURSOR_CHECK_INDEX;
00434         char const * x = (const char*)sqlite3_column_text(this->m_stmt->m_stmt.get(), index);
00435         int sz = sqlite3_column_bytes(this->m_stmt->m_stmt.get(), index);
00436         if( 0 < sz )
00437         {
00438             tgt = std::string( x, x+sz );
00439         }
00440         else
00441         {
00442             tgt = std::string();
00443         }
00444         return SQLITE_OK;
00445     }
00446     int cursor::get( int index, sqlite3_text_char_t const ** tgt, int & sz )
00447     {
00448         CURSOR_CHECK_INDEX;
00449         sz = sqlite3_column_bytes(this->m_stmt->m_stmt.get(), index);
00450         if( 0 < sz )
00451         {
00452             *tgt = sqlite3_column_text( this->m_stmt->m_stmt.get(), index);
00453         }
00454         else
00455         {
00456             tgt = 0;
00457         }
00458         return SQLITE_OK;
00459     }
00460     int cursor::get( int index, void  const ** tgt, int & sz )
00461     {
00462         CURSOR_CHECK_INDEX;
00463         sz = sqlite3_column_bytes(this->m_stmt->m_stmt.get(), index);
00464         if( 0 < sz )
00465         {
00466             *tgt = sqlite3_column_blob(this->m_stmt->m_stmt.get(), index);
00467         }
00468         return SQLITE_OK;
00469     }
00470 
00471 
00472     /**
00473        CURSOR_GET_STRING_IMPL2 is the implementation for the get(string,xxx) family of funcs
00474        which take 2 arguments.
00475     */
00476 #define CURSOR_GET_STRING_IMPL2(vaR,targetNamE) \
00477     if( ! this->m_stmt.get() ) return SQLITE_ERROR;            \
00478         if( 0 == this->index_colnames() ) return SQLITE_ERROR; \
00479         NameToIndexMap::const_iterator n2iit = this->m_cn->find( vaR ); \
00480         return ( this->m_cn->end() == n2iit ) ? SQLITE_ERROR : this->get( (*n2iit).second, targetNamE );
00481 
00482     /**
00483        CURSOR_GET_STRING_IMPL3 is the implementation for the get(string,xxx) family of funcs
00484        which take 3 arguments. It is *almost* identicle to CURSOR_GET_STRING_IMPL2.
00485     */
00486 #define CURSOR_GET_STRING_IMPL3(vaR,targetNamE,sizeNamE)    \
00487     if( ! this->m_stmt.get() ) return SQLITE_ERROR;            \
00488         if( 0 == this->index_colnames() ) return SQLITE_ERROR; \
00489         NameToIndexMap::const_iterator n2iit = this->m_cn->find( vaR ); \
00490         return ( this->m_cn->end() == n2iit ) ? SQLITE_ERROR : this->get( (*n2iit).second, targetNamE, sizeNamE );
00491 
00492 
00493     int cursor::get( std::string const & key, int & tgt )
00494     {
00495         CURSOR_GET_STRING_IMPL2(key,tgt);
00496     }
00497     int cursor::get( std::string const & key, int64_t & tgt )
00498     {
00499         CURSOR_GET_STRING_IMPL2(key,tgt);
00500     }
00501     int cursor::get( std::string const & key, double & tgt )
00502     {
00503         CURSOR_GET_STRING_IMPL2(key,tgt);
00504     }
00505     int cursor::get( std::string const & key, std::string & tgt )
00506     {
00507         CURSOR_GET_STRING_IMPL2(key,tgt);
00508     }
00509     int cursor::get( std::string const & key, sqlite3_text_char_t const ** tgt, int & sz )
00510     {
00511         CURSOR_GET_STRING_IMPL3(key,tgt,sz);
00512     }
00513     int cursor::get( std::string const & key, void  const ** tgt, int & sz )
00514     {
00515         CURSOR_GET_STRING_IMPL3(key,tgt,sz);
00516     }
00517 
00518 
00519     int cursor::colname( int index, std::string & tgt )
00520     {
00521         char const * cn = 0;
00522         int rc = this->colname( index, &cn );
00523         if( SQLITE_OK == rc )
00524         {
00525             tgt = cn ? cn : "";
00526         }
00527         return rc;
00528     }
00529 
00530     int cursor::colname( int index, char const ** cn )
00531     {
00532         return this->m_stmt->colname( index, cn );
00533     }
00534 
00535 
00536 #undef CURSOR_CHECK_INDEX
00537 #undef CURSOR_GET_STRING_IMPL2
00538 #undef CURSOR_GET_STRING_IMPL3
00539 
00540     sqlite3 * database::handle() const
00541     {
00542         return this->m_dbh.get();
00543     }
00544     database::database() : m_dbh(0), m_name()
00545     {
00546     }
00547 
00548 
00549     database::database( std::string const & dbname )
00550         : m_dbh(0), m_name(dbname)
00551     {
00552         this->open( dbname );
00553     }
00554 
00555     database::~database()
00556     {
00557         this->close();
00558     }
00559 
00560 
00561 
00562 
00563     bool database::is_open() const
00564     {
00565         return 0 != this->m_dbh.get();
00566     }
00567     std::string database::name() const
00568     {
00569         return this->m_name;
00570     }
00571 
00572     sqlite3 * database::take_handle()
00573     {
00574         return this->m_dbh.take();
00575     }
00576 
00577     void database::take_handle( sqlite3 * dbh, std::string const & name )
00578     {
00579         if( this->m_dbh.get() == dbh ) return;
00580         this->close();
00581         this->m_name = name;
00582         this->m_dbh.take( dbh );
00583     }
00584 
00585     std::string database::errormsg() const
00586     {
00587         char const * m = this->m_dbh.get() ? sqlite3_errmsg( this->m_dbh.get() ) : 0;
00588         return m ? m : "";
00589     }
00590 
00591     int database::open( char const * dbn, long flags )
00592     {
00593         if( ! dbn ) return SQLITE_ERROR;
00594         int rc = 0;
00595         if( this->m_dbh.get() )
00596         {
00597             rc = this->close();
00598             if( 0 != rc ) return rc;
00599         }
00600         this->m_name = dbn;
00601         sqlite3 * sq = 0;
00602 #if (SQLITE_VERSION_NUMBER >= 3005001)
00603         if( ! flags )
00604         {
00605             rc = sqlite3_open(dbn, &sq);
00606         }
00607         else
00608         {
00609             rc = sqlite3_open_v2( dbn, &sq, flags, NULL );
00610         }
00611 #else
00612         { int bogus; bogus = flags; } // avoid "unused variable: flags" warning from gcc
00613         rc = sqlite3_open(dbn, &sq);
00614 #endif // sqlite3 >= 3.5.1
00615         if( SQLITE_OK == rc )
00616         {
00617             this->m_dbh.take( sq );
00618             rc = this->on_open();
00619         }
00620         if( SQLITE_OK != rc )
00621         {
00622             this->close(); // ingore any close() failure in this case
00623         }
00624         return rc;
00625     }
00626 
00627     int database::open( std::string const & dbn, long flags )
00628     {
00629         return this->open( dbn.c_str(), flags );
00630     }
00631 
00632     int database::on_open()
00633     {
00634         return SQLITE_OK;
00635     }
00636 
00637 #if SQ3_USE_WCHAR
00638     int database::open( sqlite3_wstring_t dbn )
00639     {
00640         //std::wcerr << L"database::open(wchar_t " << dbn << L")\n";
00641         this->close();
00642         int rc = sqlite3_open16(dbn, &this->m_db);
00643         sqlite3 * sq = 0;
00644         sqlite3_open(dbn, &sq);
00645         if( SQLITE_OK == rc )
00646         {
00647             this->m_dbh.take( sq );
00648             rc = this->on_open();
00649         }
00650         if( SQLITE_OK != rc )
00651         {
00652             this->close();
00653         }
00654         return rc;
00655     }
00656 
00657     int database::open( std::wstring const & dbn )
00658     {
00659         return this->open( dbn.c_str() );
00660     }
00661 #endif // SQ3_USE_WCHAR
00662 
00663     int database::close( bool force )
00664     {
00665         if(0 == this->m_dbh.get()) return SQLITE_ERROR;
00666         if( force )
00667         { // do immediately close:
00668             return sqlite3_close( this->m_dbh.take() /* transfer ownership to sqlite3 */ );
00669         }
00670         else
00671         { // --reference_count and queue up the close:
00672             this->m_dbh.take(0); // drop existing handle.
00673             return SQLITE_OK;
00674         }
00675     }
00676 
00677     int64_t database::insertid()
00678     {
00679         return this->m_dbh.get()
00680             ? sqlite3_last_insert_rowid(this->m_dbh.get())
00681             : -1;
00682     }
00683 
00684     int database::changes()
00685     {
00686         return this->m_dbh.get()
00687             ? sqlite3_changes(this->m_dbh.get())
00688             : -1;
00689     }
00690 
00691     int database::setbusytimeout( int ms )
00692     {
00693         return this->m_dbh.get()
00694             ? sqlite3_busy_timeout(this->m_dbh.get(), ms)
00695             : SQLITE_ERROR;
00696     }
00697 
00698     int database::execute(const std::string &sql)
00699     {
00700         return statement( *this, sql ).execute();
00701     }
00702 
00703     int database::execute(char const * sql )
00704     {
00705         return statement( *this, sql, -1 ).execute();
00706     }
00707 
00708     int database::execute(char const * sql, int & tgt)
00709     {
00710         return statement( *this, sql ).execute( tgt );
00711     }
00712 
00713     int database::execute(std::string const & sql, int & tgt)
00714     {
00715         return statement( *this, sql ).execute( tgt );
00716     }
00717 
00718     int database::execute(char const * sql, int64_t & tgt)
00719     {
00720         return statement( *this, sql, -1 ).execute( tgt );
00721     }
00722 
00723     int database::execute(std::string const & sql, int64_t & tgt)
00724     {
00725         return statement( *this, sql ).execute( tgt );
00726     }
00727 
00728     int database::execute(char const * sql, double & tgt)
00729     {
00730         return statement( *this, sql, -1 ).execute( tgt );
00731     }
00732 
00733     int database::execute(std::string const & sql, double & tgt)
00734     {
00735         return statement( *this, sql ).execute( tgt );
00736     }
00737 
00738     int database::execute(char const * sql, std::string & tgt)
00739     {
00740         return statement( *this, sql ).execute( tgt );
00741     }
00742 
00743     int database::execute(std::string const & sql, std::string & tgt)
00744     {
00745         return statement( *this, sql ).execute( tgt );
00746     }
00747 
00748     int database::execute(char const * sql, sqlite3_text_char_t const ** tgt, int & len )
00749     {
00750         return statement( *this, sql ).execute( tgt, len );
00751     }
00752 
00753     int database::execute(std::string const & sql, sqlite3_text_char_t const ** tgt, int & len )
00754     {
00755         return statement( *this, sql ).execute( tgt, len );
00756     }
00757 
00758 //      int database::execute(char const * sql, std::wstring & tgt);
00759 //      int database::execute(std::string const & sql, std::wstring & tgt);
00760     int database::execute(char const * sql, void const ** tgt, int & len )
00761     {
00762         return statement( *this, sql ).execute( tgt, len );
00763     }
00764     int database::execute(std::string const & sql, void const ** tgt, int & len )
00765     {
00766         return statement( *this, sql ).execute( tgt, len );
00767     }
00768 
00769     int database::execute( std::string const & sql, sqlite3_callback callback, void * data, std::string & errmsg )
00770     {
00771         return this->execute( sql.c_str(), callback, data, errmsg );
00772     }
00773 
00774     int database::execute( char const * sql, sqlite3_callback callback, void * data, std::string & errmsg )
00775     {
00776         char * cerrmsg = 0;
00777         int ret = 0;
00778         try
00779         {
00780             // allow callback to safely throw.
00781             ret = sqlite3_exec( this->m_dbh.get(), sql, callback, data, &cerrmsg );
00782         }
00783         catch( ... )
00784         {
00785             if( cerrmsg )
00786             {
00787                 errmsg = cerrmsg;
00788                 sqlite3_free( cerrmsg );
00789             }
00790             throw;
00791         }
00792         if( cerrmsg )
00793         {
00794             errmsg = cerrmsg;
00795             sqlite3_free( cerrmsg );
00796         }
00797         return ret;
00798     }
00799 
00800     int database::execute( std::string const & sql, sqlite3_callback callback, void * data )
00801     {
00802         std::string ignored;
00803         return this->execute( sql, callback, data, ignored );
00804     }
00805 
00806     int database::execute( char const * sql, sqlite3_callback callback, void * data )
00807     {
00808         std::string s( sql ? sql : "" );
00809         std::string ignored;
00810         return this->execute( s, callback, data, ignored );
00811     }
00812 
00813 
00814     int database::pragma( char const * code )
00815     {
00816         std::ostringstream os;
00817         os << "pragma " << code;
00818         std::string sql( os.str() );
00819         return this->execute( sql.c_str() );
00820     }
00821 
00822     int database::vacuum()
00823     {
00824         return this->execute( "vacuum" );
00825     }
00826 
00827     int database::clear()
00828     {
00829         if( ! this->is_open() )
00830         {
00831             return SQLITE_ERROR;
00832         }
00833         char const * parts[] = { "view", "trigger", "table", 0 };
00834         std::string name;
00835         typedef std::vector<std::string> CmdList;
00836         CmdList list;
00837         int rc = SQLITE_OK;
00838         for( int i = 0; i < 3; ++i )
00839         {
00840             statement master(*this,"select name from sqlite_master where type=? and name not like 'sqlite_%'");
00841             rc = master.bind( 1, parts[i] );
00842             if( ! rc_is_okay(rc) ) return rc;
00843             cursor cur(master.get_cursor());
00844             while( SQLITE_ROW == cur.step() )
00845             {
00846                 name = "";
00847                 rc = cur.get(0, name);
00848                 if( ! rc_is_okay(rc) ) return rc;
00849                 list.push_back( std::string("drop ") + parts[i] + "'" + name + "'" );
00850             }
00851         }
00852         CmdList::const_iterator it = list.begin();
00853         CmdList::const_iterator et = list.end();
00854         for( ; et != it; ++it )
00855         {
00856             std::string cmd = *it;
00857             rc = this->execute( cmd );
00858         }
00859         return rc;
00860     }
00861 
00862 
00863 
00864 
00865 
00866 
00867 
00868 
00869 
00870     transaction::transaction( database & db, bool start )
00871         : m_db(db), m_intrans(false)
00872     {
00873         if( start ) this->begin();
00874     }
00875 
00876     transaction::~transaction()
00877     {
00878         this->rollback();
00879     }
00880 
00881     int transaction::begin()
00882     {
00883         if( this->m_intrans )
00884         {
00885             return SQLITE_ERROR;
00886         }
00887         int rc = this->m_db.execute("begin");
00888         this->m_intrans = (SQLITE_DONE == rc) || (SQLITE_OK == rc);
00889         return rc;
00890     }
00891 
00892     int transaction::commit()
00893     {
00894         if( ! this->m_intrans )
00895         {
00896             return SQLITE_ERROR;
00897         }
00898         int rc = this->m_db.execute("commit");
00899         if( SQLITE_BUSY != rc )
00900         {
00901             // According to the sqlite3 docs, if a COMMIT fails with BUSY
00902             // then the transaction is still open.
00903             this->m_intrans = false;
00904         }
00905         return rc;
00906     }
00907     int transaction::rollback()
00908     {
00909         if( ! this->m_intrans )
00910         {
00911             return SQLITE_ERROR;
00912         }
00913         this->m_intrans = false;
00914         return this->m_db.execute("rollback");
00915     }
00916 
00917     int cursor::index_colnames()
00918     {
00919         if( ! this->m_cn )
00920         {
00921             this->m_cn = new NameToIndexMap;
00922         }
00923         else
00924         if( ! this->m_cn->empty() )
00925         {
00926             // We're using a cached result
00927             return -1;
00928         }
00929         char const * cname;
00930         int cc = this->colcount();
00931         int pos = 0;
00932         for( int i = 0; i < cc; ++i, ++pos )
00933         {
00934             cname = 0;
00935             if( SQLITE_OK != this->colname( i, &cname ) )
00936                 //if( ! (cname = this->m_stmt->colname( i ) ) )
00937             {
00938                 break;
00939             }
00940             (*this->m_cn)[std::string(cname ? cname : "")] = i;
00941         }
00942         return pos;
00943     }
00944 
00945 
00946 } // namespace