-C Add\s".backup"\sand\s".restore"\scommands\sto\sthe\sCLI\s-\simplemented\susing\sthe\nnew\sbackup\sAPI.\s(CVS\s6259)
-D 2009-02-04T20:55:58
+C Add\s"backup"\sand\s"restore"\smethods\sto\sthe\sTCL\sinterfaces\sand\stest\scases\nto\sexercise\sthose\smethods.\s(CVS\s6260)
+D 2009-02-04T22:46:47
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in c7a5a30fb6852bd7839b1024e1661da8549878ee
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/resolve.c 18dc9f0df1d60048e012ce6632251063e0dd356a
F src/rowset.c ba9375f37053d422dd76965a9c370a13b6e1aac4
F src/select.c ae72b604e47092521c4d9ae54e1b1cbeb872a747
-F src/shell.c 6c674a4a4cc56c70ecfb26b07d486d43740b475f
+F src/shell.c f109ebbb50132926ebbc173a6c2d8838d5d78527
F src/sqlite.h.in 31fa12602f784adea9be66424a2e8b052116736f
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
F src/sqliteInt.h 73c1d4f9716fe21f202f9d05c4fd9e6281f2636f
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c 332ab0ea691e63862e2a8bdfe2c0617ee61062a3
-F src/tclsqlite.c 7b3e7fc4856e8280939c9ca0c3a6e49bd2c4bb46
+F src/tclsqlite.c 524c1f49ccf9b6a5e3917591cf3b6c4f4204e607
F src/test1.c f88b447699786d58a0136a3a48b12990abc72c8a
F src/test2.c 9689e7d3b7791da8c03f9acd1ea801802cb83c17
F src/test3.c 88a246b56b824275300e6c899634fbac1dc94b14
F test/autovacuum.test 61260e25744189ff766f61ca3df23c1eeec0060e
F test/autovacuum_ioerr2.test 598b0663074d3673a9c1bc9a16e80971313bafe6
F test/avtrans.test 1e901d8102706b63534dbd2bdd4d8f16c4082650
-F test/backup.test 3683d4d3d04e4db6ebba6a4dc9b9d882c3d03bff
-F test/backup_ioerr.test 2edd5e347e263733cae8c08f41bf3dbd7277b33d
-F test/backup_malloc.test 471fb098dae228ca840d4d51e41481901ac03578
+F test/backup.test f3592c6759de90fa7a7dcd4bce380aed97115c88
+F test/backup2.test 392318e059b83e87e5e4175f08be181a6ddce468
+F test/backup_ioerr.test a9b8084e488154341719833783ac9db321e14284
+F test/backup_malloc.test 1e063c6d75143d0d6e0ae77971dd690070369387
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070
F test/bigfile.test 6adfef13d24bbe0c504b4547f292b9a170184f25
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
F test/table.test 0aac9468b69d2683e68ee2682cdae28d82a453ec
F test/tableapi.test 505031f15b18a750184d967d2c896cf88fcc969c
-F test/tclsqlite.test 30636c3151ccc2d553aa09020b885054141a1963
+F test/tclsqlite.test 413a8a887d89ea8fa7055e8d118ffb03b0a4c91a
F test/tempdb.test b88ac8a19823cf771d742bf61eef93ef337c06b1
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
-F test/tester.tcl 3d11a8c1d05535400880ac4f8c5402b8dee14b7f
+F test/tester.tcl 94dc2fe5f8d9179e58ebfe1c7ce2618bdb44799d
F test/thread001.test 7595e58213eda498794860f608e0ea7e499d18d0
F test/thread002.test 0258a50c55f2371de2e4c7e02bec2576c1eef359
F test/thread003.test e17754799649c2b732c295620dca041c32f01e16
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 0882a028c8cee868bb79728499fb1fa7c0630fa6
-R 6acad12f687e13cb8812850fc6ee53f0
+P 003e1d62189e9e37f901d86a696cfccd22bd3b38
+R 007c4ac680893970254b4f79c5bdeaaf
U drh
-Z 7b9fc40e749f6a4e8493cccb068ac51f
+Z b11130f7853d25d09c92b1b009dfc517
-003e1d62189e9e37f901d86a696cfccd22bd3b38
\ No newline at end of file
+e420a3cedc7ee086a77cd719f6b9fb85415eb5f3
\ No newline at end of file
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
-** $Id: shell.c,v 1.200 2009/02/04 20:55:58 drh Exp $
+** $Id: shell.c,v 1.201 2009/02/04 22:46:47 drh Exp $
*/
#if defined(_WIN32) || defined(WIN32)
/* This needs to come before any includes for MSVC compiler */
sqlite3_close(pDest);
return 1;
}
+ open_db(p);
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
if( pBackup==0 ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
sqlite3 *pSrc;
sqlite3_backup *pBackup;
int rc;
+ int nTimeout = 0;
+
if( nArg==2 ){
zSrcFile = azArg[1];
zDb = "main";
sqlite3_close(pSrc);
return 1;
}
+ open_db(p);
pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
if( pBackup==0 ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
sqlite3_close(pSrc);
return 1;
}
- while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){
- if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
- sqlite3_sleep(10);
+ while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
+ || rc==SQLITE_BUSY ){
+ if( rc==SQLITE_BUSY ){
+ if( nTimeout++ >= 3 ) break;
+ sqlite3_sleep(100);
}
}
sqlite3_backup_finish(pBackup);
if( rc==SQLITE_DONE ){
rc = SQLITE_OK;
+ }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
+ fprintf(stderr, "source database is busy\n");
}else{
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
}
** A TCL Interface to SQLite. Append this file to sqlite3.c and
** compile the whole thing to build a TCL-enabled version of SQLite.
**
-** $Id: tclsqlite.c,v 1.235 2009/02/03 16:51:25 danielk1977 Exp $
+** $Id: tclsqlite.c,v 1.236 2009/02/04 22:46:47 drh Exp $
*/
#include "tcl.h"
#include <errno.h>
int choice;
int rc = TCL_OK;
static const char *DB_strs[] = {
- "authorizer", "busy", "cache",
- "changes", "close", "collate",
- "collation_needed", "commit_hook", "complete",
- "copy", "enable_load_extension","errorcode",
- "eval", "exists", "function",
- "incrblob", "interrupt", "last_insert_rowid",
- "nullvalue", "onecolumn", "profile",
- "progress", "rekey", "rollback_hook",
- "status", "timeout", "total_changes",
- "trace", "transaction", "update_hook",
- "version", 0
+ "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", "nullvalue", "onecolumn",
+ "profile", "progress", "rekey",
+ "restore", "rollback_hook", "status",
+ "timeout", "total_changes", "trace",
+ "transaction", "update_hook", "version",
+ 0
};
enum DB_enum {
- DB_AUTHORIZER, 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_NULLVALUE, DB_ONECOLUMN, DB_PROFILE,
- DB_PROGRESS, DB_REKEY, DB_ROLLBACK_HOOK,
- DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
- DB_TRACE, DB_TRANSACTION, DB_UPDATE_HOOK,
- DB_VERSION
+ 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_NULLVALUE, DB_ONECOLUMN,
+ DB_PROFILE, DB_PROGRESS, DB_REKEY,
+ DB_RESTORE, DB_ROLLBACK_HOOK, DB_STATUS,
+ DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
+ DB_TRANSACTION, DB_UPDATE_HOOK, DB_VERSION,
};
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
break;
}
+ /* $db backup ?DATABASE? FILENAME
+ **
+ ** Open or create a database file named FILENAME. Transfer the
+ ** content of local database DATABASE (default: "main") into the
+ ** FILENAME database.
+ */
+ case DB_BACKUP: {
+ const char *zDestFile;
+ const char *zSrcDb;
+ sqlite3 *pDest;
+ sqlite3_backup *pBackup;
+
+ if( objc==3 ){
+ zSrcDb = "main";
+ zDestFile = Tcl_GetString(objv[2]);
+ }else if( objc==4 ){
+ zSrcDb = Tcl_GetString(objv[2]);
+ zDestFile = Tcl_GetString(objv[3]);
+ }else{
+ Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
+ return TCL_ERROR;
+ }
+ rc = sqlite3_open(zDestFile, &pDest);
+ if( rc!=SQLITE_OK ){
+ Tcl_AppendResult(interp, "cannot open target database: ",
+ sqlite3_errmsg(pDest), (char*)0);
+ sqlite3_close(pDest);
+ return TCL_ERROR;
+ }
+ pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb);
+ if( pBackup==0 ){
+ Tcl_AppendResult(interp, "backup failed: ",
+ sqlite3_errmsg(pDest), (char*)0);
+ sqlite3_close(pDest);
+ return TCL_ERROR;
+ }
+ while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
+ sqlite3_backup_finish(pBackup);
+ if( rc==SQLITE_DONE ){
+ rc = TCL_OK;
+ }else{
+ Tcl_AppendResult(interp, "backup failed: ",
+ sqlite3_errmsg(pDest), (char*)0);
+ rc = TCL_ERROR;
+ }
+ sqlite3_close(pDest);
+ break;
+ }
+
/* $db busy ?CALLBACK?
**
** Invoke the given callback if an SQL statement attempts to open
break;
}
+ /* $db restore ?DATABASE? FILENAME
+ **
+ ** Open a database file named FILENAME. Transfer the content
+ ** of FILENAME into the local database DATABASE (default: "main").
+ */
+ case DB_RESTORE: {
+ const char *zSrcFile;
+ const char *zDestDb;
+ sqlite3 *pSrc;
+ sqlite3_backup *pBackup;
+ int nTimeout = 0;
+
+ if( objc==3 ){
+ zDestDb = "main";
+ zSrcFile = Tcl_GetString(objv[2]);
+ }else if( objc==4 ){
+ zDestDb = Tcl_GetString(objv[2]);
+ zSrcFile = Tcl_GetString(objv[3]);
+ }else{
+ Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
+ return TCL_ERROR;
+ }
+ rc = sqlite3_open_v2(zSrcFile, &pSrc, SQLITE_OPEN_READONLY, 0);
+ if( rc!=SQLITE_OK ){
+ Tcl_AppendResult(interp, "cannot open source database: ",
+ sqlite3_errmsg(pSrc), (char*)0);
+ sqlite3_close(pSrc);
+ return TCL_ERROR;
+ }
+ pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main");
+ if( pBackup==0 ){
+ Tcl_AppendResult(interp, "restore failed: ",
+ sqlite3_errmsg(pDb->db), (char*)0);
+ sqlite3_close(pSrc);
+ return TCL_ERROR;
+ }
+ while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
+ || rc==SQLITE_BUSY ){
+ if( rc==SQLITE_BUSY ){
+ if( nTimeout++ >= 3 ) break;
+ sqlite3_sleep(100);
+ }
+ }
+ sqlite3_backup_finish(pBackup);
+ if( rc==SQLITE_DONE ){
+ rc = TCL_OK;
+ }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
+ Tcl_AppendResult(interp, "restore failed: source database busy",
+ (char*)0);
+ rc = TCL_ERROR;
+ }else{
+ Tcl_AppendResult(interp, "restore failed: ",
+ sqlite3_errmsg(pDb->db), (char*)0);
+ rc = TCL_ERROR;
+ }
+ sqlite3_close(pSrc);
+ break;
+ }
+
/*
** $db status (step|sort)
**
-# 2008 January 30
+# 2009 January 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
# This file implements regression tests for SQLite library. The
# focus of this file is testing the sqlite3_backup_XXX API.
#
-# $Id: backup.test,v 1.2 2009/02/04 17:40:58 drh Exp $
+# $Id: backup.test,v 1.3 2009/02/04 22:46:47 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
--- /dev/null
+# 2009 February 4
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library. The
+# focus of this file is testing the "backup" and "restore" methods
+# of the TCL interface - methods which are based on the
+# sqlite3_backup_XXX API.
+#
+# $Id: backup2.test,v 1.1 2009/02/04 22:46:47 drh Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# Fill a database with test data.
+#
+do_test backup2-1 {
+ db eval {
+ CREATE TABLE t1(x);
+ INSERT INTO t1 VALUES(randstr(8000,8000));
+ INSERT INTO t1 VALUES(randstr(8000,8000));
+ INSERT INTO t1 VALUES(randstr(8000,8000));
+ INSERT INTO t1 VALUES(randstr(8000,8000));
+ INSERT INTO t1 VALUES(randstr(8000,8000));
+ CREATE VIEW v1 AS SELECT substr(x,10,10) FROM t1;
+ CREATE TABLE t2(a,b);
+ INSERT INTO t2 VALUES(1,2);
+ INSERT INTO t2 VALUES(2,4);
+ INSERT INTO t2 SELECT a+2, (a+2)*2 FROM t2;
+ INSERT INTO t2 SELECT a+4, (a+4)*2 FROM t2;
+ INSERT INTO t2 SELECT a+8, (a+8)*2 FROM t2;
+ INSERT INTO t2 SELECT a+16, (a+16)*2 FROM t2;
+ INSERT INTO t2 SELECT a+32, (a+32)*2 FROM t2;
+ INSERT INTO t2 SELECT a+64, (a+64)*2 FROM t2;
+ INSERT INTO t2 SELECT a+128, (a+128)*2 FROM t2;
+ CREATE INDEX t2i1 ON t2(a,b);
+ CREATE TRIGGER r1 AFTER INSERT ON t2 BEGIN
+ SELECT 'hello';
+ END;
+ ANALYZE;
+ PRAGMA integrity_check;
+ }
+} {ok}
+
+# Remember a check-sum on the database file.
+#
+unset -nocomplain cksum
+set cksum [dbcksum db main]
+
+# Make a backup of the test data. Verify that the backup copy
+# is identical to the original.
+#
+do_test backup2-2 {
+ file delete -force bu1.db
+ db backup bu1.db
+ sqlite3 db2 bu1.db
+ dbcksum db2 main
+} $cksum
+
+# Delete the original. Restore from backup. Verify the content is
+# unchanged.
+#
+do_test backup2-3.1 {
+ db close
+ file delete -force test.db test.db-journal
+ sqlite3 db test.db
+ db2 eval {BEGIN EXCLUSIVE}
+ set rc [catch {db restore bu1.db} res]
+ lappend rc $res
+ db2 eval {ROLLBACK}
+ set rc
+} {1 {restore failed: source database busy}}
+do_test backup2-3.2 {
+ db close
+ file delete -force test.db test.db-journal
+ sqlite3 db test.db
+ db restore bu1.db
+ dbcksum db main
+} $cksum
+
+# Use alternative databases - other than "main".
+#
+do_test backup2-4 {
+ db restore temp bu1.db
+ dbcksum db temp
+} $cksum
+do_test backup2-5 {
+ db2 close
+ file delete -force bu1.db bu2.db
+ db backup temp bu2.db
+ sqlite3 db2 bu2.db
+ dbcksum db2 main
+} $cksum
+
+# Try to backup to a readonly file.
+#
+do_test backup2-6 {
+ db2 close
+ catch {file attributes bu2.db -permissions r--------}
+ catch {file attributes bu2.db -readonly 1}
+ set rc [catch {db backup temp bu2.db} res]
+ lappend rc $res
+} {1 {backup failed: attempt to write a readonly database}}
+
+# Try to backup to something that is not a database file.
+#
+do_test backup2-7 {
+ catch {file attributes bu2.db -permissions rw-------}
+ catch {file attributes bu2.db -readonly 0}
+ set out [open bu2.db w]
+ puts $out "This is not a valid database file"
+ close $out
+ set rc [catch {db backup temp bu2.db} res]
+ lappend rc $res
+} {1 {backup failed: file is encrypted or is not a database}}
+
+# Try to backup database that does not exist
+#
+do_test backup2-8 {
+ file delete -force bu1.db
+ set rc [catch {db backup aux1 bu1.db} res]
+ lappend rc $res
+} {1 {backup failed: unknown database aux1}}
+
+# Invalid syntax on the backup method
+#
+do_test backup2-9 {
+ set rc [catch {db backup} res]
+ lappend rc $res
+} {1 {wrong # args: should be "db backup ?DATABASE? FILENAME"}}
+
+# Try to restore from an unreadable file.
+#
+do_test backup2-10 {
+ file delete -force bu3.db
+ file mkdir bu3.db
+ set rc [catch {db restore temp bu3.db} res]
+ lappend rc $res
+} {1 {cannot open source database: disk I/O error}}
+
+# Try to restore from something that is not a database file.
+#
+do_test backup2-11 {
+ set rc [catch {db restore temp bu2.db} res]
+ lappend rc $res
+} {1 {restore failed: file is encrypted or is not a database}}
+
+# Try to restore a database that does not exist
+#
+do_test backup2-12 {
+ set rc [catch {db restore aux1 bu2.db} res]
+ lappend rc $res
+} {1 {restore failed: unknown database aux1}}
+do_test backup2-13 {
+ file delete -force bu4.db
+ set rc [catch {db restore bu4.db} res]
+ lappend rc $res
+} {1 {cannot open source database: unable to open database file}}
+
+# Invalid syntax on the restore method
+#
+do_test backup2-14 {
+ set rc [catch {db restore} res]
+ lappend rc $res
+} {1 {wrong # args: should be "db restore ?DATABASE? FILENAME"}}
+
+file delete -force bu1.db bu2.db bu3.db bu4.db
+
+finish_test
-# 2008 January 30
+# 2009 January 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
# focus of this file is testing the handling of IO errors by the
# sqlite3_backup_XXX APIs.
#
-# $Id: backup_ioerr.test,v 1.1 2009/02/03 16:51:25 danielk1977 Exp $
+# $Id: backup_ioerr.test,v 1.2 2009/02/04 22:46:47 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
catch { sdb close }
catch { ddb close }
finish_test
-
-# 2008 January 30
+# 2009 January 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
# focus of this file is testing the handling of OOM errors by the
# sqlite3_backup_XXX APIs.
#
-# $Id: backup_malloc.test,v 1.1 2009/02/03 16:51:25 danielk1977 Exp $
+# $Id: backup_malloc.test,v 1.2 2009/02/04 22:46:47 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# interface is pretty well tested. This file contains some addition
# tests for fringe issues that the main test suite does not cover.
#
-# $Id: tclsqlite.test,v 1.71 2009/01/02 17:33:46 danielk1977 Exp $
+# $Id: tclsqlite.test,v 1.72 2009/02/04 22:46:47 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_test tcl-1.2 {
set v [catch {db bogus} msg]
lappend v $msg
-} {1 {bad option "bogus": must be authorizer, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, profile, progress, rekey, rollback_hook, status, timeout, total_changes, trace, transaction, update_hook, or version}}
+} {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, nullvalue, onecolumn, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, transaction, update_hook, or version}}
do_test tcl-1.2.1 {
set v [catch {db cache bogus} msg]
lappend v $msg
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
-# $Id: tester.tcl,v 1.137 2009/02/03 16:51:25 danielk1977 Exp $
+# $Id: tester.tcl,v 1.138 2009/02/04 22:46:47 drh Exp $
#
# What for user input before continuing. This gives an opportunity
return [md5 $txt]
}
+# Generate a checksum based on the contents of a single database with
+# a database connection. The name of the database is $dbname.
+# Examples of $dbname are "temp" or "main".
+#
+proc dbcksum {db dbname} {
+ if {$dbname=="temp"} {
+ set master sqlite_temp_master
+ } else {
+ set master $dbname.sqlite_master
+ }
+ set alltab [$db eval "SELECT name FROM $master WHERE type='table'"]
+ set txt [$db eval "SELECT * FROM $master"]\n
+ foreach tab $alltab {
+ append txt [$db eval "SELECT * FROM $dbname.$tab"]\n
+ }
+ return [md5 $txt]
+}
+
proc memdebug_log_sql {{filename mallocs.sql}} {
set data [sqlite3_memdebug_log dump]