Skip to content

Commit

Permalink
Adding the sqlite3_stmt_readonly() interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
Unknown committed Nov 16, 2010
1 parent e681950 commit 769de85
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 2 deletions.
15 changes: 15 additions & 0 deletions src/sqlite.h.in
Expand Up @@ -2628,6 +2628,21 @@ int sqlite3_prepare16_v2(
*/
const char *sqlite3_sql(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
**
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
** the [prepared statement] X is guaranteed to leave the database file
** unmodified. ^If the sqlite3_stmt_readonly(X) interface returns false (zero)
** then evaluating the statement might change the database file, but this
** is not guaranteed as the write operation might be conditional and the
** condition might not be met. ^If X is a NULL pointer then
** sqlite3_stmt_readonly(X) returns true. If X is a non-NULL pointer but
** is not a pointer to a valid, unfinalized prepared statement, then the
** behavior is undefined and probably harmful.
*/
int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Dynamically Typed Value Object
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
Expand Down
28 changes: 28 additions & 0 deletions src/test1.c
Expand Up @@ -2299,6 +2299,33 @@ static int test_next_stmt(
return TCL_OK;
}

/*
** Usage: sqlite3_stmt_readonly STMT
**
** Return true if STMT is a NULL pointer or a pointer to a statement
** that is guaranteed to leave the database unmodified.
*/
static int test_stmt_readonly(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_stmt *pStmt;
int rc;

if( objc!=2 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
return TCL_ERROR;
}

if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
rc = sqlite3_stmt_readonly(pStmt);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc));
return TCL_OK;
}


/*
** Usage: sqlite3_reset STMT
Expand Down Expand Up @@ -5392,6 +5419,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_step", test_step ,0 },
{ "sqlite3_sql", test_sql ,0 },
{ "sqlite3_next_stmt", test_next_stmt ,0 },
{ "sqlite3_stmt_readonly", test_stmt_readonly ,0 },

{ "sqlite3_release_memory", test_release_memory, 0},
{ "sqlite3_soft_heap_limit", test_soft_heap_limit, 0},
Expand Down
8 changes: 8 additions & 0 deletions src/vdbeapi.c
Expand Up @@ -1266,6 +1266,14 @@ sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->db : 0;
}

/*
** Return true if the prepared statement is guaranteed to not modify the
** database.
*/
int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
}

/*
** Return a pointer to the next prepared statement after pStmt associated
** with database connection pDb. If pStmt is NULL, return the first
Expand Down
27 changes: 25 additions & 2 deletions test/capi3d.test
Expand Up @@ -10,7 +10,8 @@
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file is devoted to testing the sqlite3_next_stmt interface.
# This file is devoted to testing the sqlite3_next_stmt and
# sqlite3_stmt_readonly interfaces.
#
# $Id: capi3d.test,v 1.2 2008/07/14 15:11:20 drh Exp $
#
Expand Down Expand Up @@ -88,6 +89,28 @@ for {set i 1} {$i<=100} {incr i} {
sqlite3_next_stmt db 0
} {}
}


# Tests for the is-read-only interface.
#
proc test_is_readonly {testname sql truth} {
do_test $testname [format {
set DB [sqlite3_connection_pointer db]
set STMT [sqlite3_prepare $DB {%s} -1 TAIL]
set rc [sqlite3_stmt_readonly $STMT]
sqlite3_finalize $STMT
set rc
} $sql] $truth
}

test_is_readonly capi3d-2.1 {SELECT * FROM sqlite_master} 1
test_is_readonly capi3d-2.2 {CREATE TABLE t1(x)} 0
db eval {CREATE TABLE t1(x)}
test_is_readonly capi3d-2.3 {INSERT INTO t1 VALUES(5)} 0
test_is_readonly capi3d-2.4 {UPDATE t1 SET x=x+1 WHERE x<0} 0
test_is_readonly capi3d-2.5 {SELECT * FROM t1} 1
do_test capi3-2.99 {
sqlite3_stmt_readonly 0
} 1


finish_test

0 comments on commit 769de85

Please sign in to comment.