[sqlite] Determine type of prepared statement via C Interface?

2015-05-08 Thread Stephan Beal
On Fri, May 8, 2015 at 7:01 PM, Stephen Broberg 
wrote:

> (e.g., insert, update, delete, select, etc.).  Specifically, I?d like to
> know whether a statement that either has run or is about to be run (via
> sqlite3_step) is a read-only (select) or write (pretty much everything
> else) operation.


Not a complete answer, but a SELECT (or select-like pragma) will have a
column count of >0.

-- 
- stephan beal
http://wanderinghorse.net/home/stephan/
http://gplus.to/sgbeal
"Freedom is sloppy. But since tyranny's the only guaranteed byproduct of
those who insist on a perfect world, freedom will have to do." -- Bigby Wolf


[sqlite] Determine type of prepared statement via C Interface?

2015-05-08 Thread Zsbán Ambrus
On Fri, May 8, 2015 at 8:20 PM, Simon Slavin  wrote:
> Suppose you have this statement
>
> DELETE FROM myTable WHERE id=600
>
> and there are no rows with id=600.  I presume that the function will return 
> FALSE but a literal reading of the description says that it will return TRUE. 
>  If I'm right then it might be useful to rewrite the documentation a little.

I don't think sqlite_stmt_readonly does that.  If you want to know if
a statement has actually written to the database, call
sqlite_total_changes before and after executing the statement, and
compare their return values.  Make sure you don't run other statements
or write operations on the database during that time.

-- Ambrus


[sqlite] Determine type of prepared statement via C Interface?

2015-05-08 Thread Simon Slavin

On 8 May 2015, at 6:43pm, Peter Aronson  wrote:

> Well, there's sqlite3_stmt_readonly which appears to do pretty much what 
> you're asking for: https://www.sqlite.org/c3ref/stmt_readonly.html. 

Suppose you have this statement

DELETE FROM myTable WHERE id=600

and there are no rows with id=600.  I presume that the function will return 
FALSE but a literal reading of the description says that it will return TRUE.  
If I'm right then it might be useful to rewrite the documentation a little.

Simon.


[sqlite] Determine type of prepared statement via C Interface?

2015-05-08 Thread Stephen Broberg
Using versions 3.8.5 and 3.7.7.1:

Is there something in the SQLite C API that will tell what type of statement a 
prepared sqlite3_stmt is (e.g., insert, update, delete, select, etc.).  
Specifically, I?d like to know whether a statement that either has run or is 
about to be run (via sqlite3_step) is a read-only (select) or write (pretty 
much everything else) operation.  I?m implementing a reader/writer lock 
mechanism around our access to the sqlite database, and as the consumer of the 
interface will need to specify the lock type when they construct a query object 
(save point objects would always be write, of course), I?d want to runtime 
sanity-check their choice after preparing the statement, and log or throw an 
error if they flagged a non-select statement as a reader.  Perhaps it?s 
possible to interrogate the connection object after a statement runs to 
determine if the database was changed?

A possible approach might be to use sqlite3_update_hook or sqlite3_commit_hook 
to identify the statements that modify the db.  Does sqlite3_commit_hook fire 
when a statement is implicitly committed (e.g., an update executed outside the 
context of a savepoint when in autocommit mode)?  Another option might be to 
use two database connections, one read-only, the other normal, but the design 
of our current system makes this option a major redesign (this is legacy code 
I?ve inherited.  If I had my druthers, I?d be using a dedicated sqlite 
connection per thread and running in multi-thread mode, but right now that?s 
too great a refactoring task).

Or am I doing this wrong?  Our multithreaded app produces a lot of SQLITE_BUSY 
results when concurrency increases; serializing our transactions, both read & 
write, globally solved this problem and increased throughput, but I?m 
interested in moving beyond a simple mutex to a read/write one.  We?re running 
Serialized mode, but is there some other sqlite configuration that 
automatically does what I?m trying to accomplish: serialize all write 
operations and save points for all threads, allow selects to run concurrently?

Thanks.


[sqlite] Determine type of prepared statement via C Interface?

2015-05-08 Thread Scott Hess
On Fri, May 8, 2015 at 11:20 AM, Simon Slavin  wrote:
> On 8 May 2015, at 6:43pm, Peter Aronson  wrote:
>> Well, there's sqlite3_stmt_readonly which appears to do pretty much what 
>> you're asking for: https://www.sqlite.org/c3ref/stmt_readonly.html.
>
> Suppose you have this statement
>
> DELETE FROM myTable WHERE id=600
>
> and there are no rows with id=600.  I presume that the function will return 
> FALSE but a literal reading of the description says that it will return TRUE. 
>  If I'm right then it might be useful to rewrite the documentation a little.

Why would you presume that it would return FALSE?  That would
essentially require executing the statement, which definitely _would_
be something useful to add to the documentation (but I doubt it does
that).

-scott


[sqlite] Determine type of prepared statement via C Interface?

