Simplify the "sqlite3" command in the TCL interface. The filename is now

optional.  There is a new --memdb option with an argument that is the blob
to which the database content should be initialized.

FossilOrigin-Name: 47398ae77236a92f6b9345aa397361b6df127a9a2895c0771d506b0be10822b9
This commit is contained in:
drh 2018-01-03 13:20:02 +00:00
parent 7de2c3e5ee
commit 4dcac40e3d
6 changed files with 94 additions and 49 deletions

View File

@ -1,5 +1,5 @@
C Fix\stypo\sin\sthe\sMakefile\sfor\sMSVC. C Simplify\sthe\s"sqlite3"\scommand\sin\sthe\sTCL\sinterface.\s\sThe\sfilename\sis\snow\noptional.\s\sThere\sis\sa\snew\s--memdb\soption\swith\san\sargument\sthat\sis\sthe\sblob\nto\swhich\sthe\sdatabase\scontent\sshould\sbe\sinitialized.
D 2018-01-03T12:39:35.460 D 2018-01-03T13:20:02.897
F Makefile.in 892bf253c48f3d2d8d4e4e89b44b71aa548a0eba11b148c338690cfb99822859 F Makefile.in 892bf253c48f3d2d8d4e4e89b44b71aa548a0eba11b148c338690cfb99822859
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 3b7ee2ebaf579fe7d30bece93e61e52782c3ff836455cba3a192f7a8f6f269d6 F Makefile.msc 3b7ee2ebaf579fe7d30bece93e61e52782c3ff836455cba3a192f7a8f6f269d6
@ -450,7 +450,7 @@ F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
F src/memdb.c 46109bc6c890c21a802b6aad6e667c81aee53e5623e2068c6fa9ded1b9634558 F src/memdb.c 13c69aee0185614a25303e2be3802b73416e655e95e1f1c607a9f963b35a1def
F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661 F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661
F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81 F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81
F src/mutex.c b021263554c8a3995e9d53193b8194b96d1ed28e06c3b532dd7f7d29cf0c7d53 F src/mutex.c b021263554c8a3995e9d53193b8194b96d1ed28e06c3b532dd7f7d29cf0c7d53
@ -488,7 +488,7 @@ F src/sqliteInt.h 2567341e37050ad542d57f3027b8717cb9b14ff363fdfeecf85421e0d97378
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35 F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/tclsqlite.c 45bcce558f40f245e25d1dd7c208f6845137fbee042cced2a4116f05349ffd9d F src/tclsqlite.c 907133153d3194ddfd728e84f55fa106de696dc644c9508a054c72b9f833972e
F src/test1.c 8ef15f7a357f85dfc41c6c748ce9c947b4f676e01bb5ae6a45bee4923dff8b51 F src/test1.c 8ef15f7a357f85dfc41c6c748ce9c947b4f676e01bb5ae6a45bee4923dff8b51
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
@ -1056,7 +1056,7 @@ F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7 F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
F test/memdb1.test 3d8ebffdc64ea1a7b4ccacd5502e61191233d979451747f4af88c9f2ee9b34c5 F test/memdb1.test 1d94a4bf153201f16a0a755a5a0a5d7f33b001c972e3086acb1f76ad3fb7e0e5
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e
F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08 F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
@ -1282,7 +1282,7 @@ F test/tabfunc01.test c47171c36b3d411df2bd49719dcaa5d034f8d277477fd41d253940723b
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
F test/tclsqlite.test c3d7ac9449634b9f17fd048a3c0212e88a7448be810a9c5bd051acc1ffa00d2f F test/tclsqlite.test 45462ee8dd0ca4fd95a476c9253d332ce2cf90985cb0ad5c7eae6e8c7fe24ae8
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
F test/tempdb2.test 27e41ed540b2f9b056c2e77e9bddc1b875358507 F test/tempdb2.test 27e41ed540b2f9b056c2e77e9bddc1b875358507
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
@ -1690,7 +1690,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P fb2ac2d2fa6374084f3325b41b257c7a3ace43aade4b666ec4be93b6b70dc39a P e5c6ade8ee596eaffd98d1d7ce9c7c968cd2d45f206603b894026e7ad7ac15b6
R 025ad5693b1eb347e4b6ac2d4f7892d8 R 66054801a2fc399d3dc7a916643e1819
U mistachkin U drh
Z 11bcd34cb283c66a6b2991d9a37cef7f Z 2a01cfd70faa22757159c69df08c3c76

