Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | 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. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | memdb |
Files: | files | file ages | folders |
SHA3-256: |
47398ae77236a92f6b9345aa397361b6 |
User & Date: | drh 2018-01-03 13:20:02.897 |
Context
2018-01-03
| ||
16:49 | Replace the sqlite3_memdb_ptr() interface with the more general sqlite3_serialize() interface. (check-in: 8cf2ed4eff user: drh tags: memdb) | |
13:20 | 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. (check-in: 47398ae772 user: drh tags: memdb) | |
12:39 | Fix typo in the Makefile for MSVC. (check-in: e5c6ade8ee user: mistachkin tags: memdb) | |
Changes
Changes to src/memdb.c.
︙ | ︙ | |||
471 472 473 474 475 476 477 | const char *zSchema, void *aData, sqlite3_int64 sz, sqlite3_int64 szMax, unsigned int mFlags ){ MemFile *p = memdbFromDbSchema(db, zSchema); | > | > | > > | | | | | > > > > > | 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | const char *zSchema, void *aData, sqlite3_int64 sz, sqlite3_int64 szMax, unsigned int mFlags ){ MemFile *p = memdbFromDbSchema(db, zSchema); int rc; if( p==0 ){ rc = SQLITE_ERROR; }else if( p->eLock!=SQLITE_LOCK_NONE || p->nMmap>0 ){ rc = SQLITE_BUSY; }else{ 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; } /* ** This routine is called when the extension is loaded. ** Register the new VFS. */ |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
1852 1853 1854 1855 1856 1857 1858 | "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", | | | 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 | "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", "wal_hook", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BACKUP, DB_BUSY, DB_CACHE, DB_CHANGES, DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK, |
︙ | ︙ | |||
2697 2698 2699 2700 2701 2702 2703 | Tcl_AppendResult(interp, "out of memory", (char*)0); rc = TCL_ERROR; }else{ memcpy(pData, pBA, len); xrc = sqlite3_memdb_config(pDb->db, zSchema, pData, len, len, SQLITE_MEMDB_FREEONCLOSE|SQLITE_MEMDB_RESIZEABLE); if( xrc ){ | < | 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 | Tcl_AppendResult(interp, "out of memory", (char*)0); rc = TCL_ERROR; }else{ memcpy(pData, pBA, len); xrc = sqlite3_memdb_config(pDb->db, zSchema, pData, len, len, SQLITE_MEMDB_FREEONCLOSE|SQLITE_MEMDB_RESIZEABLE); if( xrc ){ Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0); rc = TCL_ERROR; } } }else{ Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); rc = TCL_ERROR; |
︙ | ︙ | |||
3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 | Tcl_Interp *interp, int objc, Tcl_Obj *const*objv ){ return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv); } #endif /* SQLITE_TCL_NRE */ /* ** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN? ** ?-create BOOLEAN? ?-nomutex BOOLEAN? ** ** This is the main Tcl command. When the "sqlite" Tcl command is ** invoked, this routine runs to process that command. | > > > > > > > > > > > > > > > > > > | 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 | Tcl_Interp *interp, int objc, Tcl_Obj *const*objv ){ return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv); } #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? ** ** This is the main Tcl command. When the "sqlite" Tcl command is ** invoked, this routine runs to process that command. |
︙ | ︙ | |||
3415 3416 3417 3418 3419 3420 3421 | int objc, Tcl_Obj *const*objv ){ SqliteDb *p; const char *zArg; char *zErrMsg; int i; | | > > > | | 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 | int objc, Tcl_Obj *const*objv ){ SqliteDb *p; const char *zArg; char *zErrMsg; int i; const char *zFile = 0; const char *zVfs = 0; int flags; Tcl_DString translatedFilename; #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) void *pKey = 0; 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 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. */ #ifdef SQLITE_TCL_DEFAULT_FULLMUTEX flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX; #else |
︙ | ︙ | |||
3455 3456 3457 3458 3459 3460 3461 3462 | #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) Tcl_AppendResult(interp,"1",(char*)0); #else Tcl_AppendResult(interp,"0",(char*)0); #endif return TCL_OK; } } | > | > > > > > > > | | | | | | | > > > > < < < < < < < < < < > > > > > > > > > > > > > > | | | | > | 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 | #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) Tcl_AppendResult(interp,"1",(char*)0); #else Tcl_AppendResult(interp,"0",(char*)0); #endif return TCL_OK; } if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv); } 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], &nKey); #endif }else if( strcmp(zArg, "-vfs")==0 ){ zVfs = Tcl_GetString(objv[i]); }else if( strcmp(zArg, "-readonly")==0 ){ int b; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; if( b ){ flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); flags |= SQLITE_OPEN_READONLY; }else{ flags &= ~SQLITE_OPEN_READONLY; flags |= SQLITE_OPEN_READWRITE; } }else if( strcmp(zArg, "-create")==0 ){ int b; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; if( b && (flags & SQLITE_OPEN_READONLY)==0 ){ flags |= SQLITE_OPEN_CREATE; }else{ flags &= ~SQLITE_OPEN_CREATE; } }else if( strcmp(zArg, "-nomutex")==0 ){ int b; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; if( b ){ flags |= SQLITE_OPEN_NOMUTEX; flags &= ~SQLITE_OPEN_FULLMUTEX; }else{ flags &= ~SQLITE_OPEN_NOMUTEX; } }else if( strcmp(zArg, "-fullmutex")==0 ){ int b; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; if( b ){ flags |= SQLITE_OPEN_FULLMUTEX; flags &= ~SQLITE_OPEN_NOMUTEX; }else{ flags &= ~SQLITE_OPEN_FULLMUTEX; } }else if( strcmp(zArg, "-uri")==0 ){ int b; 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; } } zErrMsg = 0; p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); memset(p, 0, sizeof(*p)); #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)); sqlite3_close(p->db); p->db = 0; } }else{ |
︙ | ︙ |
Changes to test/memdb1.test.
︙ | ︙ | |||
43 44 45 46 47 48 49 | expr {[string length $::db1]==$::sz1} } 1 # Create a new MEMDB and initialize it to the content of $::db1 # Verify that the content is the same. # db close | | < | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | expr {[string length $::db1]==$::sz1} } 1 # Create a new MEMDB and initialize it to the content of $::db1 # Verify that the content is the same. # db close sqlite3 db -memdb $db1 do_execsql_test 110 { SELECT * FROM t1; } {1 2} finish_test |
Changes to test/tclsqlite.test.
︙ | ︙ | |||
18 19 20 21 22 23 24 | # $Id: tclsqlite.test,v 1.73 2009/03/16 13:19:36 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Check the error messages generated by tclsqlite # | | | | | 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 | # $Id: tclsqlite.test,v 1.73 2009/03/16 13:19:36 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # 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?" if {[sqlite3 -has-codec]} { append r " ?-key CODECKEY?" } do_test tcl-1.1 { set v [catch {sqlite3 -bogus} msg] regsub {really_sqlite3} $msg {sqlite3} 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, 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 { set v [catch {db cache bogus} msg] lappend v $msg } {1 {bad option "bogus": must be flush or size}} do_test tcl-1.2.2 { set v [catch {db cache} msg] lappend v $msg |
︙ | ︙ |