Re: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-13 Thread Stephen Sutherland
Thanks Igor I used your solution and it work. Char* was the problem. I'll use 
strings from now on . 
   
  Stephen 

Igor Mironchick <[EMAIL PROTECTED]> wrote:
  I think problem is in use char * as parameter in push function. For that 
reason I use std::string always.
Look, in callback2 SQLite pass char ** - array of char*. But when your 
code leave callback2 SQLite might errase that array and then all char* 
will garbage. But when in push method you will pass const std::string & 
-- char* will transform into std::string and you will not lose any data. 
Or event you can obviosly call ctor of std::string like

q->push( atoi(argv[0] ),atoi(argv[1] ),atoi(argv[2] ), std::string( 
argv[3] ), std::string( argv[4] ) );

and push method then will looks like this:

void QuestionDB::push( int b, int c, int v, const std::string & q, const 
std::string & a )
{
...
}

P.S. Try don't use char* in C++ code. Use std::string instead. And when 
you need char* you can transform std::string into char* with c_str() 
method of std::string.


Stephen Sutherland wrote:
> Igor I tried your solution and can't get it working . 
> Here is my code. 
> 
> The STRANGE problem that I am having is that when it adds to the vector at 
> position 1, the vector contains the object. 
> 
> But when it adds to vector at position 2 using push_back - for some reason 
> the contents at vector 1 is garbage. 
> 
> then when it adds to vector at position 3 using push_back - for some reason 
> position 3 is garabage ? 
> 
> the errors in this situation doesn't seem to follow much logic ? but it's 
> consistent.
> 
> for example if i run this code and it uses push 4 times, position 1 and 3 
> might have garbase while position 2 will have the same contents as position 4 
> ? ?
> 
> this is some weird stuff i haven't seen before. 
> I'm wondering if the problem is due to the scope of either my 
> QuestionDBStruct or my vector . 
> 
> =
> 
> static int callback2(void *NotUsed, int argc, char **argv, char **azColName)
> {
> int i;
> for(i=0; i> {
> printf("%i. %s = %s\n", i, azColName[i], argv[i] ? argv[i] : "NULL"); 
> } 
> QuestionDB* q = (QuestionDB*)NotUsed; 
> q->push(c );
> 
> return 0;
> }; 
> QuestionDB::QuestionDB()
> {
> 
> };
> void QuestionDB::push(int b, int c, int v, char* q, char* a)
> { 
> 
> 
> QuestionDBStruct qbs; 
> qbs.bible_book =1;
> qbs.bible_chapter =2; 
> qbs.bible_verse =3; 
> qbs.bible_answer ="test";
> qbs.bible_question =q;
> 
> printf("\n** push called \n"); 
> 
> vecQuestions.push_back(qbs); 
> for(int x = 0 ; x < vecQuestions.size(); x++)
> printf("\nvecQuestion[%i] = %s \n", x, 
> ((QuestionDBStruct)vecQuestions[x]).bible_question );
> 
> 
> printf("\n***\n");
> 
> }; 
> 
> 
> 
> 
> 
> 
> 
>
> Igor Mironchick wrote:
> If I understand you right then try it:
>
> static int add_value( void *st, int, char **value, char ** )
> {
> storage_t * storage = (storage_t*) st;
> st->push( value[ 0 ] );
> return SQLITE_OK;
> };
>
> class storage_t {
> public:
> storage_t()
> : m_db( 0 )
> {
> sqlite3_open( "your_database.db", _db );
> };
> virtual ~storage_t()
> {
> sqlite3_close( m_db );
> };
>
> void push( const std::string & v )
> {
> m_buff.push_back( v );
> }
>
> void read_table()
> {
> sqlite3_exec( m_db, "SELECT * FROM some_table",
> add_value, this, NULL );
> }
>
> private:
> sqlite3 * m_db;
> std::vector< std::string > m_buff;
> };
>
> This is very simple example, but it can help you I think.
>
> 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, );
>> };
>>
>> [/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 

Re: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-10 Thread John Stanton
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, );
};

