1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

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

@@ -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;
}
@@ -3394,6 +3393,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));