View File

@ -1 +1 @@
e5c6ade8ee596eaffd98d1d7ce9c7c968cd2d45f206603b894026e7ad7ac15b6 47398ae77236a92f6b9345aa397361b6df127a9a2895c0771d506b0be10822b9

View File

@ -475,13 +475,22 @@ int sqlite3_memdb_config(
unsigned int mFlags unsigned int mFlags
){ ){
MemFile *p = memdbFromDbSchema(db, zSchema); MemFile *p = memdbFromDbSchema(db, zSchema);
if( p==0 ) return SQLITE_ERROR; int rc;
if( p->eLock!=SQLITE_LOCK_NONE || p->nMmap>0 ) return SQLITE_BUSY; if( p==0 ){
if( p->mFlags & SQLITE_MEMDB_FREEONCLOSE ) sqlite3_free(p->aData); rc = SQLITE_ERROR;
p->aData = aData; }else if( p->eLock!=SQLITE_LOCK_NONE || p->nMmap>0 ){
p->sz = sz; rc = SQLITE_BUSY;
p->szMax = szMax; }else{
p->mFlags = mFlags; if( p->mFlags & SQLITE_MEMDB_FREEONCLOSE ) sqlite3_free(p->aData);
p->aData = aData;
p->sz = sz;
p->szMax = szMax;
p->mFlags = mFlags;
rc = SQLITE_OK;
}
if( rc!=SQLITE_OK && (mFlags & SQLITE_MEMDB_FREEONCLOSE)!=0 ){
sqlite3_free(aData);
}
return SQLITE_OK; return SQLITE_OK;
} }

View File

