/ Check-in [ca99920b]
Login

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

Overview
Comment:Add comments and prototype for experimental sqlite_last_statement_changes() API function. Also, allow function to be called from tcl. (CVS 1273)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:ca99920b0dbf773962b47766d690154fd1276513
User & Date: rdc 2004-02-25 22:51:06
Context
2004-02-26
19:47
Build system update:

* Update of generated/libtoolized files: config.guess, config.sub, configure, ltmain.sh * Removal of libtool, which is generated by configure * Changes to Makefile.in, adding better support for newer libtools (CVS 1274) check-in: 22d63bbf user: a.rottmann tags: trunk

2004-02-25
22:51
Add comments and prototype for experimental sqlite_last_statement_changes() API function. Also, allow function to be called from tcl. (CVS 1273) check-in: ca99920b user: rdc tags: trunk
13:47
Min() and max() functions honor the distinction between TEXT and NUMERIC data. Ticket #623. typeof() is now a user function. Some tests are now failing due to ticket #521. (CVS 1272) check-in: adbe31ad user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/func.c.

    12     12   ** This file contains the C functions that implement various SQL
    13     13   ** functions of SQLite.  
    14     14   **
    15     15   ** There is only one exported symbol in this file - the function
    16     16   ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
    17     17   ** All other code has file scope.
    18     18   **
    19         -** $Id: func.c,v 1.42 2004/02/25 13:47:32 drh Exp $
           19  +** $Id: func.c,v 1.43 2004/02/25 22:51:06 rdc Exp $
    20     20   */
    21     21   #include <ctype.h>
    22     22   #include <math.h>
    23     23   #include <stdlib.h>
    24     24   #include <assert.h>
    25     25   #include "sqliteInt.h"
    26     26   #include "os.h"
................................................................................
   206    206   ** value is the same as the sqlite_last_insert_rowid() API function.
   207    207   */
   208    208   static void last_insert_rowid(sqlite_func *context, int arg, const char **argv){
   209    209     sqlite *db = sqlite_user_data(context);
   210    210     sqlite_set_result_int(context, sqlite_last_insert_rowid(db));
   211    211   }
   212    212   
          213  +/*
          214  +** Implementation of the change_count() SQL function.  The return
          215  +** value is the same as the sqlite_changes() API function.
          216  +*/
   213    217   static void change_count(sqlite_func *context, int arg, const char **argv){
   214    218     sqlite *db = sqlite_user_data(context);
   215    219     sqlite_set_result_int(context, sqlite_changes(db));
   216    220   }
          221  +
          222  +/*
          223  +** Implementation of the last_statement_change_count() SQL function.  The
          224  +** return value is the same as the sqlite_last_statement_changes() API function.
          225  +*/
   217    226   static void last_statement_change_count(sqlite_func *context, int arg,
   218    227                                           const char **argv){
   219    228     sqlite *db = sqlite_user_data(context);
   220    229     sqlite_set_result_int(context, sqlite_last_statement_changes(db));
   221    230   }
   222    231   
   223    232   /*

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.160 2004/02/25 13:47:32 drh Exp $
           17  +** $Id: main.c,v 1.161 2004/02/25 22:51:06 rdc Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** A pointer to this structure is used to communicate information
................................................................................
   541    541   /*
   542    542   ** Return the number of changes in the most recent call to sqlite_exec().
   543    543   */
   544    544   int sqlite_changes(sqlite *db){
   545    545     return db->nChange;
   546    546   }
   547    547   
          548  +/*
          549  +** Return the number of changes produced by the last INSERT, UPDATE, or
          550  +** DELETE statement to complete execution. The count does not include
          551  +** changes due to SQL statements executed in trigger programs that were
          552  +** triggered by that statement
          553  +*/
   548    554   int sqlite_last_statement_changes(sqlite *db){
   549    555     return db->lsChange;
   550    556   }
   551    557   
   552    558   /*
   553    559   ** Close an existing SQLite database
   554    560   */

