4 # define COUT std::cerr << "SQ3:"<<__FILE__ << ":" << std::dec<<__LINE__ << ": "
41 sqlite3_finalize( st );
58 return ((SQLITE_DONE==rc) || (SQLITE_OK==rc) || (SQLITE_ROW==rc));
64 return this->
prepare( sql.c_str(),
static_cast<int>(sql.size()) );
70 const char *tail=NULL;
71 if( 0 > len ) len =
static_cast<int>(strlen(sql));
72 sqlite3_stmt * st = 0;
75 #if (SQLITE_VERSION_NUMBER >= 3003009)
80 (this->m_db.
handle(), sql, len, &st, &tail);
84 this->m_argc = sqlite3_column_count(st);
85 this->m_stmt.take( st );
97 void const * tail = NULL;
98 if( 0 > byteCount ) byteCount = ????;
99 sqlite3_stmt * st = 0;
101 #if SQLITE_VERSION_NUMBER >= 3003009
106 (this->m_db.
handle(), sql, byteCount, &st, &tail);
107 if( SQLITE_OK == rc )
109 this->m_argc = sqlite3_column_count(st);
110 this->m_stmt.take(st);
119 #endif // SQ3_USE_WCHAR
124 int rc = SQLITE_ERROR;
125 if( this->m_stmt.get() )
129 this->m_stmt.take(0);
136 : m_db(db), m_stmt(0), m_argc(0)
141 : m_db(db), m_stmt(0), m_argc(0)
146 : m_db(db), m_stmt(0), m_argc(0)
148 this->
prepare( sql, byteCount );
153 : m_db(db), m_stmt(0), m_argc(0)
158 : m_db(db), m_stmt(0), m_argc(0)
160 this->
prepare( sql, byteCount );
162 #endif // SQ3_USE_WCHAR
167 return 0 != this->m_stmt.get();
175 return sqlite3_bind_null( this->m_stmt.get(), index);
179 return sqlite3_bind_int( this->m_stmt.get(), index, data );
183 return sqlite3_bind_int64( this->m_stmt.get(), index, data );
187 return sqlite3_bind_double( this->m_stmt.get(), index, data );
191 if( 0 > len ) len =
static_cast<int>(strlen(data));
192 return sqlite3_bind_text( this->m_stmt.get(), index, data, len, SQLITE_TRANSIENT );
196 return sqlite3_bind_blob( this->m_stmt.get(), index, data, len, SQLITE_TRANSIENT );
201 return this->
bind( index, data.c_str(),
static_cast<int>(data.size() ) );
207 return sqlite3_bind_null( this->m_stmt.get(),
208 sqlite3_bind_parameter_index( this->m_stmt.get(), index ) );
212 return sqlite3_bind_int( this->m_stmt.get(),
213 sqlite3_bind_parameter_index( this->m_stmt.get(), index ), data );
217 return sqlite3_bind_int64( this->m_stmt.get(),
218 sqlite3_bind_parameter_index( this->m_stmt.get(), index ), data );
222 return sqlite3_bind_double( this->m_stmt.get(),
223 sqlite3_bind_parameter_index( this->m_stmt.get(), index ), data );
227 if( 0 > len ) len =
static_cast<int>(strlen(data) );
228 return sqlite3_bind_text( this->m_stmt.get(),
229 sqlite3_bind_parameter_index( this->m_stmt.get(), index ) , data, len, SQLITE_TRANSIENT );
233 return sqlite3_bind_blob( this->m_stmt.get(),
234 sqlite3_bind_parameter_index( this->m_stmt.get(), index ) , data, len, SQLITE_TRANSIENT );
239 return this->
bind( index, data.c_str(),
static_cast<int>(data.size() ) );
255 #define STATEMENT_EXECUTE_1ARG_IMPL \
256 cursor rd( this->get_cursor() ); \
257 int rc = rd.step(); \
258 if( SQLITE_ROW == rc ) \
260 rc = rd.get(0,tgt); \
266 STATEMENT_EXECUTE_1ARG_IMPL;
270 STATEMENT_EXECUTE_1ARG_IMPL;
274 STATEMENT_EXECUTE_1ARG_IMPL;
278 STATEMENT_EXECUTE_1ARG_IMPL;
280 #undef STATEMENT_EXECUTE_1ARG_IMPL
286 if( SQLITE_ROW == rc )
288 rc = rd.
get(0,tgt,len);
296 if( SQLITE_ROW == rc )
298 rc = rd.
get(0,tgt,len);
306 return this->m_stmt.get()
307 ? sqlite3_reset( this->m_stmt.get() )
313 return this->m_stmt.get()
321 if( -1 == count )
return 0;
322 if( (index < 0) || (index >= count) )
return 0;
323 return sqlite3_column_name(this->m_stmt.get(), index);
328 char const * c = this->
colname( index );
330 return c ? SQLITE_OK : SQLITE_ERROR;
344 this->m_stmt.take(&st);
349 if( &cp ==
this )
return *
this;
354 void cursor::copy(
cursor const & rhs )
356 if( &rhs ==
this )
return;
358 this->m_stmt = rhs.m_stmt;
361 this->m_cn =
new NameToIndexMap(*rhs.m_cn);
372 return this->m_stmt.get()
373 ? sqlite3_step(this->m_stmt->m_stmt.get())
381 return this->m_stmt.get()
382 ? this->m_stmt->reset()
387 this->m_stmt.take(0);
397 return this->m_stmt.get()
398 ? this->m_stmt->colcount()
402 #define CURSOR_CHECK_INDEX \
403 if( ! this->m_stmt.get() ) return SQLITE_ERROR; \
404 if( (index)>(this->m_stmt->m_argc-1)) return SQLITE_ERROR;
409 tgt = sqlite3_column_type( this->m_stmt->m_stmt.get(), index) == SQLITE_NULL;
416 tgt = sqlite3_column_int( this->m_stmt->m_stmt.get(), index );
422 tgt = sqlite3_column_int64( this->m_stmt->m_stmt.get(), index );
428 tgt = sqlite3_column_double( this->m_stmt->m_stmt.get(), index );
434 char const * x = (
const char*)sqlite3_column_text(this->m_stmt->m_stmt.get(), index);
435 int sz = sqlite3_column_bytes(this->m_stmt->m_stmt.get(), index);
438 tgt = std::string( x, x+sz );
449 sz = sqlite3_column_bytes(this->m_stmt->m_stmt.get(), index);
452 *tgt = sqlite3_column_text( this->m_stmt->m_stmt.get(), index);
463 sz = sqlite3_column_bytes(this->m_stmt->m_stmt.get(), index);
466 *tgt = sqlite3_column_blob(this->m_stmt->m_stmt.get(), index);
476 #define CURSOR_GET_STRING_IMPL2(vaR,targetNamE) \
477 if( ! this->m_stmt.get() ) return SQLITE_ERROR; \
478 if( 0 == this->index_colnames() ) return SQLITE_ERROR; \
479 NameToIndexMap::const_iterator n2iit = this->m_cn->find( vaR ); \
480 return ( this->m_cn->end() == n2iit ) ? SQLITE_ERROR : this->get( (*n2iit).second, targetNamE );
486 #define CURSOR_GET_STRING_IMPL3(vaR,targetNamE,sizeNamE) \
487 if( ! this->m_stmt.get() ) return SQLITE_ERROR; \
488 if( 0 == this->index_colnames() ) return SQLITE_ERROR; \
489 NameToIndexMap::const_iterator n2iit = this->m_cn->find( vaR ); \
490 return ( this->m_cn->end() == n2iit ) ? SQLITE_ERROR : this->get( (*n2iit).second, targetNamE, sizeNamE );
495 CURSOR_GET_STRING_IMPL2(key,tgt);
499 CURSOR_GET_STRING_IMPL2(key,tgt);
503 CURSOR_GET_STRING_IMPL2(key,tgt);
507 CURSOR_GET_STRING_IMPL2(key,tgt);
511 CURSOR_GET_STRING_IMPL3(key,tgt,sz);
513 int cursor::get( std::string
const & key,
void const ** tgt,
int & sz )
515 CURSOR_GET_STRING_IMPL3(key,tgt,sz);
522 int rc = this->
colname( index, &cn );
523 if( SQLITE_OK == rc )
532 return this->m_stmt->colname( index, cn );
536 #undef CURSOR_CHECK_INDEX
537 #undef CURSOR_GET_STRING_IMPL2
538 #undef CURSOR_GET_STRING_IMPL3
542 return this->m_dbh.get();
550 : m_dbh(0), m_name(dbname)
552 this->
open( dbname );
565 return 0 != this->m_dbh.get();
574 return this->m_dbh.take();
579 if( this->m_dbh.get() == dbh )
return;
582 this->m_dbh.take( dbh );
587 char const * m = this->m_dbh.get() ? sqlite3_errmsg( this->m_dbh.get() ) : 0;
593 if( ! dbn )
return SQLITE_ERROR;
595 if( this->m_dbh.get() )
598 if( 0 != rc )
return rc;
602 #if (SQLITE_VERSION_NUMBER >= 3005001)
605 rc = sqlite3_open(dbn, &sq);
609 rc = sqlite3_open_v2( dbn, &sq, flags, NULL );
612 {
int bogus; bogus = flags; }
613 rc = sqlite3_open(dbn, &sq);
614 #endif // sqlite3 >= 3.5.1
615 if( SQLITE_OK == rc )
617 this->m_dbh.take( sq );
620 if( SQLITE_OK != rc )
629 return this->
open( dbn.c_str(), flags );
642 int rc = sqlite3_open16(dbn, &this->m_db);
644 sqlite3_open(dbn, &sq);
645 if( SQLITE_OK == rc )
647 this->m_dbh.take( sq );
650 if( SQLITE_OK != rc )
659 return this->
open( dbn.c_str() );
661 #endif // SQ3_USE_WCHAR
665 if(0 == this->m_dbh.get())
return SQLITE_ERROR;
668 return sqlite3_close( this->m_dbh.take() );
679 return this->m_dbh.get()
680 ? sqlite3_last_insert_rowid(this->m_dbh.get())
686 return this->m_dbh.get()
687 ? sqlite3_changes(this->m_dbh.get())
693 return this->m_dbh.get()
694 ? sqlite3_busy_timeout(this->m_dbh.get(), ms)
769 int database::execute( std::string
const & sql, sqlite3_callback callback,
void * data, std::string & errmsg )
771 return this->
execute( sql.c_str(), callback, data, errmsg );
774 int database::execute(
char const * sql, sqlite3_callback callback,
void * data, std::string & errmsg )
781 ret = sqlite3_exec( this->m_dbh.get(), sql, callback, data, &cerrmsg );
788 sqlite3_free( cerrmsg );
795 sqlite3_free( cerrmsg );
803 return this->
execute( sql, callback, data, ignored );
808 std::string s( sql ? sql :
"" );
810 return this->
execute( s, callback, data, ignored );
816 std::ostringstream os;
817 os <<
"pragma " << code;
818 std::string sql( os.str() );
819 return this->
execute( sql.c_str() );
824 return this->
execute(
"vacuum" );
833 char const * parts[] = {
"view",
"trigger",
"table", 0 };
835 typedef std::vector<std::string> CmdList;
838 for(
int i = 0; i < 3; ++i )
840 statement master(*
this,
"select name from sqlite_master where type=? and name not like 'sqlite_%'");
841 rc = master.
bind( 1, parts[i] );
844 while( SQLITE_ROW == cur.step() )
847 rc = cur.
get(0, name);
849 list.push_back( std::string(
"drop ") + parts[i] +
"'" + name +
"'" );
852 CmdList::const_iterator it = list.begin();
853 CmdList::const_iterator et = list.end();
854 for( ; et != it; ++it )
856 std::string cmd = *it;
870 transaction::transaction(
database & db,
bool start )
871 : m_db(db), m_intrans(false)
873 if( start ) this->
begin();
883 if( this->m_intrans )
887 int rc = this->m_db.
execute(
"begin");
888 this->m_intrans = (SQLITE_DONE == rc) || (SQLITE_OK == rc);
894 if( ! this->m_intrans )
898 int rc = this->m_db.
execute(
"commit");
899 if( SQLITE_BUSY != rc )
903 this->m_intrans =
false;
909 if( ! this->m_intrans )
913 this->m_intrans =
false;
914 return this->m_db.
execute(
"rollback");
917 int cursor::index_colnames()
921 this->m_cn =
new NameToIndexMap;
924 if( ! this->m_cn->empty() )
932 for(
int i = 0; i < cc; ++i, ++pos )
935 if( SQLITE_OK != this->
colname( i, &cname ) )
940 (*this->m_cn)[std::string(cname ? cname :
"")] = i;