@ -1856,7 +1856,7 @@ static int SQLITE_TCLAPI DbObjCmd(
"onecolumn", "preupdate", "profile", "onecolumn", "preupdate", "profile",
"progress", "rekey", "restore", "progress", "rekey", "restore",
"rollback_hook", "status", "timeout", "rollback_hook", "status", "timeout",
"total_changes", "trace", "trace_v", "total_changes", "trace", "trace_v2",
"transaction", "unlock_notify", "update_hook", "transaction", "unlock_notify", "update_hook",
"version", "wal_hook", 0 "version", "wal_hook", 0
}; };
@ -2701,7 +2701,6 @@ static int SQLITE_TCLAPI DbObjCmd(
xrc = sqlite3_memdb_config(pDb->db, zSchema, pData, len, len, xrc = sqlite3_memdb_config(pDb->db, zSchema, pData, len, len,
SQLITE_MEMDB_FREEONCLOSE|SQLITE_MEMDB_RESIZEABLE); SQLITE_MEMDB_FREEONCLOSE|SQLITE_MEMDB_RESIZEABLE);
if( xrc ){ if( xrc ){
sqlite3_free(pData);
Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0); Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0);
rc = TCL_ERROR; rc = TCL_ERROR;
} }
@ -3394,6 +3393,24 @@ static int SQLITE_TCLAPI DbObjCmdAdaptor(
} }
#endif /* SQLITE_TCL_NRE */ #endif /* SQLITE_TCL_NRE */
/*
** Issue the usage message when the "sqlite3" command arguments are
** incorrect.
*/
static int sqliteCmdUsage(
Tcl_Interp *interp,
Tcl_Obj *const*objv
){
Tcl_WrongNumArgs(interp, 1, objv,
"HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
" ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
" ?-key CODECKEY?"
#endif
);
return TCL_ERROR;
}
/* /*
** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN? ** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
** ?-create BOOLEAN? ?-nomutex BOOLEAN? ** ?-create BOOLEAN? ?-nomutex BOOLEAN?
@ -3419,7 +3436,7 @@ static int SQLITE_TCLAPI DbMain(
const char *zArg; const char *zArg;
char *zErrMsg; char *zErrMsg;
int i; int i;
const char *zFile; const char *zFile = 0;
const char *zVfs = 0; const char *zVfs = 0;
int flags; int flags;
Tcl_DString translatedFilename; Tcl_DString translatedFilename;
@ -3428,9 +3445,12 @@ static int SQLITE_TCLAPI DbMain(
int nKey = 0; int nKey = 0;
#endif #endif
int rc; int rc;
#ifdef SQLITE_ENABLE_MEMDB
Tcl_Obj *pDbObj = 0;
#endif
/* In normal use, each TCL interpreter runs in a single thread. So /* In normal use, each TCL interpreter runs in a single thread. So
** by default, we can turn of mutexing on SQLite database connections. ** by default, we can turn off mutexing on SQLite database connections.
** However, for testing purposes it is useful to have mutexes turned ** However, for testing purposes it is useful to have mutexes turned
** on. So, by default, mutexes default off. But if compiled with ** on. So, by default, mutexes default off. But if compiled with
** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on. ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
@ -3459,18 +3479,26 @@ static int SQLITE_TCLAPI DbMain(
#endif #endif
return TCL_OK; return TCL_OK;
} }
if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv);
} }
for(i=3; i+1<objc; i+=2){ for(i=2; i<objc; i++){
zArg = Tcl_GetString(objv[i]); zArg = Tcl_GetString(objv[i]);
if( zArg[0]!='-' ){
if( zFile!=0 ) return sqliteCmdUsage(interp, objv);
zFile = zArg;
continue;
}
if( i==objc-1 ) return sqliteCmdUsage(interp, objv);
i++;
if( strcmp(zArg,"-key")==0 ){ if( strcmp(zArg,"-key")==0 ){
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey); pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey);
#endif #endif
}else if( strcmp(zArg, "-vfs")==0 ){ }else if( strcmp(zArg, "-vfs")==0 ){
zVfs = Tcl_GetString(objv[i+1]); zVfs = Tcl_GetString(objv[i]);
}else if( strcmp(zArg, "-readonly")==0 ){ }else if( strcmp(zArg, "-readonly")==0 ){
int b; int b;
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){ if( b ){
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
flags |= SQLITE_OPEN_READONLY; flags |= SQLITE_OPEN_READONLY;
@ -3480,7 +3508,7 @@ static int SQLITE_TCLAPI DbMain(
} }
}else if( strcmp(zArg, "-create")==0 ){ }else if( strcmp(zArg, "-create")==0 ){
int b; int b;
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b && (flags & SQLITE_OPEN_READONLY)==0 ){ if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
flags |= SQLITE_OPEN_CREATE; flags |= SQLITE_OPEN_CREATE;
}else{ }else{
@ -3488,7 +3516,7 @@ static int SQLITE_TCLAPI DbMain(
} }
}else if( strcmp(zArg, "-nomutex")==0 ){ }else if( strcmp(zArg, "-nomutex")==0 ){
int b; int b;
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){ if( b ){
flags |= SQLITE_OPEN_NOMUTEX; flags |= SQLITE_OPEN_NOMUTEX;
flags &= ~SQLITE_OPEN_FULLMUTEX; flags &= ~SQLITE_OPEN_FULLMUTEX;
@ -3497,7 +3525,7 @@ static int SQLITE_TCLAPI DbMain(
} }
}else if( strcmp(zArg, "-fullmutex")==0 ){ }else if( strcmp(zArg, "-fullmutex")==0 ){
int b; int b;
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){ if( b ){
flags |= SQLITE_OPEN_FULLMUTEX; flags |= SQLITE_OPEN_FULLMUTEX;
flags &= ~SQLITE_OPEN_NOMUTEX; flags &= ~SQLITE_OPEN_NOMUTEX;
@ -3506,34 +3534,43 @@ static int SQLITE_TCLAPI DbMain(
} }
}else if( strcmp(zArg, "-uri")==0 ){ }else if( strcmp(zArg, "-uri")==0 ){
int b; int b;
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR;
if( b ){ if( b ){
flags |= SQLITE_OPEN_URI; flags |= SQLITE_OPEN_URI;
}else{ }else{
flags &= ~SQLITE_OPEN_URI; flags &= ~SQLITE_OPEN_URI;
} }
#ifdef SQLITE_ENABLE_MEMDB
}else if( strcmp(zArg, "-memdb")==0 ){
pDbObj = objv[i];
#endif
}else{ }else{
Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
return TCL_ERROR; return TCL_ERROR;
} }
} }
if( objc<3 || (objc&1)!=1 ){
Tcl_WrongNumArgs(interp, 1, objv,
"HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
" ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
" ?-key CODECKEY?"
#endif
);
return TCL_ERROR;
}
zErrMsg = 0; zErrMsg = 0;
p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
memset(p, 0, sizeof(*p)); memset(p, 0, sizeof(*p));
zFile = Tcl_GetStringFromObj(objv[2], 0); #ifdef SQLITE_ENABLE_MEMDB
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); if( pDbObj ){
rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs); rc = sqlite3_open_v2("x", &p->db, flags, "memdb");
Tcl_DStringFree(&translatedFilename); if( rc==SQLITE_OK ){
int len;
unsigned char *aData = Tcl_GetByteArrayFromObj(pDbObj, &len);
unsigned char *a = sqlite3_malloc64( len );
memcpy(a, aData, len);
sqlite3_memdb_config(p->db, "main", a, len, sqlite3_msize(a),
SQLITE_MEMDB_FREEONCLOSE | SQLITE_MEMDB_RESIZEABLE);
}
}else
#endif
{
if( zFile==0 ) zFile = ":memory:";
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
Tcl_DStringFree(&translatedFilename);
}
if( p->db ){ if( p->db ){
if( SQLITE_OK!=sqlite3_errcode(p->db) ){ if( SQLITE_OK!=sqlite3_errcode(p->db) ){
zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));

View File

@ -47,8 +47,7 @@ do_test 100 {
# Verify that the content is the same. # Verify that the content is the same.
# #
db close db close
sqlite3 db dummy2 -vfs memdb sqlite3 db -memdb $db1
db memdb main $db1
do_execsql_test 110 { do_execsql_test 110 {
SELECT * FROM t1; SELECT * FROM t1;
} {1 2} } {1 2}

View File

@ -22,19 +22,19 @@ source $testdir/tester.tcl
# Check the error messages generated by tclsqlite # Check the error messages generated by tclsqlite
# #
set r "sqlite_orig HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" set r "sqlite_orig HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
if {[sqlite3 -has-codec]} { if {[sqlite3 -has-codec]} {
append r " ?-key CODECKEY?" append r " ?-key CODECKEY?"
} }
do_test tcl-1.1 { do_test tcl-1.1 {
set v [catch {sqlite3 bogus} msg] set v [catch {sqlite3 -bogus} msg]
regsub {really_sqlite3} $msg {sqlite3} msg regsub {really_sqlite3} $msg {sqlite3} msg
lappend v $msg lappend v $msg
} [list 1 "wrong # args: should be \"$r\""] } [list 1 "wrong # args: should be \"$r\""]
do_test tcl-1.2 { do_test tcl-1.2 {
set v [catch {db bogus} msg] set v [catch {db bogus} msg]
lappend v $msg lappend v $msg
} {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}} } {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, memdb, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}}
do_test tcl-1.2.1 { do_test tcl-1.2.1 {
set v [catch {db cache bogus} msg] set v [catch {db cache bogus} msg]
lappend v $msg lappend v $msg