SQLite

Check-in [565a530896]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the sqlite3_next_stmt() interface, including test cases. (CVS 5243)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 565a530896b40790287eeaad709edd51980fbddf
User & Date: drh 2008-06-19 02:52:25.000
Context
2008-06-19
08:51
Shuffle some of the mutex related documentation in sqlite.h.in to match the new sqlite3_mutex_methods based API. (CVS 5244) (check-in: 9cd7f8669a user: danielk1977 tags: trunk)
02:52
Add the sqlite3_next_stmt() interface, including test cases. (CVS 5243) (check-in: 565a530896 user: drh tags: trunk)
01:50
Fix a bug in the noop-mutex implementation. (CVS 5242) (check-in: eec9a54dc3 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/sqlite.h.in.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.337 2008/06/19 00:16:08 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.







|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
** on how SQLite interfaces are suppose to operate.
**
** The name of this file under configuration management is "sqlite.h.in".
** The makefile makes some minor changes to this file (such as inserting
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.338 2008/06/19 02:52:25 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
4735
4736
4737
4738
4739
4740
4741

































4742
4743
4744
4745
4746
4747
4748
**
** {F13123} The [sqlite3_db_handle(S)] interface returns a pointer
**          to the [database connection] associated with
**          [prepared statement] S.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt*);



































/*
** CAPI3REF: Commit And Rollback Notification Callbacks {F12950}
**
** The sqlite3_commit_hook() interface registers a callback
** function to be invoked whenever a transaction is committed.
** Any callback set by a previous call to sqlite3_commit_hook()







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
**
** {F13123} The [sqlite3_db_handle(S)] interface returns a pointer
**          to the [database connection] associated with
**          [prepared statement] S.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt*);

/*
** CAPI3REF:  Find the next prepared statement {F13140}
**
** Return a pointer to the next [prepared statement] after pStmt
** associated with [database connection] pDb.  If pStmt is NULL
** then return a pointer to the first [prepared statement] associated
** with the [database connection] pDb.  If no [prepared statement]
** satisfies the conditions of this routine, return NULL.
**
** INVARIANTS:
**
** {F13143} If D is a [database connection] that holds one or more
**          unfinalized [prepared statements] and S is a NULL pointer,
**          then [sqlite3_next_stmt(D, S)] routine shall return a pointer
**          to one of the [prepared statements] associated with D.
**
** {F13146} If D is a [database connection] that holds no
**          unfinalized [prepared statements] and S is a NULL pointer,
**          then [sqlite3_next_stmt(D, S)] routine shall return a NULL
**          pointer.
**
** {F13149} If S is a [prepared statement] in [database connection] D
**          and S is not the last [prepared statement] in D, then
**          [sqlite3_next_stmt(D, S)] routine shall return a pointer
**          to the next [prepared statement] in D after S.
**
** {F13152} If S is the last [prepared statement] in [database connection] D
**          then [sqlite3_next_stmt(D, S)] routine shall return a NULL
**          pointer.
**
*/
sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);


/*
** CAPI3REF: Commit And Rollback Notification Callbacks {F12950}
**
** The sqlite3_commit_hook() interface registers a callback
** function to be invoked whenever a transaction is committed.
** Any callback set by a previous call to sqlite3_commit_hook()
Changes to src/test1.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.305 2008/05/29 02:57:48 shane Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.306 2008/06/19 02:52:25 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
1893
1894
1895
1896
1897
1898
1899
































1900
1901
1902
1903
1904
1905
1906
    db = StmtToDb(pStmt);
  }
  rc = sqlite3_finalize(pStmt);
  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
  if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
  return TCL_OK;
}

































/*
** Usage:  sqlite3_reset  STMT 
**
** Reset a statement handle.
*/
static int test_reset(







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
    db = StmtToDb(pStmt);
  }
  rc = sqlite3_finalize(pStmt);
  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
  if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
  return TCL_OK;
}

/*
** Usage:  sqlite3_next_stmt  DB  STMT
**
** Return the next statment in sequence after STMT.
*/
static int test_next_stmt(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3_stmt *pStmt;
  sqlite3 *db = 0;
  char zBuf[50];

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

  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt) ) return TCL_ERROR;
  pStmt = sqlite3_next_stmt(db, pStmt);
  if( pStmt ){
    if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
    Tcl_AppendResult(interp, zBuf, 0);
  }
  return TCL_OK;
}


