/ Check-in [8a355d7a]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Add the "exists" method to the TCL interface. (CVS 2813)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8a355d7aade5c7a95ab08aeedf1ee1857c121c33
User & Date: drh 2005-12-10 21:19:05
Context
2005-12-12
06:53
Fix minor malloc() related problems and add sqlite3_soft_heap_limit() stubs. (CVS 2814) check-in: 1637f379 user: danielk1977 tags: trunk
2005-12-10
21:19
Add the "exists" method to the TCL interface. (CVS 2813) check-in: 8a355d7a user: drh tags: trunk
2005-12-09
20:54
New bind tests (check-ins (2797) and (2798)) only work right on a UTF8 database. So make sure they are only run when the database is UTF8. (CVS 2812) check-in: 39803790 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

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.135 2005/12/07 06:27:44 danielk1977 Exp $
           14  +** $Id: tclsqlite.c,v 1.136 2005/12/10 21:19:05 drh 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 "hash.h"
    20     20   #include "tcl.h"
    21     21   #include <stdlib.h>
................................................................................
   617    617     int choice;
   618    618     int rc = TCL_OK;
   619    619     static const char *DB_strs[] = {
   620    620       "authorizer",         "busy",              "cache",
   621    621       "changes",            "close",             "collate",
   622    622       "collation_needed",   "commit_hook",       "complete",
   623    623       "copy",               "errorcode",         "eval",
   624         -    "function",           "last_insert_rowid", "nullvalue",
   625         -    "onecolumn",          "profile",           "progress",
   626         -    "rekey",              "timeout",           "total_changes",
   627         -    "trace",              "transaction",       "version",
   628         -    0                    
          624  +    "exists",             "function",          "last_insert_rowid",
          625  +    "nullvalue",          "onecolumn",         "profile",
          626  +    "progress",           "rekey",             "timeout",
          627  +    "total_changes",      "trace",             "transaction",
          628  +    "version",            0                    
   629    629     };
   630    630     enum DB_enum {
   631    631       DB_AUTHORIZER,        DB_BUSY,             DB_CACHE,
   632    632       DB_CHANGES,           DB_CLOSE,            DB_COLLATE,
   633    633       DB_COLLATION_NEEDED,  DB_COMMIT_HOOK,      DB_COMPLETE,
   634    634       DB_COPY,              DB_ERRORCODE,        DB_EVAL,
   635         -    DB_FUNCTION,          DB_LAST_INSERT_ROWID,DB_NULLVALUE,
   636         -    DB_ONECOLUMN,         DB_PROFILE,          DB_PROGRESS,
   637         -    DB_REKEY,             DB_TIMEOUT,          DB_TOTAL_CHANGES,
   638         -    DB_TRACE,             DB_TRANSACTION,      DB_VERSION
          635  +    DB_EXISTS,            DB_FUNCTION,         DB_LAST_INSERT_ROWID,
          636  +    DB_NULLVALUE,         DB_ONECOLUMN,        DB_PROFILE,
          637  +    DB_PROGRESS,          DB_REKEY,            DB_TIMEOUT,
          638  +    DB_TOTAL_CHANGES,     DB_TRACE,            DB_TRANSACTION,
          639  +    DB_VERSION
   639    640     };
   640    641     /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
   641    642   
   642    643     if( objc<2 ){
   643    644       Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
   644    645       return TCL_ERROR;
   645    646     }