2015-05-08 Thread Peter Aronson
Well, there's sqlite3_stmt_readonly which appears to do pretty much what 
you're asking for: https://www.sqlite.org/c3ref/stmt_readonly.html.  Or, 
if you want more detailed control, there's the whole authorizer 
interface: https://www.sqlite.org/c3ref/set_authorizer.html.

Peter

On 5/8/2015 10:01 AM, Stephen Broberg wrote:
> Using versions 3.8.5 and 3.7.7.1:
>
> Is there something in the SQLite C API that will tell what type of statement 
> a prepared sqlite3_stmt is (e.g., insert, update, delete, select, etc.).  
> Specifically, I?d like to know whether a statement that either has run or is 
> about to be run (via sqlite3_step) is a read-only (select) or write (pretty 
> much everything else) operation.  I?m implementing a reader/writer lock 
> mechanism around our access to the sqlite database, and as the consumer of 
> the interface will need to specify the lock type when they construct a query 
> object (save point objects would always be write, of course), I?d want to 
> runtime sanity-check their choice after preparing the statement, and log or 
> throw an error if they flagged a non-select statement as a reader.  Perhaps 
> it?s possible to interrogate the connection object after a statement runs to 
> determine if the database was changed?
>
> A possible approach might be to use sqlite3_update_hook or 
> sqlite3_commit_hook to identify the statements that modify the db.  Does 
> sqlite3_commit_hook fire when a statement is implicitly committed (e.g., an 
> update executed outside the context of a savepoint when in autocommit mode)?  
> Another option might be to use two database connections, one read-only, the 
> other normal, but the design of our current system makes this option a major 
> redesign (this is legacy code I?ve inherited.  If I had my druthers, I?d be 
> using a dedicated sqlite connection per thread and running in multi-thread 
> mode, but right now that?s too great a refactoring task).
>
> Or am I doing this wrong?  Our multithreaded app produces a lot of 
> SQLITE_BUSY results when concurrency increases; serializing our transactions, 
> both read & write, globally solved this problem and increased throughput, but 
> I?m interested in moving beyond a simple mutex to a read/write one.  We?re 
> running Serialized mode, but is there some other sqlite configuration that 
> automatically does what I?m trying to accomplish: serialize all write 
> operations and save points for all threads, allow selects to run concurrently?
>
> Thanks.
> ___
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users



[sqlite] Determine type of prepared statement via C Interface?

2015-05-08 Thread Scott Hess
sqlite3_stmt_readonly(stmt)?  This hits INSERT/UPDATE/DELETE, but not
BEGIN/COMMIT/ROLLBACK.

Or sqlite3_sql(stmt) if you want to do it heuristically by inspecting
the statement.

I think a "BEGIN READONLY" would be a sensible transaction type.
Having a wrapper API force the developer to select read-only or
immediate for the transaction type up front has some benefits.  My
experience is that most developers don't write their code in a way
which allows them to correctly handle SQLITE_BUSY after the
transaction starts, and once they've written it it can be hard to
refactor things to allow the overall transaction to be correctly
restarted.

-scott


On Fri, May 8, 2015 at 10:01 AM, Stephen Broberg  
wrote:
> Using versions 3.8.5 and 3.7.7.1:
>
> Is there something in the SQLite C API that will tell what type of statement 
> a prepared sqlite3_stmt is (e.g., insert, update, delete, select, etc.).  
> Specifically, I?d like to know whether a statement that either has run or is 
> about to be run (via sqlite3_step) is a read-only (select) or write (pretty 
> much everything else) operation.  I?m implementing a reader/writer lock 
> mechanism around our access to the sqlite database, and as the consumer of 
> the interface will need to specify the lock type when they construct a query 
> object (save point objects would always be write, of course), I?d want to 
> runtime sanity-check their choice after preparing the statement, and log or 
> throw an error if they flagged a non-select statement as a reader.  Perhaps 
> it?s possible to interrogate the connection object after a statement runs to 
> determine if the database was changed?
>
> A possible approach might be to use sqlite3_update_hook or 
> sqlite3_commit_hook to identify the statements that modify the db.  Does 
> sqlite3_commit_hook fire when a statement is implicitly committed (e.g., an 
> update executed outside the context of a savepoint when in autocommit mode)?  
> Another option might be to use two database connections, one read-only, the 
> other normal, but the design of our current system makes this option a major 
> redesign (this is legacy code I?ve inherited.  If I had my druthers, I?d be 
> using a dedicated sqlite connection per thread and running in multi-thread 
> mode, but right now that?s too great a refactoring task).
>
> Or am I doing this wrong?  Our multithreaded app produces a lot of 
> SQLITE_BUSY results when concurrency increases; serializing our transactions, 
> both read & write, globally solved this problem and increased throughput, but 
> I?m interested in moving beyond a simple mutex to a read/write one.  We?re 
> running Serialized mode, but is there some other sqlite configuration that 
> automatically does what I?m trying to accomplish: serialize all write 
> operations and save points for all threads, allow selects to run concurrently?
>
> Thanks.
> ___
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users