libsq3
2007.10.18
|
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