> On 4 Sep 2014, at 4:21pm, Jan Slodicka <[email protected]> wrote:
>
> Our C# wrapper (inspired by system.data.sqlite) uses this quasi-code:
>
> bool Step(stmt)
> {
> while(true)
> {
> start time measurement
> rc = sqlite3_step(stmt);
> if( rc == SQLITE_ROW) return true; // ... reading column values
> possible
> if( rc == SQLITE_DONE) return false; // ... done
>
> rc = sqlite3_reset(stmt); // needed? looks strange to me
>
> if( rc!=SQLITE_LOCKED && rc!=SQLITE_BUSY)
> throw an exception (message taken from sqlite3_errmsg())
> else {
> if timeout expired => throw a timeout exception
> else sleep a bit
> }
> }
> }
Bad code. No cookie. A better structure would be
int stepResult = sqlite3_step(statement);
while (stepResult == SQLITE_ROW) {
// we received a legit row of data
// so handle it here then once it has been handled ...
stepResult = sqlite3_step(statement);
}
sqlite3_finalize(statement);
// now stepResult contains the reason there was no more data.
// if stepResult == SQLITE_DONE then we just finished receiving legit
// results and can carry on with the program. But ...
if (stepResult != SQLITE_DONE) {
// handle other result codes here and halt/cancel/error
}
You don't need to sleep for timeouts yourself. Just use this call once, after
you've opened your connection, to set a timeout of a minute or so ...
<http://www.sqlite.org/c3ref/busy_timeout.html>
and SQLite will handle timeouts and sleeping and exponential backoff itself
without you having to write your own code to do it. If the database is still
locked after the amount of timeout you specified, /then/ you get SQLITE_BUSY.
> If I understand sqlite3_reset correctly (i.e. when it is called after some
> table rows are read, then it returns to the first row), then this code looks
> buggy.
A statement still exists until it has been sqlite3_reset() or
sqlite3_finalized() and you should act as if it's taking up memory, pointers,
or some other annoying stuff. You reset it if you think you're going to start
it again later, which will restart a SELECT from the first row again. You
finalize it if you're done with it and don't intend to execute it again later.
Both of these calls release resources and set status so that when you
eventually close the connection to the database SQLite knows you've tidied up
and can release everything associated with it.
Theoretically you should not execute things like sqlite3_finalize() or
sqlite3_close() without checking the values they returned to make sure they're
SQLITE_OK. I ommitted this check from my above example to make it more
understandable.
Simon.
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users