diff --git a/manifest b/manifest index 18582dcc85..873d3e68bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Documentation\supdates.\s(CVS\s2440) -D 2005-04-01T16:29:12 +C Apply\sTcl\s'nullvalue'\spatch\sfrom\sStefan\sFinzel.\s(CVS\s2441) +D 2005-04-03T23:54:44 F Makefile.in 5c00d0037104de2a50ac7647a5f12769795957a3 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -63,7 +63,7 @@ F src/shell.c 25b3217d7c64e6497225439d261a253a23efff26 F src/sqlite.h.in 1ece9aafba94b8515b276b3de73cbabe0912d42a F src/sqliteInt.h 474c20597ee66bb3a666bed0abd76e7be579184a F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9 -F src/tclsqlite.c 650b9ae64d7d9b40b3c8cd8bf27224139a10028e +F src/tclsqlite.c 245b242edfb587e305954698ed93c1bc3daed678 F src/test1.c 32a158ca4aca2e9b43d911eda4552253df9a207d F src/test2.c 7f0ef466706ac01414e1136b96e5d8a65cb97545 F src/test3.c 683e1e3819152ffd35da2f201e507228921148d0 @@ -192,7 +192,7 @@ F test/subquery.test 6274cce7617bc7f625490759cbe4f0c0eef24895 F test/subselect.test 3f3f7a940dc3195c3139f4d530385cb54665d614 F test/table.test e87fb2211b97c6a3a367fbc116e8572091b53160 F test/tableapi.test 6a66d58b37d46dc0f2b3c7d4bd2617d209399bd1 -F test/tclsqlite.test 4ac312b47632596516353948b59089b02312aed7 +F test/tclsqlite.test 7112be2a9d0d70c8767b9b2c748bf39d407a6aba F test/temptable.test c71eeffe8af807f76eafdc5a39824639a1e301df F test/tester.tcl 69c0dc1accaf0ff26bff62b33e13590a4ecba17d F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35 @@ -274,11 +274,11 @@ F www/quickstart.tcl 6f6f694b6139be2d967b1492eb9a6bdf7058aa60 F www/speed.tcl 656ed5be8cc9d536353e1a96927b925634a62933 F www/sqlite.tcl b51fd15f0531a54874de785a9efba323eecd5975 F www/support.tcl 3955da0fd82be68cc5c83d347c05095e80967051 -F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc +F www/tclsqlite.tcl 425be741b8ae664f55cb1ef2371aab0a75109cf9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b -P e8391491a68018406e30c2a699a4cab9e0de092c -R 0099f7c3586b4b93ff511d85ac21c75e -U drh -Z da8ce3a3ad37d1a0e8ba4a6a000261c8 +P 7e6f688d468099a6e62e405086c9172459d43e3f +R a8cca6db5487eb412a323e0b22bfb314 +U danielk1977 +Z ee96ebc082df4a64e80f84ebea2df6dc diff --git a/manifest.uuid b/manifest.uuid index a44edfba54..c76c1eb5d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7e6f688d468099a6e62e405086c9172459d43e3f \ No newline at end of file +9906ae37b9be684b615a1190cf8798513baa799a \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 5b5edfe6de..f837b56de3 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -11,7 +11,7 @@ ************************************************************************* ** A TCL Interface to SQLite ** -** $Id: tclsqlite.c,v 1.120 2005/03/31 18:26:21 drh Exp $ +** $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 */ @@ -83,6 +83,7 @@ struct SqliteDb { 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() */ @@ -136,6 +137,9 @@ static void DbDeleteCmd(void *db){ if( pDb->zAuth ){ Tcl_Free(pDb->zAuth); } + if( pDb->zNull ){ + Tcl_Free(pDb->zNull); + } Tcl_Free((char*)pDb); } @@ -441,9 +445,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ "changes", "close", "collate", "collation_needed", "commit_hook", "complete", "copy", "errorcode", "eval", - "function", "last_insert_rowid", "onecolumn", - "progress", "rekey", "timeout", - "total_changes", "trace", "version", + "function", "last_insert_rowid", "nullvalue", + "onecolumn", "progress", "rekey", + "timeout", "total_changes", "trace", + "version", 0 }; enum DB_enum { @@ -451,9 +456,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ 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_ONECOLUMN, - DB_PROGRESS, DB_REKEY, DB_TIMEOUT, - DB_TOTAL_CHANGES, DB_TRACE, DB_VERSION + 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 */ @@ -975,6 +981,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ pVal = Tcl_NewDoubleObj(r); break; } + case SQLITE_NULL: { + pVal = dbTextToObj(pDb->zNull); + break; + } default: { pVal = dbTextToObj(sqlite3_column_text(pStmt, i)); break; @@ -1246,6 +1256,37 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ 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 ** diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 1b59de9e4f..69c995254b 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -15,7 +15,7 @@ # 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.38 2005/02/26 17:31:28 drh Exp $ +# $Id: tclsqlite.test,v 1.39 2005/04/03 23:54:45 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -34,7 +34,7 @@ do_test tcl-1.1 { 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, onecolumn, progress, rekey, timeout, total_changes, trace, or version}} +} {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)} @@ -302,4 +302,20 @@ do_test tcl-7.1 { 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 diff --git a/www/tclsqlite.tcl b/www/tclsqlite.tcl index 69e00e8c88..8bb6d7978f 100644 --- a/www/tclsqlite.tcl +++ b/www/tclsqlite.tcl @@ -1,7 +1,7 @@ # # Run this Tcl script to generate the tclsqlite.html file. # -set rcsid {$Id: tclsqlite.tcl,v 1.12 2004/12/17 15:41:13 tpoindex Exp $} +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} { @@ -46,7 +46,7 @@ the database is stored.
Once an SQLite database is open, it can be controlled using -methods of the dbcmd. There are currently 18 methods +methods of the dbcmd. There are currently 19 methods defined:
@@ -66,6 +66,7 @@ foreach m [lsort { eval function last_insert_rowid + nullvalue onecolumn progress timeout @@ -365,6 +366,24 @@ db function hex {format 0x%X} } +############################################################################## +METHOD nullvalue { + +
+The "nullvalue" method changes the representation for NULL returned +as result of the "eval" method.
+ ++db1 nullvalue NULL ++ +
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.
+} + + + ############################################################################## METHOD onecolumn {