Replace the sqlite3_memdb_ptr() interface with the more general
sqlite3_serialize() interface. FossilOrigin-Name: 8cf2ed4eff6d2e0958656e23384b05ead2128b678b0b69a591878af4190cd077
This commit is contained in:
parent
4dcac40e3d
commit
cb7d541d3a
20
manifest
20
manifest
@ -1,5 +1,5 @@
|
||||
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-03T13:20:02.897
|
||||
C Replace\sthe\ssqlite3_memdb_ptr()\sinterface\swith\sthe\smore\sgeneral\nsqlite3_serialize()\sinterface.
|
||||
D 2018-01-03T16:49:52.676
|
||||
F Makefile.in 892bf253c48f3d2d8d4e4e89b44b71aa548a0eba11b148c338690cfb99822859
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 3b7ee2ebaf579fe7d30bece93e61e52782c3ff836455cba3a192f7a8f6f269d6
|
||||
@ -450,7 +450,7 @@ F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
|
||||
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
|
||||
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
|
||||
F src/memdb.c 13c69aee0185614a25303e2be3802b73416e655e95e1f1c607a9f963b35a1def
|
||||
F src/memdb.c 39dd9443f902759b858e598f17afc425c094b0d5f057b7ec988d224d812bd2a3
|
||||
F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661
|
||||
F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81
|
||||
F src/mutex.c b021263554c8a3995e9d53193b8194b96d1ed28e06c3b532dd7f7d29cf0c7d53
|
||||
@ -481,14 +481,14 @@ F src/resolve.c bbee7e31d369a18a2f4836644769882e9c5d40ef4a3af911db06410b65cb3730
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 8b22abe193e4d8243befa2038e4ae2405802fed1c446e5e502d11f652e09ba74
|
||||
F src/shell.c.in a418ddceef7a2789f18bdc2bcdd481b2562fe4a7754b8009c8dd33d5a67da332
|
||||
F src/sqlite.h.in 8b6cd7fd8b286d567bcc1ee3a750686cbb1c0962dc453b2cfa034684fe5808db
|
||||
F src/sqlite.h.in 16bbb15a5fc53bfd725305ec9a201a7f57df7770749aa758b33a0636946d1bb4
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34
|
||||
F src/sqliteInt.h 2567341e37050ad542d57f3027b8717cb9b14ff363fdfeecf85421e0d973787f
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
F src/tclsqlite.c 907133153d3194ddfd728e84f55fa106de696dc644c9508a054c72b9f833972e
|
||||
F src/tclsqlite.c 322ad6b4e613aba84eee8cf6239eae668167f8b9891ca9e4aa53b78cd3aaff35
|
||||
F src/test1.c 8ef15f7a357f85dfc41c6c748ce9c947b4f676e01bb5ae6a45bee4923dff8b51
|
||||
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
|
||||
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
|
||||
@ -1056,7 +1056,7 @@ F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f
|
||||
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
|
||||
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
|
||||
F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
|
||||
F test/memdb1.test 1d94a4bf153201f16a0a755a5a0a5d7f33b001c972e3086acb1f76ad3fb7e0e5
|
||||
F test/memdb1.test 062cdf3b7de2f861878e4275d3a67b80982d9f792f693418c844fade15ec7537
|
||||
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
|
||||
F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e
|
||||
F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
|
||||
@ -1624,7 +1624,7 @@ F tool/mkkeywordhash.c 2e852ac0dfdc5af18886dc1ce7e9676d11714ae3df0a282dc7d90b3a0
|
||||
F tool/mkmsvcmin.tcl 8baf26690b80d861d0ac341b29880eec6ade39e4f11fe690271ded9cb90563a3
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl 4ee2a30ccbd900dc4d5cdb61bdab87cd2166cd2affcc78c9cc0b8d22a65b2eee
|
||||
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
|
||||
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
|
||||
F tool/mkpragmatab.tcl 2144bc8550a6471a029db262a132d2df4b9e0db61b90398bf64f5b7b3f8d92cd
|
||||
F tool/mkshellc.tcl 574307265b49d813301fba91ccd74e6a26d33f65f74b6891c320a0ffbee07895
|
||||
F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b
|
||||
@ -1690,7 +1690,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P e5c6ade8ee596eaffd98d1d7ce9c7c968cd2d45f206603b894026e7ad7ac15b6
|
||||
R 66054801a2fc399d3dc7a916643e1819
|
||||
P 47398ae77236a92f6b9345aa397361b6df127a9a2895c0771d506b0be10822b9
|
||||
R bfc121db68c7d1b10b977a508d74da37
|
||||
U drh
|
||||
Z 2a01cfd70faa22757159c69df08c3c76
|
||||
Z 6064e9ffbc398d82aebface075258c56
|
||||
|
@ -1 +1 @@
|
||||
47398ae77236a92f6b9345aa397361b6df127a9a2895c0771d506b0be10822b9
|
||||
8cf2ed4eff6d2e0958656e23384b05ead2128b678b0b69a591878af4190cd077
|
81
src/memdb.c
81
src/memdb.c
@ -157,6 +157,7 @@ static int memdbRead(
|
||||
MemFile *p = (MemFile *)pFile;
|
||||
if( iOfst+iAmt>p->sz ){
|
||||
memset(zBuf, 0, iAmt);
|
||||
if( iOfst<p->sz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst);
|
||||
return SQLITE_IOERR_SHORT_READ;
|
||||
}
|
||||
memcpy(zBuf, p->aData+iOfst, iAmt);
|
||||
@ -449,20 +450,6 @@ static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a pointer to the memory used to hold the database.
|
||||
** Return NULL if the arguments do not describe a memdb database.
|
||||
*/
|
||||
void *sqlite3_memdb_ptr(sqlite3 *db, const char *zSchema, sqlite3_int64 *pSz){
|
||||
MemFile *p = memdbFromDbSchema(db, zSchema);
|
||||
if( p==0 ){
|
||||
*pSz = 0;
|
||||
return 0;
|
||||
}
|
||||
*pSz = p->sz;
|
||||
return p->aData;
|
||||
}
|
||||
|
||||
/*
|
||||
** Reconfigure a memdb database.
|
||||
*/
|
||||
@ -494,6 +481,72 @@ int sqlite3_memdb_config(
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the serialization of a database
|
||||
*/
|
||||
unsigned char *sqlite3_serialize(
|
||||
sqlite3 *db, /* The database connection */
|
||||
const char *zSchema, /* Which database within the connection */
|
||||
sqlite3_int64 *piSize, /* Write size here, if not NULL */
|
||||
unsigned int mFlags /* Maybe SQLITE_SERIALIZE_NOCOPY */
|
||||
){
|
||||
MemFile *p = memdbFromDbSchema(db, zSchema);
|
||||
int iDb = sqlite3FindDbName(db, zSchema);
|
||||
Btree *pBt;
|
||||
sqlite3_int64 sz;
|
||||
int szPage = 0;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
unsigned char *pOut;
|
||||
char *zSql;
|
||||
int rc;
|
||||
|
||||
if( piSize ) *piSize = -1;
|
||||
if( iDb<0 ) return 0;
|
||||
if( p ){
|
||||
if( piSize ) *piSize = p->sz;
|
||||
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
|
||||
pOut = p->aData;
|
||||
}else{
|
||||
pOut = sqlite3_malloc64( p->sz );
|
||||
if( pOut ) memcpy(pOut, p->aData, p->sz);
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
pBt = db->aDb[iDb].pBt;
|
||||
if( pBt==0 ) return 0;
|
||||
szPage = sqlite3BtreeGetPageSize(pBt);
|
||||
zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema);
|
||||
rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM;
|
||||
sqlite3_free(zSql);
|
||||
if( rc ) return 0;
|
||||
sqlite3_step(pStmt);
|
||||
sz = sqlite3_column_int64(pStmt, 0)*szPage;
|
||||
if( piSize ) *piSize = sz;
|
||||
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
|
||||
pOut = 0;
|
||||
}else{
|
||||
pOut = sqlite3_malloc64( sz );
|
||||
if( pOut ){
|
||||
int nPage = sqlite3_column_int(pStmt, 0);
|
||||
Pager *pPager = sqlite3BtreePager(pBt);
|
||||
int pgno;
|
||||
for(pgno=1; pgno<=nPage; pgno++){
|
||||
DbPage *pPage = 0;
|
||||
unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1);
|
||||
rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
memcpy(pTo, sqlite3PagerGetData(pPage), szPage);
|
||||
}else{
|
||||
memset(pTo, 0, szPage);
|
||||
}
|
||||
sqlite3PagerUnref(pPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
return pOut;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine is called when the extension is loaded.
|
||||
** Register the new VFS.
|
||||
|
111
src/sqlite.h.in
111
src/sqlite.h.in
@ -8758,22 +8758,6 @@ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
|
||||
*/
|
||||
SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Retrieve the current MEMDB buffer
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** This interface is only available when SQLite is compiled
|
||||
** with SQLITE_ENABLE_MEMDB.
|
||||
**
|
||||
** The sqlite3_memdb_ptr(D,S,P) interface returns a pointer to the
|
||||
** memory buffer that is the database file used for [database connection] D
|
||||
** and schema S. If schema S of database connection D is not a MEMDB
|
||||
** database, then this routine returns NULL. If P is not NULL, then it must
|
||||
** be a pointer to a 64-bit signed integer into which the size of the
|
||||
** database file is written.
|
||||
*/
|
||||
SQLITE_EXPERIMENTAL void *sqlite3_memdb_ptr(sqlite3*,const char*,sqlite3_int64*);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Set the current MEMDB buffer
|
||||
** EXPERIMENTAL
|
||||
@ -8785,7 +8769,7 @@ SQLITE_EXPERIMENTAL void *sqlite3_memdb_ptr(sqlite3*,const char*,sqlite3_int64*)
|
||||
** The database identified by D and S must not be in active use when this
|
||||
** interface is called, or [SQLITE_BUSY] is returned.
|
||||
*/
|
||||
SQLITE_EXPERIMENTAL int sqlite3_memdb_config(sqlite3*,const char*,void*,sqlite3_int64,sqlite3_int64,unsigned);
|
||||
int sqlite3_memdb_config(sqlite3*,const char*,void*,sqlite3_int64,sqlite3_int64,unsigned);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags for configuring MEMDB databases
|
||||
@ -8797,6 +8781,99 @@ SQLITE_EXPERIMENTAL int sqlite3_memdb_config(sqlite3*,const char*,void*,sqlite3_
|
||||
#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
|
||||
**
|
||||
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
|
||||
** that is a serialization of the S database on [database connection] D.
|
||||
** If P is not a NULL pointer, then the size of the database in bytes
|
||||
** is written into *P.
|
||||
**
|
||||
** For an ordinary on-disk database file, the serialization is just a
|
||||
** copy of the disk file. For an in-memory database or a "TEMP" database,
|
||||
** the serialization is the same sequence of bytes which would be written
|
||||
** to disk if that database where backed up to disk.
|
||||
**
|
||||
** The usual case is that sqlite3_serialize() copies the serialization of
|
||||
** the database into memory obtained from [sqlite3_malloc64()] and returns
|
||||
** a pointer to that memory. The caller is responsible for freeing the
|
||||
** returned value to avoid a memory leak. However, if the F argument
|
||||
** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations
|
||||
** are made, and the sqlite3_serialize() function will return a pointer
|
||||
** to the contiguous memory representation of the database that SQLite
|
||||
** is currently using for that database, or NULL if the no such contiguous
|
||||
** memory representation of the database exists. A contigous memory
|
||||
** representation of the database will usually only exist if there has
|
||||
** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
|
||||
** values of D and S.
|
||||
** The size of the database is written into *P even if the
|
||||
** SQLITE_SERIALIZE_NOCOPY bit is set but no contigious copy
|
||||
** of the database exists.
|
||||
**
|
||||
** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
|
||||
** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
|
||||
** allocation error occurs.
|
||||
*/
|
||||
unsigned char *sqlite3_serialize(
|
||||
sqlite3 *db, /* The database connection */
|
||||
const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */
|
||||
sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */
|
||||
unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags for sqlite3_serialize
|
||||
** EXPERIMENTAL
|
||||
*/
|
||||
#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Set the current MEMDB buffer
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
|
||||
** [database connection] D to disconnection from database S and then
|
||||
** reopen S as an in-memory database based on the serialization contained
|
||||
** in P. The serialized database P is N bytes in size. M is the size of
|
||||
** the buffer P, which might be larger than N. If M is larger than N, and
|
||||
** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
|
||||
** permitted to add content to the in-memory database as long as the total
|
||||
** size does not exceed M bytes.
|
||||
**
|
||||
** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
|
||||
** invoke sqlite3_free() on the serialization buffer when the database
|
||||
** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
|
||||
** SQLite will try to increase the buffer size using sqlite3_realloc64()
|
||||
** if writes on the database cause it to grow larger than M bytes.
|
||||
**
|
||||
** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
|
||||
** database is currently in a read transaction or is involved in a backup
|
||||
** operation.
|
||||
**
|
||||
** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the
|
||||
** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
|
||||
** [sqlite3_free()] is invoked on argument P prior to returning.
|
||||
*/
|
||||
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 */
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags for sqlite3_deserialize()
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** The following are allowed values for the 6th argument (the "flags" or "F"
|
||||
** argument) of the [sqlite3_deserialize()] interface.
|
||||
*/
|
||||
#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */
|
||||
#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */
|
||||
#define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */
|
||||
|
||||
/*
|
||||
** Undo the hack that converts floating point types to integer for
|
||||
|
108
src/tclsqlite.c
108
src/tclsqlite.c
@ -1846,34 +1846,36 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
int choice;
|
||||
int rc = TCL_OK;
|
||||
static const char *DB_strs[] = {
|
||||
"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", "wal_hook", 0
|
||||
"authorizer", "backup", "busy",
|
||||
"cache", "changes", "close",
|
||||
"collate", "collation_needed", "commit_hook",
|
||||
"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
|
||||
};
|
||||
enum DB_enum {
|
||||
DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
|
||||
DB_CACHE, DB_CHANGES, DB_CLOSE,
|
||||
DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
|
||||
DB_COMPLETE, DB_COPY, 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_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_AUTHORIZER, DB_BACKUP, DB_BUSY,
|
||||
DB_CACHE, DB_CHANGES, DB_CLOSE,
|
||||
DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
|
||||
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
|
||||
};
|
||||
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
|
||||
|
||||
@ -2411,6 +2413,16 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** $db deserialize ?DATABASE? VALUE
|
||||
**
|
||||
** Reopen DATABASE (default "main") using the content in $VALUE
|
||||
*/
|
||||
case DB_DESERIALIZE: {
|
||||
rc = TCL_ERROR; /* TBD */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** $db enable_load_extension BOOLEAN
|
||||
**
|
||||
@ -2679,17 +2691,8 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
rc = TCL_ERROR;
|
||||
#else
|
||||
const char *zSchema = Tcl_GetString(objv[2]);
|
||||
sqlite3_int64 sz = 0;
|
||||
unsigned char *pData;
|
||||
if( objc==3 ){
|
||||
pData = sqlite3_memdb_ptr(pDb->db, zSchema, &sz);
|
||||
if( pData==0 ){
|
||||
Tcl_AppendResult(interp, "not a MEMDB database", (char*)0);
|
||||
rc = TCL_ERROR;
|
||||
}else{
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz));
|
||||
}
|
||||
}else if( objc==4 ){
|
||||
if( objc==4 ){
|
||||
int len = 0, xrc;
|
||||
unsigned char *pBA = Tcl_GetByteArrayFromObj(objv[3], &len);
|
||||
pData = sqlite3_malloc64( len );
|
||||
@ -2933,6 +2936,39 @@ static int SQLITE_TCLAPI DbObjCmd(
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** $db serialize ?DATABASE?
|
||||
**
|
||||
** Return a serialization of a database.
|
||||
*/
|
||||
case DB_SERIALIZE: {
|
||||
#ifndef SQLITE_ENABLE_MEMDB
|
||||
Tcl_AppendResult(interp, "MEMDB not available in this build",
|
||||
(char*)0);
|
||||
rc = TCL_ERROR;
|
||||
#else
|
||||
const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main";
|
||||
sqlite3_int64 sz = 0;
|
||||
unsigned char *pData;
|
||||
if( objc!=2 && objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?");
|
||||
rc = TCL_ERROR;
|
||||
}else{
|
||||
int needFree;
|
||||
pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY);
|
||||
if( pData ){
|
||||
needFree = 0;
|
||||
}else{
|
||||
pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0);
|
||||
needFree = 1;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz));
|
||||
if( needFree ) sqlite3_free(pData);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** $db status (step|sort|autoindex|vmstep)
|
||||
**
|
||||
|
@ -27,8 +27,6 @@ ifcapable !memdb {
|
||||
# Verify that the size of $::db1 is the same as the size of
|
||||
# the database.
|
||||
#
|
||||
db close
|
||||
sqlite3 db dummy -vfs memdb
|
||||
unset -nocomplain db1
|
||||
unset -nocomplain sz1
|
||||
unset -nocomplain pgsz
|
||||
@ -39,9 +37,12 @@ do_test 100 {
|
||||
}
|
||||
set ::pgsz [db one {PRAGMA page_size}]
|
||||
set ::sz1 [expr {$::pgsz*[db one {PRAGMA page_count}]}]
|
||||
set ::db1 [db memdb main]
|
||||
set ::db1 [db serialize]
|
||||
expr {[string length $::db1]==$::sz1}
|
||||
} 1
|
||||
set fd [open db1.db wb]
|
||||
puts -nonewline $fd $db1
|
||||
close $fd
|
||||
|
||||
# Create a new MEMDB and initialize it to the content of $::db1
|
||||
# Verify that the content is the same.
|
||||
|
@ -11,7 +11,7 @@ while {![eof stdin]} {
|
||||
if {$line==""} continue
|
||||
regsub -all "\[ \t\n,\]+" [string trim $line] { } line
|
||||
foreach token [split $line { }] {
|
||||
if {![regexp {(([a-zA-Z]+)_)?([_a-zA-Z]+)} $token all px p2 name]} continue
|
||||
if {![regexp {(([a-zA-Z]+)_)?([_a-zA-Z0-9]+)} $token all px p2 name]} continue
|
||||
lappend namelist [string tolower $name]
|
||||
if {$px!=""} {set prefix $p2}
|
||||
}
|
||||
@ -23,7 +23,7 @@ proc put_item x {
|
||||
global col
|
||||
if {$col==0} {puts -nonewline " "}
|
||||
if {$col<2} {
|
||||
puts -nonewline [format " %-21s" $x]
|
||||
puts -nonewline [format " %-25s" $x]
|
||||
incr col
|
||||
} else {
|
||||
puts $x
|
||||
|
Loading…
x
Reference in New Issue
Block a user