Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Apply Tcl 'nullvalue' patch from Stefan Finzel. (CVS 2441) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9906ae37b9be684b615a1190cf879851 |
User & Date: | danielk1977 2005-04-03 23:54:44.000 |
Context
2005-04-08
| ||
16:07 | Fixed stack growth in delete trigger on views (tkt #1169) (CVS 2442) (check-in: 1a757ba132 user: kwel tags: trunk) | |
2005-04-03
| ||
23:54 | Apply Tcl 'nullvalue' patch from Stefan Finzel. (CVS 2441) (check-in: 9906ae37b9 user: danielk1977 tags: trunk) | |
2005-04-01
| ||
16:29 | Documentation updates. (CVS 2440) (check-in: 7e6f688d46 user: drh tags: trunk) | |
Changes
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $Id: tclsqlite.c,v 1.121 2005/04/03 23:54:44 danielk1977 Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "hash.h" #include "tcl.h" #include <stdlib.h> |
︙ | ︙ | |||
79 80 81 82 83 84 85 86 87 88 89 90 91 92 | sqlite3 *db; /* The "real" database structure */ Tcl_Interp *interp; /* The interpreter used for this database */ char *zBusy; /* The busy callback routine */ char *zCommit; /* The commit hook callback routine */ char *zTrace; /* The trace callback routine */ char *zProgress; /* The progress callback routine */ char *zAuth; /* The authorization callback routine */ SqlFunc *pFunc; /* List of SQL functions */ SqlCollate *pCollate; /* List of SQL collation functions */ int rc; /* Return code of most recent sqlite3_exec() */ Tcl_Obj *pCollateNeeded; /* Collation needed script */ SqlPreparedStmt *stmtList; /* List of prepared statements*/ SqlPreparedStmt *stmtLast; /* Last statement in the list */ int maxStmt; /* The next maximum number of stmtList */ | > | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | sqlite3 *db; /* The "real" database structure */ Tcl_Interp *interp; /* The interpreter used for this database */ char *zBusy; /* The busy callback routine */ char *zCommit; /* The commit hook callback routine */ char *zTrace; /* The trace callback routine */ char *zProgress; /* The progress callback routine */ char *zAuth; /* The authorization callback routine */ char *zNull; /* Text to substitute for an SQL NULL value */ SqlFunc *pFunc; /* List of SQL functions */ SqlCollate *pCollate; /* List of SQL collation functions */ int rc; /* Return code of most recent sqlite3_exec() */ Tcl_Obj *pCollateNeeded; /* Collation needed script */ SqlPreparedStmt *stmtList; /* List of prepared statements*/ SqlPreparedStmt *stmtLast; /* Last statement in the list */ int maxStmt; /* The next maximum number of stmtList */ |
︙ | ︙ | |||
132 133 134 135 136 137 138 139 140 141 142 143 144 145 | } if( pDb->zTrace ){ Tcl_Free(pDb->zTrace); } if( pDb->zAuth ){ Tcl_Free(pDb->zAuth); } Tcl_Free((char*)pDb); } /* ** This routine is called when a database file is locked while trying ** to execute SQL. */ | > > > | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | } if( pDb->zTrace ){ Tcl_Free(pDb->zTrace); } if( pDb->zAuth ){ Tcl_Free(pDb->zAuth); } if( pDb->zNull ){ Tcl_Free(pDb->zNull); } Tcl_Free((char*)pDb); } /* ** This routine is called when a database file is locked while trying ** to execute SQL. */ |
︙ | ︙ | |||
437 438 439 440 441 442 443 | int choice; int rc = TCL_OK; static const char *DB_strs[] = { "authorizer", "busy", "cache", "changes", "close", "collate", "collation_needed", "commit_hook", "complete", "copy", "errorcode", "eval", | | | | > | | | > | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | int choice; int rc = TCL_OK; static const char *DB_strs[] = { "authorizer", "busy", "cache", "changes", "close", "collate", "collation_needed", "commit_hook", "complete", "copy", "errorcode", "eval", "function", "last_insert_rowid", "nullvalue", "onecolumn", "progress", "rekey", "timeout", "total_changes", "trace", "version", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BUSY, DB_CACHE, DB_CHANGES, DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK, DB_COMPLETE, DB_COPY, DB_ERRORCODE, DB_EVAL, DB_FUNCTION, DB_LAST_INSERT_ROWID,DB_NULLVALUE, DB_ONECOLUMN, DB_PROGRESS, DB_REKEY, DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, DB_VERSION }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); return TCL_ERROR; } |
︙ | ︙ | |||
970 971 972 973 974 975 976 977 978 979 980 981 982 983 | } break; } case SQLITE_FLOAT: { double r = sqlite3_column_double(pStmt, i); pVal = Tcl_NewDoubleObj(r); break; } default: { pVal = dbTextToObj(sqlite3_column_text(pStmt, i)); break; } } | > > > > | 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 | } break; } case SQLITE_FLOAT: { double r = sqlite3_column_double(pStmt, i); pVal = Tcl_NewDoubleObj(r); break; } case SQLITE_NULL: { pVal = dbTextToObj(pDb->zNull); break; } default: { pVal = dbTextToObj(sqlite3_column_text(pStmt, i)); break; } } |
︙ | ︙ | |||
1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 | return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR; sqlite3_busy_timeout(pDb->db, ms); break; } /* ** $db total_changes ** ** Return the number of rows that were modified, inserted, or deleted ** since the database handle was created. */ case DB_TOTAL_CHANGES: { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 | return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR; sqlite3_busy_timeout(pDb->db, ms); break; } /* ** $db nullvalue ?STRING? ** ** Change text used when a NULL comes back from the database. If ?STRING? ** is not present, then the current string used for NULL is returned. ** If STRING is present, then STRING is returned. ** */ case DB_NULLVALUE: { if( objc!=2 && objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE"); return TCL_ERROR; } if( objc==3 ){ int len; char *zNull = Tcl_GetStringFromObj(objv[2], &len); if( pDb->zNull ){ Tcl_Free(pDb->zNull); } if( zNull && len>0 ){ pDb->zNull = Tcl_Alloc( len + 1 ); strncpy(pDb->zNull, zNull, len); pDb->zNull[len] = '\0'; }else{ pDb->zNull = 0; } } Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull)); break; } /* ** $db total_changes ** ** Return the number of rows that were modified, inserted, or deleted ** since the database handle was created. */ case DB_TOTAL_CHANGES: { |
︙ | ︙ |
Changes to test/tclsqlite.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 | # This file implements regression tests for TCL interface to the # SQLite library. # # Actually, all tests are based on the TCL interface, so the main # interface is pretty well tested. This file contains some addition # tests for fringe issues that the main test suite does not cover. # | | | | 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 | # This file implements regression tests for TCL interface to the # SQLite library. # # Actually, all tests are based on the TCL interface, so the main # interface is pretty well tested. This file contains some addition # tests for fringe issues that the main test suite does not cover. # # $Id: tclsqlite.test,v 1.39 2005/04/03 23:54:45 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Check the error messages generated by tclsqlite # if {[sqlite3 -has-codec]} { set r "sqlite_orig HANDLE FILENAME ?-key CODEC-KEY?" } else { set r "sqlite3 HANDLE FILENAME ?MODE?" } do_test tcl-1.1 { set v [catch {sqlite3 bogus} msg] lappend v $msg } [list 1 "wrong # args: should be \"$r\""] do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg } {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, progress, rekey, timeout, total_changes, trace, or version}} do_test tcl-1.3 { execsql {CREATE TABLE t1(a int, b int)} execsql {INSERT INTO t1 VALUES(10,20)} set v [catch { db eval {SELECT * FROM t1} data { error "The error message" } |
︙ | ︙ | |||
297 298 299 300 301 302 303 304 305 | return_test 0 } {} do_test tcl-7.1 { db version expr 0 } {0} finish_test | > > > > > > > > > > > > > > > > | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | return_test 0 } {} do_test tcl-7.1 { db version expr 0 } {0} # modify and reset the NULL representation # do_test tcl-8.1 { db nullvalue NaN execsql {INSERT INTO t1 VALUES(30,NULL)} db eval {SELECT * FROM t1 WHERE b IS NULL} } {30 NaN} do_test tcl-8.2 { db nullvalue NULL db nullvalue } {NULL} do_test tcl-8.3 { db nullvalue {} db eval {SELECT * FROM t1 WHERE b IS NULL} } {30 {}} finish_test |
Changes to www/tclsqlite.tcl.
1 2 3 | # # Run this Tcl script to generate the tclsqlite.html file. # | | | 1 2 3 4 5 6 7 8 9 10 11 | # # Run this Tcl script to generate the tclsqlite.html file. # set rcsid {$Id: tclsqlite.tcl,v 1.13 2005/04/03 23:54:45 danielk1977 Exp $} source common.tcl header {The Tcl interface to the SQLite library} proc METHOD {name text} { puts "<a name=\"$name\">\n<h3>The \"$name\" method</h3>\n" puts $text } puts { |
︙ | ︙ | |||
42 43 44 45 46 47 48 | <p> The name of the database is just the name of a disk file in which the database is stored. </p> <p> Once an SQLite database is open, it can be controlled using | | > | 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 | <p> The name of the database is just the name of a disk file in which the database is stored. </p> <p> Once an SQLite database is open, it can be controlled using methods of the <i>dbcmd</i>. There are currently 19 methods defined:</p> <p> <ul> } foreach m [lsort { authorizer busy changes close collate collation_needed commit_hook complete copy errorcode eval function last_insert_rowid nullvalue onecolumn progress timeout total_changes trace }] { puts "<li><a href=\"#$m\">$m</a></li>" |
︙ | ︙ | |||
360 361 362 363 364 365 366 367 368 369 370 371 372 373 | </p> <blockquote><b> db function hex {format 0x%X} </b></blockquote> } ############################################################################## METHOD onecolumn { <p>The "onecolumn" method works like "eval" in that it evaluates the SQL query statement given as its argument. The difference is that "onecolumn" returns a single element which is the first column of the | > > > > > > > > > > > > > > > > > > | 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 | </p> <blockquote><b> db function hex {format 0x%X} </b></blockquote> } ############################################################################## METHOD nullvalue { <p> The "nullvalue" method changes the representation for NULL returned as result of the "eval" method.</p> <blockquote><b> db1 nullvalue NULL </b></blockquote> <p>The "nullvalue" method is useful to differ between NULL and empty column values as Tcl lacks a NULL representation. The default representation for NULL values is an empty string.</p> } ############################################################################## METHOD onecolumn { <p>The "onecolumn" method works like "eval" in that it evaluates the SQL query statement given as its argument. The difference is that "onecolumn" returns a single element which is the first column of the |
︙ | ︙ |