Changes to src/sqlite.h.in.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This header file defines the interface that the SQLite library
    13     13   ** presents to client programs.
    14     14   **
    15         -** @(#) $Id: sqlite.h.in,v 1.58 2004/02/25 13:47:33 drh Exp $
           15  +** @(#) $Id: sqlite.h.in,v 1.59 2004/02/25 22:51:06 rdc Exp $
    16     16   */
    17     17   #ifndef _SQLITE_H_
    18     18   #define _SQLITE_H_
    19     19   #include <stdarg.h>     /* Needed for the definition of va_list */
    20     20   
    21     21   /*
    22     22   ** Make sure we can call this stuff from C++.
................................................................................
   200    200   ** this optimization, the change count for "DELETE FROM table" will be
   201    201   ** zero regardless of the number of elements that were originally in the
   202    202   ** table. To get an accurate count of the number of rows deleted, use
   203    203   ** "DELETE FROM table WHERE 1" instead.
   204    204   */
   205    205   int sqlite_changes(sqlite*);
   206    206   
          207  +/*
          208  +** This function returns the number of database rows that were changed
          209  +** by the last INSERT, UPDATE, or DELETE statment executed by sqlite_exec(),
          210  +** or by the last VM to run to completion. The change count is not updated
          211  +** by SQL statements other than INSERT, UPDATE or DELETE.
          212  +**
          213  +** Changes are counted, even if they are later undone by a ROLLBACK or
          214  +** ABORT. Changes associated with trigger programs that execute as a
          215  +** result of the INSERT, UPDATE, or DELETE statement are not counted.
          216  +**
          217  +** If a callback invokes sqlite_exec() recursively, then the changes
          218  +** in the inner, recursive call are counted together with the changes
          219  +** in the outer call.
          220  +**
          221  +** SQLite implements the command "DELETE FROM table" without a WHERE clause
          222  +** by dropping and recreating the table.  (This is much faster than going
          223  +** through and deleting individual elements form the table.)  Because of
          224  +** this optimization, the change count for "DELETE FROM table" will be
          225  +** zero regardless of the number of elements that were originally in the
          226  +** table. To get an accurate count of the number of rows deleted, use
          227  +** "DELETE FROM table WHERE 1" instead.
          228  +**
          229  +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
          230  +*/
          231  +int sqlite_last_statement_changes(sqlite*);
          232  +
   207    233   /* If the parameter to this routine is one of the return value constants
   208    234   ** defined above, then this routine returns a constant text string which
   209    235   ** descripts (in English) the meaning of the return value.
   210    236   */
   211    237   const char *sqlite_error_string(int);
   212    238   #define sqliteErrStr sqlite_error_string  /* Legacy. Do not use in new code. */
   213    239   

Changes to src/tclsqlite.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** A TCL Interface to SQLite
    13     13   **
    14         -** $Id: tclsqlite.c,v 1.58 2004/02/12 20:49:36 drh Exp $
           14  +** $Id: tclsqlite.c,v 1.59 2004/02/25 22:51:06 rdc Exp $
    15     15   */
    16     16   #ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
    17     17   
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include <stdlib.h>
    21     21   #include <string.h>
................................................................................
   484    484   ** subroutine to be invoked.
   485    485   */
   486    486   static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
   487    487     SqliteDb *pDb = (SqliteDb*)cd;
   488    488     int choice;
   489    489     int rc = TCL_OK;
   490    490     static const char *DB_strs[] = {
   491         -    "authorizer",         "busy",              "changes",
   492         -    "close",              "commit_hook",       "complete",
   493         -    "errorcode",          "eval",              "function",
   494         -    "last_insert_rowid",  "onecolumn",         "progress",
   495         -    "rekey",              "timeout",           "trace",
          491  +    "authorizer",         "busy",                   "changes",
          492  +    "close",              "commit_hook",            "complete",
          493  +    "errorcode",          "eval",                   "function",
          494  +    "last_insert_rowid",  "last_statement_changes", "onecolumn",
          495  +    "progress",           "rekey",                  "timeout",
          496  +    "trace",
   496    497       0                    
   497    498     };
   498    499     enum DB_enum {
   499         -    DB_AUTHORIZER,        DB_BUSY,             DB_CHANGES,
   500         -    DB_CLOSE,             DB_COMMIT_HOOK,      DB_COMPLETE,
   501         -    DB_ERRORCODE,         DB_EVAL,             DB_FUNCTION,
   502         -    DB_LAST_INSERT_ROWID, DB_ONECOLUMN,        DB_PROGRESS,
   503         -    DB_REKEY,             DB_TIMEOUT,          DB_TRACE,
          500  +    DB_AUTHORIZER,        DB_BUSY,                   DB_CHANGES,
          501  +    DB_CLOSE,             DB_COMMIT_HOOK,            DB_COMPLETE,
          502  +    DB_ERRORCODE,         DB_EVAL,                   DB_FUNCTION,
          503  +    DB_LAST_INSERT_ROWID, DB_LAST_STATEMENT_CHANGES, DB_ONECOLUMN,        
          504  +    DB_PROGRESS,          DB_REKEY,                  DB_TIMEOUT,
          505  +    DB_TRACE
   504    506     };
   505    507   
   506    508     if( objc<2 ){
   507    509       Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
   508    510       return TCL_ERROR;
   509    511     }
   510    512     if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){
................................................................................
   655    657         return TCL_ERROR;
   656    658       }
   657    659       nChange = sqlite_changes(pDb->db);
   658    660       pResult = Tcl_GetObjResult(interp);
   659    661       Tcl_SetIntObj(pResult, nChange);
   660    662       break;
   661    663     }
          664  +
          665  +  /*
          666  +  **     $db last_statement_changes
          667  +  **
          668  +  ** Return the number of rows that were modified, inserted, or deleted by
          669  +  ** the last statment to complete execution (excluding changes due to
          670  +  ** triggers)
          671  +  */
          672  +  case DB_LAST_STATEMENT_CHANGES: {
          673  +    Tcl_Obj *pResult;
          674  +    int lsChange;
          675  +    if( objc!=2 ){
          676  +      Tcl_WrongNumArgs(interp, 2, objv, "");
          677  +      return TCL_ERROR;
          678  +    }
          679  +    lsChange = sqlite_last_statement_changes(pDb->db);
          680  +    pResult = Tcl_GetObjResult(interp);
          681  +    Tcl_SetIntObj(pResult, lsChange);
          682  +    break;
          683  +  }
   662    684   
   663    685     /*    $db close
   664    686     **
   665    687     ** Shutdown the database
   666    688     */
   667    689     case DB_CLOSE: {
   668    690       Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));

