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
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;
00128
00129 this->m_stmt.take(0);
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
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
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
00474
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
00484
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; }
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();
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
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 {
00668 return sqlite3_close( this->m_dbh.take() );
00669 }
00670 else
00671 {
00672 this->m_dbh.take(0);
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
00759
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
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
00902
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
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
00937 {
00938 break;
00939 }
00940 (*this->m_cn)[std::string(cname ? cname : "")] = i;
00941 }
00942 return pos;
00943 }
00944
00945
00946 }