Sqlite has a feature where you can contanenate SQL statements and
prepare and step them in a loop. Prepare returns a pointer to the start
of the next statement.
The basic prepare/step/reset activity requires that there be a loop to
handle multiple rows, busy returns and possible errors.
Stephen Sutherland wrote:
okay i'm trying to use preparestatement and step and finalize.
I have some quick questions about this legacy.c code.
First I notice that it has a while loop within a while loop.
Question: when I implement this prepared statement, will I also need a while loop within a while loop ?
Just double checking
I noticed rc = sqlite3_step(pStmt); is the start of the inner while loop.
I'm guessing the inner while loop is needed with pStmt contains multiple SQl statements right ?
Thanks
STev
Dennis Cote <[EMAIL PROTECTED]> wrote:
Stephen Sutherland wrote:
Hi
I am using the 'quick start' C-styled code for sqlite3
http://www.sqlite.org/quickstart.html
I think I'm running into a problem trying to put it in classes to make it somewhat object oriented. So I'm asking for help about how to make it object-oriented - or to confirm whether what I'm doing is object oriented.
Here is the code:
[code]
//callback function
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
int i;
for(i=0; i> printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
};
// this callback is referenced here.
void MyClass::executeSQLStatement()
{
rc = sqlite3_exec(db, "select * from table1" , callback, 0, &zErrMsg);
};
[/code]
However I am trying to add a vector in the callback function to store the
results. When I put the vector in it seems I am forced to do something like
this:
[code]
vector vecX;
static int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
int i;
for(i=0; i> printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
vecX.push_back(argv[3]);
printf("\n");
return 0;
};
[/code]
Now this doesn't seem object oriented ?
Nor do I understand how I would access this vector from other classes ?
And I don't know how this vector which I created can be considered part of the class ? it seems to me to only have page scope.
Any advice on how to make my vector object oriented or accessible by other classes ?
Thanks in Advance
Stephen
---------------------------------
Pinpoint customers who are looking for what you sell.
Stephen,
You should look into using the newer prepare/step API functions instead
of the callback mechanism. It will make your code clearer, and will
probably execute faster as well.
The new API is used to implement the current version of sqlite3_exec
that uses the callback mechanism so you can look at that code to see
how the new API is used. The following excerpt is from the file legacy.c
in the sqlite source. It shows how sqlite uses the new API functions to
build the arrays of strings it passes to the callback function.
By using the new API functions directly you can avoid the overhead of
converting all the database fields into string and building these
arrays, only to have your callback function iterate over the string
arrays and convert the values back into other types (for non string
fields anyway) and then stuff them into vectors. You can extract the
fields and store them directly into the vectors you want.
/*
** Execute SQL code. Return one of the SQLITE_ success/failure
** codes. Also write an error message into memory obtained from
** malloc() and make *pzErrMsg point to that message.
**
** If the SQL is a query, then for each row in the query result
** the xCallback() function is called. pArg becomes the first
** argument to xCallback(). If xCallback=NULL then no callback
** is invoked, even for queries.
*/
int sqlite3_exec(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
sqlite3_callback xCallback, /* Invoke this callback routine */
void *pArg, /* First argument to xCallback() */
char **pzErrMsg /* Write error messages here */
){
int rc = SQLITE_OK;
const char *zLeftover;
sqlite3_stmt *pStmt = 0;
char **azCols = 0;
int nRetry = 0;
int nCallback;
if( zSql==0 ) return SQLITE_OK;
while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) &&
zSql[0] ){
int nCol;
char **azVals = 0;
pStmt = 0;
rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
assert( rc==SQLITE_OK || pStmt==0 );
if( rc!=SQLITE_OK ){
continue;
}
if( !pStmt ){
/* this happens for a comment or white-space */
zSql = zLeftover;
continue;
}
nCallback = 0;
nCol = sqlite3_column_count(pStmt);
azCols = sqliteMalloc(2*nCol*sizeof(const char *) + 1);
if( azCols==0 ){
goto exec_out;
}
while( 1 ){
int i;
rc = sqlite3_step(pStmt);
/* Invoke the callback function if required */
if( xCallback && (SQLITE_ROW==rc ||
(SQLITE_DONE==rc && !nCallback &&
db->flags&SQLITE_NullCallback)) ){
if( 0==nCallback ){
for(i=0; i azCols[i] = (char *)sqlite3_column_name(pStmt, i);
}
nCallback++;
}
if( rc==SQLITE_ROW ){
azVals = &azCols[nCol];
for(i=0; i azVals[i] = (char *)sqlite3_column_text(pStmt, i);
}
}
if( xCallback(pArg, nCol, azVals, azCols) ){
rc = SQLITE_ABORT;
goto exec_out;
}
}
if( rc!=SQLITE_ROW ){
rc = sqlite3_finalize(pStmt);
pStmt = 0;
if( rc!=SQLITE_SCHEMA ){
nRetry = 0;
zSql = zLeftover;
while( isspace((unsigned char)zSql[0]) ) zSql++;
}
break;
}
}
sqliteFree(azCols);
azCols = 0;
}
HTH
Dennis Cote
-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------
---------------------------------
Pinpoint customers who are looking for what you sell.
-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------