Changes to test/tclsqlite.test.

    11     11   # This file implements regression tests for TCL interface to the
    12     12   # SQLite library. 
    13     13   #
    14     14   # Actually, all tests are based on the TCL interface, so the main
    15     15   # interface is pretty well tested.  This file contains some addition
    16     16   # tests for fringe issues that the main test suite does not cover.
    17     17   #
    18         -# $Id: tclsqlite.test,v 1.19 2004/02/11 02:18:07 drh Exp $
           18  +# $Id: tclsqlite.test,v 1.20 2004/02/25 22:51:06 rdc Exp $
    19     19   
    20     20   set testdir [file dirname $argv0]
    21     21   source $testdir/tester.tcl
    22     22   
    23     23   # Check the error messages generated by tclsqlite
    24     24   #
    25     25   if {[sqlite -has-codec]} {
................................................................................
    30     30   do_test tcl-1.1 {
    31     31     set v [catch {sqlite bogus} msg]
    32     32     lappend v $msg
    33     33   } [list 1 "wrong # args: should be \"$r\""]
    34     34   do_test tcl-1.2 {
    35     35     set v [catch {db bogus} msg]
    36     36     lappend v $msg
    37         -} {1 {bad option "bogus": must be authorizer, busy, changes, close, commit_hook, complete, errorcode, eval, function, last_insert_rowid, onecolumn, progress, rekey, timeout, or trace}}
           37  +} {1 {bad option "bogus": must be authorizer, busy, changes, close, commit_hook, complete, errorcode, eval, function, last_insert_rowid, last_statement_changes, onecolumn, progress, rekey, timeout, or trace}}
    38     38   do_test tcl-1.3 {
    39     39     execsql {CREATE TABLE t1(a int, b int)}
    40     40     execsql {INSERT INTO t1 VALUES(10,20)}
    41     41     set v [catch {
    42     42       db eval {SELECT * FROM t1} data {
    43     43         error "The error message"
    44     44       }