/*
** Usage:  sqlite3_reset  STMT 
**
** Reset a statement handle.
*/
static int test_reset(
4601
4602
4603
4604
4605
4606
4607

4608
4609
4610
4611
4612
4613
4614
     { "sqlite3_prepare16_v2",          test_prepare16_v2  ,0 },
     { "sqlite3_finalize",              test_finalize      ,0 },
     { "sqlite3_reset",                 test_reset         ,0 },
     { "sqlite3_expired",               test_expired       ,0 },
     { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
     { "sqlite3_changes",               test_changes       ,0 },
     { "sqlite3_step",                  test_step          ,0 },


     { "sqlite3_release_memory",        test_release_memory,     0},
     { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
     { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
     { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},

     { "sqlite3_load_extension",        test_load_extension,     0},







>







4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
     { "sqlite3_prepare16_v2",          test_prepare16_v2  ,0 },
     { "sqlite3_finalize",              test_finalize      ,0 },
     { "sqlite3_reset",                 test_reset         ,0 },
     { "sqlite3_expired",               test_expired       ,0 },
     { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
     { "sqlite3_changes",               test_changes       ,0 },
     { "sqlite3_step",                  test_step          ,0 },
     { "sqlite3_next_stmt",             test_next_stmt     ,0 },

     { "sqlite3_release_memory",        test_release_memory,     0},
     { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
     { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
     { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},

     { "sqlite3_load_extension",        test_load_extension,     0},
Changes to src/vdbeapi.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
**
** $Id: vdbeapi.c,v 1.133 2008/06/18 17:09:10 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** The following structure contains pointers to the end points of a







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
**
** $Id: vdbeapi.c,v 1.134 2008/06/19 02:52:25 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** The following structure contains pointers to the end points of a
1252
1253
1254
1255
1256
1257
1258


















** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
  return pStmt ? ((Vdbe*)pStmt)->db : 0;
}

























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
  return pStmt ? ((Vdbe*)pStmt)->db : 0;
}

/*
** Return a pointer to the next prepared statement after pStmt associated
** with database connection pDb.  If pStmt is NULL, return the first
** prepared statement for the database connection.  Return NULL if there
** are no more.
*/
sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
  sqlite3_stmt *pNext;
  sqlite3_mutex_enter(pDb->mutex);
  if( pStmt==0 ){
    pNext = (sqlite3_stmt*)pDb->pVdbe;
  }else{
    pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext;
  }
  sqlite3_mutex_leave(pDb->mutex);
  return pNext;
}
Added test/capi3d.test.
























































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# 2008 June 18
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  
#
# This file is devoted to testing the sqlite3_next_stmt interface.
#
# $Id: capi3d.test,v 1.1 2008/06/19 02:52:25 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create N prepared statements against database connection db
# and return a list of all the generated prepared statements.
#
proc make_prepared_statements {N} {
  set plist {}
  for {set i 0} {$i<$N} {incr i} {
    set sql "SELECT $i FROM sqlite_master WHERE name LIKE '%$i%'"
    if {rand()<0.33} {    
      set s [sqlite3_prepare_v2 db $sql -1 notused]
    } else {
      ifcapable utf16 {
        if {rand()<0.5} {
          set sql [encoding convertto unicode $sql]\x00\x00
          set s [sqlite3_prepare16 db $sql -1 notused]
        } else {
          set s [sqlite3_prepare db $sql -1 notused]
        }
      }
      ifcapable !utf16 {
        set s [sqlite3_prepare db $sql -1 notused]
      }
    }
    lappend plist $s
  }
  return $plist
}


# Scramble the $inlist into a random order.
#
proc scramble {inlist} {
  set y {}
  foreach x $inlist {
    lappend y [list [expr {rand()}] $x]
  }
  set y [lsort $y]
  set outlist {}
  foreach x $y {
    lappend outlist [lindex $x 1]
  }
  return $outlist
}

# Database initially has no prepared statements.
#
do_test capi3d-1.1 {
  sqlite3_next_stmt db 0
} {}

# Run the following tests for between 1 and 100 prepared statements.
#
for {set i 1} {$i<=100} {incr i} {
  set stmtlist [make_prepared_statements $i]
  do_test capi3d-1.2.$i.1 {
    set p [sqlite3_next_stmt db 0]
    set x {}
    while {$p!=""} {
      lappend x $p
      set p [sqlite3_next_stmt db $p]
    }
    lsort $x
  } [lsort $stmtlist]
  do_test capi3-1.2.$i.2 {
    foreach p [scramble $::stmtlist] {
      sqlite3_finalize $p
    }
    sqlite3_next_stmt db 0
  } {}
}
      

finish_test