Re: [sqlite] Using prepare, step, finalize and handling BUSY answers

2006-07-21 Thread Jay Sprenkle

>
That's what I think as well.
But, when you say 'all your suggestions' are you talking about
sqlite3_interrupt too?


That would be useful if you were doing queries where you don't know how long
they will take. All my code is written in a way the queries are short so I would
not have to abort long ones. Depending on your usage that would be a very
nice feature..


--
SqliteImporter and SqliteReplicator: Command line utilities for Sqlite
http://www.reddawn.net/~jsprenkl/Sqlite

Cthulhu Bucks!
http://www.cthulhubucks.com


Re: [sqlite] Using prepare, step, finalize and handling BUSY answers

2006-07-21 Thread Jay Sprenkle

Jay, thank you very much man! That answers a lot. And it showed me that
I was not checking the SQLITE_LOCKED case.

But, from what I can see, if your database is busy or locked you just
stop your program execution, or you will end this function WITHOUT
running neither sqlite3_finalize nor sqlite3_close. Either way you will
have a memory leak and this is not a good thing when you're running an
daemon (my case).

What if you put an loop = false instead of the throw at the 'default'
case? Do you have to you use sqlite3_interrupt before sqlite3_finalize?


This code was for a benchmark so I wasn't careful to check for locking
and do good error recovery. You're correct, and all your suggestions
should be put in.  You'll have to decide what's an appropriate error
response for your daemon.

I usually use the assumption none of the applications using the database
will keep it locked for long periods. So retrying for a small time
after a lock return
works well for me.


Re: [sqlite] Using prepare, step, finalize and handling BUSY answers

2006-07-21 Thread Daniel van Ham Colchete
Jay Sprenkle wrote:
> Here's some example code:
>
> sqlite3*db;
>
> // connect to database
> if ( sqlite3_open( "test.db",  ) )
>   throw "Can't open database";
>
> char* sql;
>
> // two forms of the same sql
> sql = "SELECT one.test1, two.test2"
>  " FROM one"
>  " INNER JOIN two ON one.id = two.id"
>  ;
> sqlite3_stmt*   pStmt;
>
> if ( sqlite3_prepare( db, sql, strlen(sql), , NULL ) != SQLITE_OK )
>   {
>  string str = "Cannot prepare sql: ";
>  str += sql[t];
>  str += ", Error: ";
>  str += sqlite3_errmsg(db);
>  throw str.c_str();
>   }
>
> bool Loop = true;
> while ( Loop )
>   switch ( sqlite3_step( pStmt ) )
>  {
> case SQLITE_ROW:
>// retrieve the results
>char* p = (char *) sqlite3_column_text( pStmt, 0 );
>string test1  = string( p ? p : "" );
>
>p = (char *) sqlite3_column_text( pStmt, 1 );
>string test2 = string( p ? p : "" );
>
>break;
> case SQLITE_DONE:
>Loop = false;
>break;
> case SQLITE_BUSY:
> case SQLITE_LOCKED:
> default:
>string str = "Cannot execute sql: ";
>str += sql[t];
>str += ", Error: ";
>str += sqlite3_errmsg(db);
>throw str.c_str();
>break;
>  }
>
> // clean up when finished
> sqlite3_finalize( pStmt );
>
> sqlite3_close( db );

Jay, thank you very much man! That answers a lot. And it showed me that
I was not checking the SQLITE_LOCKED case.

But, from what I can see, if your database is busy or locked you just
stop your program execution, or you will end this function WITHOUT
running neither sqlite3_finalize nor sqlite3_close. Either way you will
have a memory leak and this is not a good thing when you're running an
daemon (my case).

What if you put an loop = false instead of the throw at the 'default'
case? Do you have to you use sqlite3_interrupt before sqlite3_finalize?

Best regards,
Daniel Colchete