................................................................................
  1132   1133     ** If "array" is an empty string, then the values are placed in variables
  1133   1134     ** that have the same name as the fields extracted by the query.
  1134   1135     **
  1135   1136     ** The onecolumn method is the equivalent of:
  1136   1137     **     lindex [$db eval $sql] 0
  1137   1138     */
  1138   1139     case DB_ONECOLUMN:
  1139         -  case DB_EVAL: {
         1140  +  case DB_EVAL:
         1141  +  case DB_EXISTS: {
  1140   1142       char const *zSql;      /* Next SQL statement to execute */
  1141   1143       char const *zLeft;     /* What is left after first stmt in zSql */
  1142   1144       sqlite3_stmt *pStmt;   /* Compiled SQL statment */
  1143   1145       Tcl_Obj *pArray;       /* Name of array into which results are written */
  1144   1146       Tcl_Obj *pScript;      /* Script to run for each result set */
  1145   1147       Tcl_Obj **apParm;      /* Parameters that need a Tcl_DecrRefCount() */
  1146   1148       int nParm;             /* Number of entries used in apParm[] */
  1147   1149       Tcl_Obj *aParm[10];    /* Static space for apParm[] in the common case */
  1148   1150       Tcl_Obj *pRet;         /* Value to be returned */
  1149   1151       SqlPreparedStmt *pPreStmt;  /* Pointer to a prepared statement */
  1150   1152       int rc2;
  1151   1153   
  1152         -    if( choice==DB_ONECOLUMN ){
  1153         -      if( objc!=3 ){
  1154         -        Tcl_WrongNumArgs(interp, 2, objv, "SQL");
  1155         -        return TCL_ERROR;
  1156         -      }
  1157         -      pRet = 0;
  1158         -    }else{
         1154  +    if( choice==DB_EVAL ){
  1159   1155         if( objc<3 || objc>5 ){
  1160   1156           Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
  1161   1157           return TCL_ERROR;
  1162   1158         }
  1163   1159         pRet = Tcl_NewObj();
  1164   1160         Tcl_IncrRefCount(pRet);
         1161  +    }else{
         1162  +      if( objc!=3 ){
         1163  +        Tcl_WrongNumArgs(interp, 2, objv, "SQL");
         1164  +        return TCL_ERROR;
         1165  +      }
         1166  +      pRet = 0;
         1167  +      if( choice==DB_EXISTS ){
         1168  +        Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
         1169  +      }
  1165   1170       }
  1166   1171       if( objc==3 ){
  1167   1172         pArray = pScript = 0;
  1168   1173       }else if( objc==4 ){
  1169   1174         pArray = 0;
  1170   1175         pScript = objv[3];
  1171   1176       }else{
................................................................................
  1362   1367             if( pScript ){
  1363   1368               if( pArray==0 ){
  1364   1369                 Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);
  1365   1370               }else{
  1366   1371                 Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);
  1367   1372               }
  1368   1373             }else if( choice==DB_ONECOLUMN ){
         1374  +            assert( pRet==0 );
  1369   1375               if( pRet==0 ){
  1370   1376                 pRet = pVal;
  1371   1377                 Tcl_IncrRefCount(pRet);
  1372   1378               }
  1373   1379               rc = TCL_BREAK;
         1380  +            i = nCol;
         1381  +          }else if( choice==DB_EXISTS ){
         1382  +            assert( pRet==0 );
         1383  +            Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
         1384  +            rc = TCL_BREAK;
         1385  +            i = nCol;
  1374   1386             }else{
  1375   1387               Tcl_ListObjAppendElement(interp, pRet, pVal);
  1376   1388             }
  1377   1389           }
  1378   1390     
  1379   1391           if( pScript ){
  1380   1392             rc = Tcl_EvalObjEx(interp, pScript, 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.44 2005/08/29 23:00:05 drh Exp $
           18  +# $Id: tclsqlite.test,v 1.45 2005/12/10 21:19:06 drh 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 {[sqlite3 -has-codec]} {
................................................................................
    30     30   do_test tcl-1.1 {
    31     31     set v [catch {sqlite3 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, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, errorcode, eval, function, last_insert_rowid, nullvalue, onecolumn, profile, progress, rekey, timeout, total_changes, trace, transaction, or version}}
           37  +} {1 {bad option "bogus": must be authorizer, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, errorcode, eval, exists, function, last_insert_rowid, nullvalue, onecolumn, profile, progress, rekey, timeout, total_changes, trace, transaction, or version}}
    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       }
................................................................................
   430    430         }
   431    431       }
   432    432     }]
   433    433   } {2}
   434    434   do_test tcl-10.13 {
   435    435     db eval {SELECT * FROM t4}
   436    436   } {1 2 3 4 5 6 7}
          437  +
          438  +do_test tcl-11.1 {
          439  +  db exists {SELECT x,x*2,x+x FROM t4 WHERE x==4}
          440  +} {1}
          441  +do_test tcl-11.2 {
          442  +  db exists {SELECT 0 FROM t4 WHERE x==4}
          443  +} {1}
          444  +do_test tcl-11.3 {
          445  +  db exists {SELECT 1 FROM t4 WHERE x==8}
          446  +} {0}
   437    447   
   438    448   finish_test