[/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, , );
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_NullCallback)) ){

if( 0==nCallback ){
for(i=0; i azCols[i] = (char 

Re: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-10 Thread Dennis Cote

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 ? 
   
 

Stephen,

The two loops are used, as you surmised, to execute multiple SQL 
statements. The outer loop is repeated for each SQL statement in the 
input to sqlite3_exec. The inner loop is used to step through each row 
of the result of the execution of a particular statement.


In the normal case, with only a single SQL statement passed in, the 
outer loop is executed only once. The inner loop will be executed once 
for each result row. 


HTH
Dennis Cote

-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-10 Thread Igor Mironchick

Hi, guys.

Dennis Cote wrote:

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.


I don't think so. Prepare/step mechanism can invoke productivity of 
"INSERT" or "UPDATE", or something like this, when you have much rows to 
insert/update. But when you need to do "SELECT" sqlite3_exec - the best 
way in my opinion. Look at the code that you represent - this is the 
answer on all questions. Want you or don't, but you must allocate memory 
for result and call function in C/C++ is very cheaply operation. You 
sad: "It will make your code clearer". I don't agree. Look...


char * sql = sqlite3_mprintf( "SELECT * FROM %s", table_name );
int ret = sqlite3_exec( db, sql, callback, NULL, NULL );
sqlite3_free( sql );

What can be clearer than it???

But when you store many information in DB than transactions/prepare/step 
are more preferable for productivity. But it does not make code clearer, 
inside out...




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.


And here I see this magic word "callback" :)

--
Regards,
Igor Mironchick,
Intervale ©
#ICQ 492-597-570


-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-09 Thread Igor Mironchick
I think problem is in use char * as parameter in push function. For that 
reason I use std::string always.
Look, in callback2 SQLite pass char ** - array of char*. But when your 
code leave callback2 SQLite might errase that array and then all char* 
will garbage. But when in push method you will pass const std::string & 
-- char* will transform into std::string and you will not lose any data. 
Or event you can obviosly call ctor of std::string like


q->push( atoi(argv[0] ),atoi(argv[1] ),atoi(argv[2] ), std::string( 
argv[3] ), std::string( argv[4] ) );


and push method then will looks like this:

void QuestionDB::push( int b, int c, int v, const std::string & q, const 
std::string & a )

{
   ...
}

P.S. Try don't use char* in C++ code. Use std::string instead. And when 
you need char* you can transform std::string into char* with c_str() 
method of std::string.



Stephen Sutherland wrote:
Igor I tried your solution and can't get it working . 
  Here is my code. 
   
  The STRANGE problem that I am having is that when it adds to the vector at position 1, the vector contains the object. 
   
  But when it adds to vector at position 2 using push_back - for some reason the contents at vector 1 is garbage. 
   
  then when it adds to vector at position 3 using push_back - for some reason position 3 is garabage ? 
   
  the errors in this situation doesn't seem to follow much logic ? but it's consistent.
   
  for example if i run this code and it uses push 4 times, position 1 and 3 might have garbase while position 2 will have the same contents as position 4 ? ?
   
  this is some weird stuff i haven't seen before. 
  I'm wondering if the problem is due to the scope of either my QuestionDBStruct or my vector . 
   
  =
 
  static int callback2(void *NotUsed, int argc, char **argv, char **azColName)

  {
   int i;
   for(i=0; ipush(c );
   
   return 0;
  };  
  QuestionDB::QuestionDB()

  {

  };

  void QuestionDB::push(int b, int c, int v, char* q, char* a)
  { 

  
QuestionDBStruct qbs; 
qbs.bible_book =1;
qbs.bible_chapter  =2; 
qbs.bible_verse=3;   
qbs.bible_answer   ="test";

qbs.bible_question =q;

printf("\n** push called \n"); 
 
vecQuestions.push_back(qbs); 
for(int x = 0 ; x < vecQuestions.size(); x++)

  printf("\nvecQuestion[%i] = %s \n", x, 
((QuestionDBStruct)vecQuestions[x]).bible_question );
 
 
printf("\n***\n");
   
  };  
   
   
   
   
   
   
  


Igor Mironchick <[EMAIL PROTECTED]> wrote:
  If I understand you right then try it:

static int add_value( void *st, int, char **value, char ** )
{
storage_t * storage = (storage_t*) st;
st->push( value[ 0 ] );
return SQLITE_OK;
};

class storage_t {
public:
storage_t()
: m_db( 0 )
{
sqlite3_open( "your_database.db", _db );
};
virtual ~storage_t()
{
sqlite3_close( m_db );
};

void push( const std::string & v )
{
m_buff.push_back( v );
}

void read_table()
{
sqlite3_exec( m_db, "SELECT * FROM some_table",
add_value, this, NULL );
}

private:
sqlite3 * m_db;
std::vector< std::string > m_buff;
};

This is very simple example, but it can help you I think.

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, );
};

[/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 

Re: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-09 Thread Stephen Sutherland
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, );
> };
> 
> [/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, , );
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_NullCallback)) ){
if( 0==nCallback ){
for(i=0; i azCols[i] = (char *)sqlite3_column_name(pStmt, i);
}
nCallback++;
}
if( rc==SQLITE_ROW ){
azVals = [nCol];
for(i=0; i azVals[i] = (char *)sqlite3_column_text(pStmt, i);
}
}
if( xCallback(pArg, nCol, azVals, azCols) ){
rc = 

Re: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-09 Thread Stephen Sutherland
Igor I tried your solution and can't get it working . 
  Here is my code. 
   
  The STRANGE problem that I am having is that when it adds to the vector at 
position 1, the vector contains the object. 
   
  But when it adds to vector at position 2 using push_back - for some reason 
the contents at vector 1 is garbage. 
   
  then when it adds to vector at position 3 using push_back - for some reason 
position 3 is garabage ? 
   
  the errors in this situation doesn't seem to follow much logic ? but it's 
consistent.
   
  for example if i run this code and it uses push 4 times, position 1 and 3 
might have garbase while position 2 will have the same contents as position 4 ? 
?
   
  this is some weird stuff i haven't seen before. 
  I'm wondering if the problem is due to the scope of either my 
QuestionDBStruct or my vector . 
   
  =
 
  static int callback2(void *NotUsed, int argc, char **argv, char **azColName)
  {
   int i;
   for(i=0; ipush(atoi(argv[0] ),atoi(argv[1] ),atoi(argv[2] ), argv[3] , argv[4] 
);
   
   return 0;
  };  
  QuestionDB::QuestionDB()
  {

  };
  void QuestionDB::push(int b, int c, int v, char* q, char* a)
  { 

  
QuestionDBStruct qbs; 
qbs.bible_book =1;
qbs.bible_chapter  =2; 
qbs.bible_verse=3;   
qbs.bible_answer   ="test";
qbs.bible_question =q;

printf("\n** push called \n"); 
 
vecQuestions.push_back(qbs); 
for(int x = 0 ; x < vecQuestions.size(); x++)
  printf("\nvecQuestion[%i] = %s \n", x, 
((QuestionDBStruct)vecQuestions[x]).bible_question );
 
 
printf("\n***\n");
   
  };  
   
   
   
   
   
   
  

Igor Mironchick <[EMAIL PROTECTED]> wrote:
  If I understand you right then try it:

static int add_value( void *st, int, char **value, char ** )
{
storage_t * storage = (storage_t*) st;
st->push( value[ 0 ] );
return SQLITE_OK;
};

class storage_t {
public:
storage_t()
: m_db( 0 )
{
sqlite3_open( "your_database.db", _db );
};
virtual ~storage_t()
{
sqlite3_close( m_db );
};

void push( const std::string & v )
{
m_buff.push_back( v );
}

void read_table()
{
sqlite3_exec( m_db, "SELECT * FROM some_table",
add_value, this, NULL );
}

private:
sqlite3 * m_db;
std::vector< std::string > m_buff;
};

This is very simple example, but it can help you I think.

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, );
> };
> 
> [/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. 
> 

-- 
Regards,
Igor Mironchick,
Intervale ©
#ICQ 492-597-570


-
To unsubscribe, send email to [EMAIL PROTECTED]
-



   
-
Be a better Globetrotter. Get better travel answers from someone who knows.
Yahoo! Answers - Check it out.

Re: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-09 Thread Stephen Sutherland
Thanks I guess i have to figure out how to use prepared statements instead of 
callbacks because i can't get callbacks working as expected. 
   
  

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, );
> };
> 
> [/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, , );
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_NullCallback)) ){
if( 0==nCallback ){
for(i=0; i azCols[i] = (char *)sqlite3_column_name(pStmt, i);
}
nCallback++;
}
if( rc==SQLITE_ROW ){
azVals = [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 

Re: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-09 Thread Dennis Cote

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; iflags_NullCallback)) ){

   if( 0==nCallback ){
 for(i=0; i

RE: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-09 Thread Lee Crain
The formatting on part of my response didn't turn out as I expected. I'll
try that part again:


Think of a vRecordset vector like this, as a vector of vRecord vectors:

vRecord0< Field0, Field1, Field2, FieldN >

vRecord1< Field0, Field1, Field2, FieldN > 

vRecord2< Field0, Field1, Field2, FieldN > 

vRecord3< Field0, Field1, Field2, FieldN > 

vRecord4< Field0, Field1, Field2, FieldN > 

vRecord5< Field0, Field1, Field2, FieldN > 

vRecord6< Field0, Field1, Field2, FieldN > 

vRecord7< Field0, Field1, Field2, FieldN >




Lee Crain

__

-Original Message-
From: Lee Crain [mailto:[EMAIL PROTECTED] 
Sent: Thursday, August 09, 2007 1:45 PM
To: sqlite-users@sqlite.org
Subject: RE: [sqlite] Object Oriented Question About Adding a vector
inside the callback function

Stephen,

I was faced with a similar problem while writing a SQLite API wrapper for
our application programmers. 

My solution was this:

> I created a Field class that is a container than can hold ONE of several
different data types. 
> I created a Record class that consists of a vector of Fields and
supporting vector access services. (vector vRecord)
> I created a vector of Records as my Recordset. (vector
vRecordset) 

Think of a vRecordset vector like this, as a vector of vRecord vectors:
vRecord0< Field0, Field1, Field2, FieldN >
vRecord1< Field0, Field1, Field2, FieldN > 
vRecord2< Field0, Field1, Field2, FieldN > 
vRecord3< Field0, Field1, Field2, FieldN > 
vRecord4< Field0, Field1, Field2, FieldN > 
vRecord5< Field0, Field1, Field2, FieldN > 
vRecord6< Field0, Field1, Field2, FieldN > 
vRecord7< Field0, Field1, Field2, FieldN >

The x axis consists of the Field containers loaded into the vRecord
vector.

The y axis consists of the vRecord vectors loaded into the vRecordset
vector.

The Recordset vector is instantiated on the stack in application code and
before the SQLite API wrapper call. Then its ADDRESS is passed as an
argument to my SQLite API wrapper class method calls. Those calls store
the pointer to the vRecordset vector in a static vRecordset vector
pointer, then execute the "sqlite3_exec()" function call which triggers
the static callback function (at global scope) to read back the data from
the SQL queries. 

The callback function populates a Field class object for each field in the
received data. After all fields have been received (1 row per callback),
each of the Field class objects is loaded into a vRecord vector which is
loaded into the vRecordset vector ("pushback()" calls).

I don't see a way to make the callback function non-static. So, I didn't
try. 

OO programming is type specific. That presented a problem in the static
callback function because the data coming back is not type specific. So, I
solved that problem by creating a Field container that could hold any
datatype. For each query executed, I programmed my solution to know
exactly the order of (left to right) and the expected datatypes for each
field that is returned, so that the callback function can translate the
returned data to its correct datatype before loading that data into a
Field container. That way, when the application code receives a vRecordset
back from a read operation, it doesn't have to deal with the datatypes;
they're already correctly set inside each Field container.


With the exception of the static parts of my implementation, everything is
strictly OO. The breakthrough for me was to create a Field container that
could hold any datatype. Now, I have an interface that is not bound to any
particular tables or fields, which can receive and hold the data results
from any query. Even if our underlying database changes, my SQLite API
wrapper source code will not. 

I hope this helps,

Lee Crain





-Original Message-
From: Stephen Sutherland [mailto:[EMAIL PROTECTED] 
Sent: Thursday, August 09, 2007 1:06 PM
To: sqlite-users@sqlite.org
Subject: [sqlite] Object Oriented Question About Adding a vector inside
the callback function

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<argc; 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, );
};
   
  [/code]
   
   
  However I am trying to add 

RE: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-09 Thread Lee Crain
Stephen,

I was faced with a similar problem while writing a SQLite API wrapper for
our application programmers. 

My solution was this:

> I created a Field class that is a container than can hold ONE of several
different data types. 
> I created a Record class that consists of a vector of Fields and
supporting vector access services. (vector vRecord)
> I created a vector of Records as my Recordset. (vector
vRecordset) 

Think of a vRecordset vector like this, as a vector of vRecord vectors:
vRecord0< Field0, Field1, Field2, FieldN >
vRecord1< Field0, Field1, Field2, FieldN > 
vRecord2< Field0, Field1, Field2, FieldN > 
vRecord3< Field0, Field1, Field2, FieldN > 
vRecord4< Field0, Field1, Field2, FieldN > 
vRecord5< Field0, Field1, Field2, FieldN > 
vRecord6< Field0, Field1, Field2, FieldN > 
vRecord7< Field0, Field1, Field2, FieldN >

The x axis consists of the Field containers loaded into the vRecord
vector.

The y axis consists of the vRecord vectors loaded into the vRecordset
vector.

The Recordset vector is instantiated on the stack in application code and
before the SQLite API wrapper call. Then its ADDRESS is passed as an
argument to my SQLite API wrapper class method calls. Those calls store
the pointer to the vRecordset vector in a static vRecordset vector
pointer, then execute the "sqlite3_exec()" function call which triggers
the static callback function (at global scope) to read back the data from
the SQL queries. 

The callback function populates a Field class object for each field in the
received data. After all fields have been received (1 row per callback),
each of the Field class objects is loaded into a vRecord vector which is
loaded into the vRecordset vector ("pushback()" calls).

I don't see a way to make the callback function non-static. So, I didn't
try. 

OO programming is type specific. That presented a problem in the static
callback function because the data coming back is not type specific. So, I
solved that problem by creating a Field container that could hold any
datatype. For each query executed, I programmed my solution to know
exactly the order of (left to right) and the expected datatypes for each
field that is returned, so that the callback function can translate the
returned data to its correct datatype before loading that data into a
Field container. That way, when the application code receives a vRecordset
back from a read operation, it doesn't have to deal with the datatypes;
they're already correctly set inside each Field container.


With the exception of the static parts of my implementation, everything is
strictly OO. The breakthrough for me was to create a Field container that
could hold any datatype. Now, I have an interface that is not bound to any
particular tables or fields, which can receive and hold the data results
from any query. Even if our underlying database changes, my SQLite API
wrapper source code will not. 

I hope this helps,

Lee Crain





-Original Message-
From: Stephen Sutherland [mailto:[EMAIL PROTECTED] 
Sent: Thursday, August 09, 2007 1:06 PM
To: sqlite-users@sqlite.org
Subject: [sqlite] Object Oriented Question About Adding a vector inside
the callback function

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<argc; 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, );
};
   
  [/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<argc; 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

Re: [sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-09 Thread Igor Mironchick

If I understand you right then try it:

static int add_value( void *st, int, char **value, char ** )
{
   storage_t * storage = (storage_t*) st;
   st->push( value[ 0 ] );
   return SQLITE_OK;
};

class storage_t {
public:
   storage_t()
   :m_db( 0 )
   {
   sqlite3_open( "your_database.db", _db );
   };
   virtual ~storage_t()
   {
   sqlite3_close( m_db );
   };

   void push( const std::string & v )
   {
   m_buff.push_back( v );
   }

   void read_table()
   {
   sqlite3_exec( m_db, "SELECT * FROM some_table",
   add_value, this, NULL );
   }

private:
   sqlite3 * m_db;
   std::vector< std::string > m_buff;
};

This is very simple example, but it can help you I think.

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

[sqlite] Object Oriented Question About Adding a vector inside the callback function

2007-08-09 Thread Stephen Sutherland
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