diff options
author | drh <drh@noemail.net> | 2018-01-03 13:20:02 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2018-01-03 13:20:02 +0000 |
commit | 4dcac40e3d4cf02513c84c95ccd4198ef35f2320 (patch) | |
tree | 0831633ddaf0baefe2be084b928643b30bed4b2e /src/tclsqlite.c | |
parent | 7de2c3e5eee332de01158b6f99bb71af86e28de5 (diff) | |
download | sqlite-4dcac40e3d4cf02513c84c95ccd4198ef35f2320.tar.gz sqlite-4dcac40e3d4cf02513c84c95ccd4198ef35f2320.zip |
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
Diffstat (limited to 'src/tclsqlite.c')
-rw-r--r-- | src/tclsqlite.c | 89 |
1 files changed, 63 insertions, 26 deletions
diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 0e86d727b..d02d94baf 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1856,7 +1856,7 @@ static int SQLITE_TCLAPI DbObjCmd( "onecolumn", "preupdate", "profile", "progress", "rekey", "restore", "rollback_hook", "status", "timeout", - "total_changes", "trace", "trace_v", + "total_changes", "trace", "trace_v2", "transaction", "unlock_notify", "update_hook", "version", "wal_hook", 0 }; @@ -2701,7 +2701,6 @@ static int SQLITE_TCLAPI DbObjCmd( xrc = sqlite3_memdb_config(pDb->db, zSchema, pData, len, len, SQLITE_MEMDB_FREEONCLOSE|SQLITE_MEMDB_RESIZEABLE); if( xrc ){ - sqlite3_free(pData); Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0); rc = TCL_ERROR; } @@ -3395,6 +3394,24 @@ static int SQLITE_TCLAPI DbObjCmdAdaptor( #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? ** ?-create BOOLEAN? ?-nomutex BOOLEAN? ** @@ -3419,7 +3436,7 @@ static int SQLITE_TCLAPI DbMain( const char *zArg; char *zErrMsg; int i; - const char *zFile; + const char *zFile = 0; const char *zVfs = 0; int flags; Tcl_DString translatedFilename; @@ -3428,9 +3445,12 @@ static int SQLITE_TCLAPI DbMain( int nKey = 0; #endif int rc; +#ifdef SQLITE_ENABLE_MEMDB + Tcl_Obj *pDbObj = 0; +#endif /* 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 ** on. So, by default, mutexes default off. But if compiled with ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on. @@ -3459,18 +3479,26 @@ static int SQLITE_TCLAPI DbMain( #endif 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]); + 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 defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) - pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey); + pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey); #endif }else if( strcmp(zArg, "-vfs")==0 ){ - zVfs = Tcl_GetString(objv[i+1]); + zVfs = Tcl_GetString(objv[i]); }else if( strcmp(zArg, "-readonly")==0 ){ 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_READWRITE|SQLITE_OPEN_CREATE); flags |= SQLITE_OPEN_READONLY; @@ -3480,7 +3508,7 @@ static int SQLITE_TCLAPI DbMain( } }else if( strcmp(zArg, "-create")==0 ){ 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 ){ flags |= SQLITE_OPEN_CREATE; }else{ @@ -3488,7 +3516,7 @@ static int SQLITE_TCLAPI DbMain( } }else if( strcmp(zArg, "-nomutex")==0 ){ 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_NOMUTEX; flags &= ~SQLITE_OPEN_FULLMUTEX; @@ -3497,7 +3525,7 @@ static int SQLITE_TCLAPI DbMain( } }else if( strcmp(zArg, "-fullmutex")==0 ){ 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_FULLMUTEX; flags &= ~SQLITE_OPEN_NOMUTEX; @@ -3506,34 +3534,43 @@ static int SQLITE_TCLAPI DbMain( } }else if( strcmp(zArg, "-uri")==0 ){ 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_URI; }else{ flags &= ~SQLITE_OPEN_URI; } +#ifdef SQLITE_ENABLE_MEMDB + }else if( strcmp(zArg, "-memdb")==0 ){ + pDbObj = objv[i]; +#endif }else{ Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); 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; p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); memset(p, 0, sizeof(*p)); - zFile = Tcl_GetStringFromObj(objv[2], 0); - zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); - rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs); - Tcl_DStringFree(&translatedFilename); +#ifdef SQLITE_ENABLE_MEMDB + if( pDbObj ){ + rc = sqlite3_open_v2("x", &p->db, flags, "memdb"); + 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( SQLITE_OK!=sqlite3_errcode(p->db) ){ zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); |