aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2018-01-03 19:03:31 +0000
committerdrh <drh@noemail.net>2018-01-03 19:03:31 +0000
commit3ec8665e22a6fe5cf6a2b98c04de1d350d519c8c (patch)
tree089d1b1b514c40d264b89fc9289a3d66d7168889 /src
parentcb7d541d3ae005e24bb0d36bb138d84a3ca3d415 (diff)
downloadsqlite-3ec8665e22a6fe5cf6a2b98c04de1d350d519c8c.tar.gz
sqlite-3ec8665e22a6fe5cf6a2b98c04de1d350d519c8c.zip
Replace sqlite3_memdb_config() with sqlite3_deserialize(). Remove the
"db memdb" command from the TCL interface, replacing it with "db serialize" and "db deserialize". FossilOrigin-Name: 2f6e9df9f0c5a9e5b1acb99cfa9486850cc1822d35b0989e779a7a10f3b1f1ac
Diffstat (limited to 'src')
-rw-r--r--src/attach.c126
-rw-r--r--src/memdb.c99
-rw-r--r--src/sqlite.h.in25
-rw-r--r--src/sqliteInt.h5
-rw-r--r--src/tclsqlite.c138
5 files changed, 187 insertions, 206 deletions
diff --git a/src/attach.c b/src/attach.c
index fa38e8415..151b52e7a 100644
--- a/src/attach.c
+++ b/src/attach.c
@@ -55,6 +55,10 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
**
** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
** third argument.
+**
+** If the db->init.reopenMemdb flags is set, then instead of attaching a
+** new database, close the database on db->init.iDb and reopen it as an
+** empty MemDB.
*/
static void attachFunc(
sqlite3_context *context,
@@ -75,65 +79,79 @@ static void attachFunc(
sqlite3_vfs *pVfs;
UNUSED_PARAMETER(NotUsed);
-
zFile = (const char *)sqlite3_value_text(argv[0]);
zName = (const char *)sqlite3_value_text(argv[1]);
if( zFile==0 ) zFile = "";
if( zName==0 ) zName = "";
- /* Check for the following errors:
- **
- ** * Too many attached databases,
- ** * Transaction currently open
- ** * Specified database name already being used.
- */
- if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
- zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d",
- db->aLimit[SQLITE_LIMIT_ATTACHED]
- );
- goto attach_error;
- }
- for(i=0; i<db->nDb; i++){
- char *z = db->aDb[i].zDbSName;
- assert( z && zName );
- if( sqlite3StrICmp(z, zName)==0 ){
- zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
+ if( db->init.reopenMemdb ){
+ /* This is not a real ATTACH. Instead, this routine is being called
+ ** from sqlite3_deserialize() to close database db->init.iDb and
+ ** reopen it as a MemDB */
+ pVfs = sqlite3_vfs_find("memdb");
+ if( pVfs==0 ) return;
+ pNew = &db->aDb[db->init.iDb];
+ sqlite3BtreeClose(pNew->pBt);
+ pNew->pBt = 0;
+ pNew->pSchema = 0;
+ rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
+ }else{
+ /* This is a real ATTACH */
+
+ /* Check for the following errors:
+ **
+ ** * Too many attached databases,
+ ** * Transaction currently open
+ ** * Specified database name already being used.
+ */
+ if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
+ zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d",
+ db->aLimit[SQLITE_LIMIT_ATTACHED]
+ );
goto attach_error;
}
+ for(i=0; i<db->nDb; i++){
+ char *z = db->aDb[i].zDbSName;
+ assert( z && zName );
+ if( sqlite3StrICmp(z, zName)==0 ){
+ zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
+ goto attach_error;
+ }
+ }
+
+ /* Allocate the new entry in the db->aDb[] array and initialize the schema
+ ** hash tables.
+ */
+ if( db->aDb==db->aDbStatic ){
+ aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
+ if( aNew==0 ) return;
+ memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
+ }else{
+ aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
+ if( aNew==0 ) return;
+ }
+ db->aDb = aNew;
+ pNew = &db->aDb[db->nDb];
+ memset(pNew, 0, sizeof(*pNew));
+
+ /* Open the database file. If the btree is successfully opened, use
+ ** it to obtain the database schema. At this point the schema may
+ ** or may not be initialized.
+ */
+ flags = db->openFlags;
+ rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
+ sqlite3_result_error(context, zErr, -1);
+ sqlite3_free(zErr);
+ return;
+ }
+ assert( pVfs );
+ flags |= SQLITE_OPEN_MAIN_DB;
+ rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
+ sqlite3_free( zPath );
+ db->nDb++;
}
-
- /* Allocate the new entry in the db->aDb[] array and initialize the schema
- ** hash tables.
- */
- if( db->aDb==db->aDbStatic ){
- aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
- if( aNew==0 ) return;
- memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
- }else{
- aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
- if( aNew==0 ) return;
- }
- db->aDb = aNew;
- pNew = &db->aDb[db->nDb];
- memset(pNew, 0, sizeof(*pNew));
-
- /* Open the database file. If the btree is successfully opened, use
- ** it to obtain the database schema. At this point the schema may
- ** or may not be initialized.
- */
- flags = db->openFlags;
- rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
- return;
- }
- assert( pVfs );
- flags |= SQLITE_OPEN_MAIN_DB;
- rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
- sqlite3_free( zPath );
- db->nDb++;
db->skipBtreeMutex = 0;
if( rc==SQLITE_CONSTRAINT ){
rc = SQLITE_ERROR;
@@ -160,7 +178,7 @@ static void attachFunc(
sqlite3BtreeLeave(pNew->pBt);
}
pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
- pNew->zDbSName = sqlite3DbStrDup(db, zName);
+ if( !db->init.reopenMemdb ) pNew->zDbSName = sqlite3DbStrDup(db, zName);
if( rc==SQLITE_OK && pNew->zDbSName==0 ){
rc = SQLITE_NOMEM_BKPT;
}
@@ -200,8 +218,8 @@ static void attachFunc(
/* If the file was opened successfully, read the schema for the new database.
** If this fails, or if opening the file failed, then close the file and
- ** remove the entry from the db->aDb[] array. i.e. put everything back the way
- ** we found it.
+ ** remove the entry from the db->aDb[] array. i.e. put everything back the
+ ** way we found it.
*/
if( rc==SQLITE_OK ){
sqlite3BtreeEnterAll(db);
diff --git a/src/memdb.c b/src/memdb.c
index 0a81978cc..5a1f12dcb 100644
--- a/src/memdb.c
+++ b/src/memdb.c
@@ -12,17 +12,6 @@
**
** This is an in-memory VFS implementation. The application supplies
** a chunk of memory to hold the database file.
-**
-** USAGE:
-**
-** sqlite3_open_v2("whatever", &db, SQLITE_OPEN_READWRITE, "memdb");
-** void *sqlite3_memdb_ptr(db, "main", &sz);
-** int sqlite3_memdb_config(db, "main", pMem, szData, szMem, mFlags);
-**
-** Flags:
-**
-** SQLITE_MEMDB_FREEONCLOSE Free pMem when closing the connection
-** SQLITE_MEMDB_RESIZEABLE Use sqlite3_realloc64() to resize pMem
*/
#ifdef SQLITE_ENABLE_MEMDB
#include "sqliteInt.h"
@@ -141,7 +130,7 @@ static const sqlite3_io_methods memdb_io_methods = {
*/
static int memdbClose(sqlite3_file *pFile){
MemFile *p = (MemFile *)pFile;
- if( p->mFlags & SQLITE_MEMDB_FREEONCLOSE ) sqlite3_free(p->aData);
+ if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData);
return SQLITE_OK;
}
@@ -169,7 +158,7 @@ static int memdbRead(
*/
static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
unsigned char *pNew;
- if( (p->mFlags & SQLITE_MEMDB_RESIZEABLE)==0 ) return SQLITE_FULL;
+ if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 ) return SQLITE_FULL;
if( p->nMmap>0 ) return SQLITE_FULL;
pNew = sqlite3_realloc64(p->aData, newSz);
if( pNew==0 ) return SQLITE_FULL;
@@ -334,7 +323,7 @@ static int memdbOpen(
MemFile *p = (MemFile*)pFile;
memset(p, 0, sizeof(*p));
if( (flags & SQLITE_OPEN_MAIN_DB)==0 ) return SQLITE_CANTOPEN;
- p->mFlags = SQLITE_MEMDB_RESIZEABLE | SQLITE_MEMDB_FREEONCLOSE;
+ p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
*pOutFlags = flags | SQLITE_OPEN_MEMORY;
p->base.pMethods = &memdb_io_methods;
return SQLITE_OK;
@@ -451,37 +440,6 @@ static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
}
/*
-** Reconfigure a memdb database.
-*/
-int sqlite3_memdb_config(
- sqlite3 *db,
- 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;
-}
-
-/*
** Return the serialization of a database
*/
unsigned char *sqlite3_serialize(
@@ -547,6 +505,57 @@ unsigned char *sqlite3_serialize(
return pOut;
}
+/* Convert zSchema to a MemDB and initialize its content.
+*/
+int sqlite3_deserialize(
+ sqlite3 *db, /* The database connection */
+ const char *zSchema, /* Which DB to reopen with the deserialization */
+ unsigned char *pData, /* The serialized database content */
+ sqlite3_int64 szDb, /* Number bytes in the deserialization */
+ sqlite3_int64 szBuf, /* Total size of buffer pData[] */
+ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */
+){
+ MemFile *p;
+ char *zSql;
+ sqlite3_stmt *pStmt = 0;
+ int rc;
+ int iDb;
+
+ sqlite3_mutex_enter(db->mutex);
+ if( zSchema==0 ) zSchema = db->aDb[0].zDbSName;
+ iDb = sqlite3FindDbName(db, zSchema);
+ if( iDb<0 ){
+ rc = SQLITE_ERROR;
+ goto end_deserialize;
+ }
+ zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema);
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
+ sqlite3_free(zSql);
+ if( rc ) goto end_deserialize;
+ db->init.iDb = (u8)iDb;
+ db->init.reopenMemdb = 1;
+ rc = sqlite3_step(pStmt);
+ db->init.reopenMemdb = 0;
+ if( rc!=SQLITE_DONE ){
+ rc = SQLITE_ERROR;
+ goto end_deserialize;
+ }
+ p = memdbFromDbSchema(db, zSchema);
+ if( p==0 ){
+ rc = SQLITE_ERROR;
+ }else{
+ p->aData = pData;
+ p->sz = szDb;
+ p->szMax = szBuf;
+ p->mFlags = mFlags;
+ rc = SQLITE_OK;
+ }
+end_deserialize:
+ sqlite3_finalize(pStmt);
+ sqlite3_mutex_leave(db->mutex);
+ return rc;
+}
+
/*
** This routine is called when the extension is loaded.
** Register the new VFS.
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 6b6a5655b..233a2cf60 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -8759,29 +8759,6 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
/*
-** CAPI3REF: Set the current MEMDB buffer
-** EXPERIMENTAL
-**
-** This interface is only available when SQLite is compiled
-** with SQLITE_ENABLE_MEMDB.
-**
-** The sqlite3_memdb_config(D,S,P,N,M,F) interface initializes a MEMDB database.
-** The database identified by D and S must not be in active use when this
-** interface is called, or [SQLITE_BUSY] is returned.
-*/
-int sqlite3_memdb_config(sqlite3*,const char*,void*,sqlite3_int64,sqlite3_int64,unsigned);
-
-/*
-** CAPI3REF: Flags for configuring MEMDB databases
-** EXPERIMENTAL
-**
-** The following are allowed values for the 6th argument (the "flags"
-** argument) of the [sqlite3_memdb_config()] interface.
-*/
-#define SQLITE_MEMDB_FREEONCLOSE 0x001 /* Free the memory buffer on close */
-#define SQLITE_MEMDB_RESIZEABLE 0x002 /* Resize using sqlite3_realloc64() */
-
-/*
** CAPI3REF: Serialize a database
** EXPERIMENTAL
**
@@ -8829,7 +8806,7 @@ unsigned char *sqlite3_serialize(
#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */
/*
-** CAPI3REF: Set the current MEMDB buffer
+** CAPI3REF: Deserialize a database
** EXPERIMENTAL
**
** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 002fb4e91..35074ee81 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -1365,8 +1365,9 @@ struct sqlite3 {
int newTnum; /* Rootpage of table being initialized */
u8 iDb; /* Which db file is being initialized */
u8 busy; /* TRUE if currently initializing */
- u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
- u8 imposterTable; /* Building an imposter table */
+ u8 orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
+ u8 imposterTable : 1; /* Building an imposter table */
+ u8 reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */
} init;
int nVdbeActive; /* Number of VDBEs currently running */
int nVdbeRead; /* Number of active VDBEs that read or write */
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index 2c6e1bbe2..c9b4ff610 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -1852,14 +1852,14 @@ static int SQLITE_TCLAPI DbObjCmd(
"complete", "copy", "deserialize",
"enable_load_extension", "errorcode", "eval",
"exists", "function", "incrblob",
- "interrupt", "last_insert_rowid", "memdb",
- "nullvalue", "onecolumn", "preupdate",
- "profile", "progress", "rekey",
- "restore", "rollback_hook", "serialize",
- "status", "timeout", "total_changes",
- "trace", "trace_v2", "transaction",
- "unlock_notify", "update_hook", "version",
- "wal_hook", 0
+ "interrupt", "last_insert_rowid", "nullvalue",
+ "onecolumn", "preupdate", "profile",
+ "progress", "rekey", "restore",
+ "rollback_hook", "serialize", "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,
@@ -1868,14 +1868,13 @@ static int SQLITE_TCLAPI DbObjCmd(
DB_COMPLETE, DB_COPY, DB_DESERIALIZE,
DB_ENABLE_LOAD_EXTENSION, DB_ERRORCODE, DB_EVAL,
DB_EXISTS, DB_FUNCTION, DB_INCRBLOB,
- DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_MEMDB,
- DB_NULLVALUE, DB_ONECOLUMN, DB_PREUPDATE,
- DB_PROFILE, DB_PROGRESS, DB_REKEY,
- DB_RESTORE, DB_ROLLBACK_HOOK, DB_SERIALIZE,
- DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
- DB_TRACE, DB_TRACE_V2, DB_TRANSACTION,
- DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION,
- DB_WAL_HOOK
+ DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE,
+ DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE,
+ DB_PROGRESS, DB_REKEY, DB_RESTORE,
+ DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS,
+ DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
+ DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY,
+ DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK
};
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
@@ -2419,7 +2418,44 @@ static int SQLITE_TCLAPI DbObjCmd(
** Reopen DATABASE (default "main") using the content in $VALUE
*/
case DB_DESERIALIZE: {
- rc = TCL_ERROR; /* TBD */
+#ifndef SQLITE_ENABLE_MEMDB
+ Tcl_AppendResult(interp, "MEMDB not available in this build",
+ (char*)0);
+ rc = TCL_ERROR;
+#else
+ const char *zSchema;
+ Tcl_Obj *pValue;
+ unsigned char *pBA;
+ unsigned char *pData;
+ int len, xrc;
+
+ if( objc==3 ){
+ zSchema = 0;
+ pValue = objv[2];
+ }else if( objc==4 ){
+ zSchema = Tcl_GetString(objv[2]);
+ pValue = objv[3];
+ }else{
+ Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE");
+ rc = TCL_ERROR;
+ break;
+ }
+ pBA = Tcl_GetByteArrayFromObj(pValue, &len);
+ pData = sqlite3_malloc64( len );
+ if( pData==0 ){
+ Tcl_AppendResult(interp, "out of memory", (char*)0);
+ rc = TCL_ERROR;
+ }else{
+ memcpy(pData, pBA, len);
+ xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len,
+ SQLITE_DESERIALIZE_FREEONCLOSE |
+ SQLITE_DESERIALIZE_RESIZEABLE);
+ if( xrc ){
+ Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0);
+ rc = TCL_ERROR;
+ }
+ }
+#endif
break;
}
@@ -2679,44 +2715,6 @@ static int SQLITE_TCLAPI DbObjCmd(
}
/*
- ** $db memdb DATABASE ?BLOB?
- **
- ** Set or query the content of a MEMDB database.
- **
- */
- case DB_MEMDB: {
-#ifndef SQLITE_ENABLE_MEMDB
- Tcl_AppendResult(interp, "MEMDB not available in this build",
- (char*)0);
- rc = TCL_ERROR;
-#else
- const char *zSchema = Tcl_GetString(objv[2]);
- unsigned char *pData;
- if( objc==4 ){
- int len = 0, xrc;
- unsigned char *pBA = Tcl_GetByteArrayFromObj(objv[3], &len);
- pData = sqlite3_malloc64( len );
- if( pData==0 ){
- 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;
- }
-#endif
- break;
- }
-
- /*
** $db nullvalue ?STRING?
**
** Change text used when a NULL comes back from the database. If ?STRING?
@@ -3481,9 +3479,6 @@ 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 off mutexing on SQLite database connections.
@@ -3576,10 +3571,6 @@ static int SQLITE_TCLAPI DbMain(
}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;
@@ -3588,25 +3579,10 @@ static int SQLITE_TCLAPI DbMain(
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( zFile==0 ) zFile = "";
+ 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));