Add "backup" and "restore" methods to the TCL interfaces and test cases
to exercise those methods. (CVS 6260) FossilOrigin-Name: e420a3cedc7ee086a77cd719f6b9fb85415eb5f3
This commit is contained in:
parent
9ff849fc87
commit
dc2c491525
25
manifest
25
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\s".backup"\sand\s".restore"\scommands\sto\sthe\sCLI\s-\simplemented\susing\sthe\nnew\sbackup\sAPI.\s(CVS\s6259)
|
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-04T20:55:58
|
D 2009-02-04T22:46:47
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in c7a5a30fb6852bd7839b1024e1661da8549878ee
|
F Makefile.in c7a5a30fb6852bd7839b1024e1661da8549878ee
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@ -156,14 +156,14 @@ F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
|
|||||||
F src/resolve.c 18dc9f0df1d60048e012ce6632251063e0dd356a
|
F src/resolve.c 18dc9f0df1d60048e012ce6632251063e0dd356a
|
||||||
F src/rowset.c ba9375f37053d422dd76965a9c370a13b6e1aac4
|
F src/rowset.c ba9375f37053d422dd76965a9c370a13b6e1aac4
|
||||||
F src/select.c ae72b604e47092521c4d9ae54e1b1cbeb872a747
|
F src/select.c ae72b604e47092521c4d9ae54e1b1cbeb872a747
|
||||||
F src/shell.c 6c674a4a4cc56c70ecfb26b07d486d43740b475f
|
F src/shell.c f109ebbb50132926ebbc173a6c2d8838d5d78527
|
||||||
F src/sqlite.h.in 31fa12602f784adea9be66424a2e8b052116736f
|
F src/sqlite.h.in 31fa12602f784adea9be66424a2e8b052116736f
|
||||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||||
F src/sqliteInt.h 73c1d4f9716fe21f202f9d05c4fd9e6281f2636f
|
F src/sqliteInt.h 73c1d4f9716fe21f202f9d05c4fd9e6281f2636f
|
||||||
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
||||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||||
F src/table.c 332ab0ea691e63862e2a8bdfe2c0617ee61062a3
|
F src/table.c 332ab0ea691e63862e2a8bdfe2c0617ee61062a3
|
||||||
F src/tclsqlite.c 7b3e7fc4856e8280939c9ca0c3a6e49bd2c4bb46
|
F src/tclsqlite.c 524c1f49ccf9b6a5e3917591cf3b6c4f4204e607
|
||||||
F src/test1.c f88b447699786d58a0136a3a48b12990abc72c8a
|
F src/test1.c f88b447699786d58a0136a3a48b12990abc72c8a
|
||||||
F src/test2.c 9689e7d3b7791da8c03f9acd1ea801802cb83c17
|
F src/test2.c 9689e7d3b7791da8c03f9acd1ea801802cb83c17
|
||||||
F src/test3.c 88a246b56b824275300e6c899634fbac1dc94b14
|
F src/test3.c 88a246b56b824275300e6c899634fbac1dc94b14
|
||||||
@ -233,9 +233,10 @@ F test/autoinc.test ab549b48b389cabd92967b86c379ec8b31fa6c16
|
|||||||
F test/autovacuum.test 61260e25744189ff766f61ca3df23c1eeec0060e
|
F test/autovacuum.test 61260e25744189ff766f61ca3df23c1eeec0060e
|
||||||
F test/autovacuum_ioerr2.test 598b0663074d3673a9c1bc9a16e80971313bafe6
|
F test/autovacuum_ioerr2.test 598b0663074d3673a9c1bc9a16e80971313bafe6
|
||||||
F test/avtrans.test 1e901d8102706b63534dbd2bdd4d8f16c4082650
|
F test/avtrans.test 1e901d8102706b63534dbd2bdd4d8f16c4082650
|
||||||
F test/backup.test 3683d4d3d04e4db6ebba6a4dc9b9d882c3d03bff
|
F test/backup.test f3592c6759de90fa7a7dcd4bce380aed97115c88
|
||||||
F test/backup_ioerr.test 2edd5e347e263733cae8c08f41bf3dbd7277b33d
|
F test/backup2.test 392318e059b83e87e5e4175f08be181a6ddce468
|
||||||
F test/backup_malloc.test 471fb098dae228ca840d4d51e41481901ac03578
|
F test/backup_ioerr.test a9b8084e488154341719833783ac9db321e14284
|
||||||
|
F test/backup_malloc.test 1e063c6d75143d0d6e0ae77971dd690070369387
|
||||||
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
|
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
|
||||||
F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070
|
F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070
|
||||||
F test/bigfile.test 6adfef13d24bbe0c504b4547f292b9a170184f25
|
F test/bigfile.test 6adfef13d24bbe0c504b4547f292b9a170184f25
|
||||||
@ -548,10 +549,10 @@ F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
|
|||||||
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
|
F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
|
||||||
F test/table.test 0aac9468b69d2683e68ee2682cdae28d82a453ec
|
F test/table.test 0aac9468b69d2683e68ee2682cdae28d82a453ec
|
||||||
F test/tableapi.test 505031f15b18a750184d967d2c896cf88fcc969c
|
F test/tableapi.test 505031f15b18a750184d967d2c896cf88fcc969c
|
||||||
F test/tclsqlite.test 30636c3151ccc2d553aa09020b885054141a1963
|
F test/tclsqlite.test 413a8a887d89ea8fa7055e8d118ffb03b0a4c91a
|
||||||
F test/tempdb.test b88ac8a19823cf771d742bf61eef93ef337c06b1
|
F test/tempdb.test b88ac8a19823cf771d742bf61eef93ef337c06b1
|
||||||
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
|
||||||
F test/tester.tcl 3d11a8c1d05535400880ac4f8c5402b8dee14b7f
|
F test/tester.tcl 94dc2fe5f8d9179e58ebfe1c7ce2618bdb44799d
|
||||||
F test/thread001.test 7595e58213eda498794860f608e0ea7e499d18d0
|
F test/thread001.test 7595e58213eda498794860f608e0ea7e499d18d0
|
||||||
F test/thread002.test 0258a50c55f2371de2e4c7e02bec2576c1eef359
|
F test/thread002.test 0258a50c55f2371de2e4c7e02bec2576c1eef359
|
||||||
F test/thread003.test e17754799649c2b732c295620dca041c32f01e16
|
F test/thread003.test e17754799649c2b732c295620dca041c32f01e16
|
||||||
@ -700,7 +701,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P 0882a028c8cee868bb79728499fb1fa7c0630fa6
|
P 003e1d62189e9e37f901d86a696cfccd22bd3b38
|
||||||
R 6acad12f687e13cb8812850fc6ee53f0
|
R 007c4ac680893970254b4f79c5bdeaaf
|
||||||
U drh
|
U drh
|
||||||
Z 7b9fc40e749f6a4e8493cccb068ac51f
|
Z b11130f7853d25d09c92b1b009dfc517
|
||||||
|
@ -1 +1 @@
|
|||||||
003e1d62189e9e37f901d86a696cfccd22bd3b38
|
e420a3cedc7ee086a77cd719f6b9fb85415eb5f3
|
16
src/shell.c
16
src/shell.c
@ -12,7 +12,7 @@
|
|||||||
** This file contains code to implement the "sqlite" command line
|
** This file contains code to implement the "sqlite" command line
|
||||||
** utility for accessing SQLite databases.
|
** 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)
|
#if defined(_WIN32) || defined(WIN32)
|
||||||
/* This needs to come before any includes for MSVC compiler */
|
/* This needs to come before any includes for MSVC compiler */
|
||||||
@ -1113,6 +1113,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
|||||||
sqlite3_close(pDest);
|
sqlite3_close(pDest);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
open_db(p);
|
||||||
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
|
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
|
||||||
if( pBackup==0 ){
|
if( pBackup==0 ){
|
||||||
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
|
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
|
||||||
@ -1506,6 +1507,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
|||||||
sqlite3 *pSrc;
|
sqlite3 *pSrc;
|
||||||
sqlite3_backup *pBackup;
|
sqlite3_backup *pBackup;
|
||||||
int rc;
|
int rc;
|
||||||
|
int nTimeout = 0;
|
||||||
|
|
||||||
if( nArg==2 ){
|
if( nArg==2 ){
|
||||||
zSrcFile = azArg[1];
|
zSrcFile = azArg[1];
|
||||||
zDb = "main";
|
zDb = "main";
|
||||||
@ -1519,20 +1522,25 @@ static int do_meta_command(char *zLine, struct callback_data *p){
|
|||||||
sqlite3_close(pSrc);
|
sqlite3_close(pSrc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
open_db(p);
|
||||||
pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
|
pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
|
||||||
if( pBackup==0 ){
|
if( pBackup==0 ){
|
||||||
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
|
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
|
||||||
sqlite3_close(pSrc);
|
sqlite3_close(pSrc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){
|
while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
|
||||||
if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
|
|| rc==SQLITE_BUSY ){
|
||||||
sqlite3_sleep(10);
|
if( rc==SQLITE_BUSY ){
|
||||||
|
if( nTimeout++ >= 3 ) break;
|
||||||
|
sqlite3_sleep(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlite3_backup_finish(pBackup);
|
sqlite3_backup_finish(pBackup);
|
||||||
if( rc==SQLITE_DONE ){
|
if( rc==SQLITE_DONE ){
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
|
}else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
|
||||||
|
fprintf(stderr, "source database is busy\n");
|
||||||
}else{
|
}else{
|
||||||
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
|
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
|
||||||
}
|
}
|
||||||
|
155
src/tclsqlite.c
155
src/tclsqlite.c
@ -12,7 +12,7 @@
|
|||||||
** A TCL Interface to SQLite. Append this file to sqlite3.c and
|
** A TCL Interface to SQLite. Append this file to sqlite3.c and
|
||||||
** compile the whole thing to build a TCL-enabled version of SQLite.
|
** 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 "tcl.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -983,30 +983,31 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
int choice;
|
int choice;
|
||||||
int rc = TCL_OK;
|
int rc = TCL_OK;
|
||||||
static const char *DB_strs[] = {
|
static const char *DB_strs[] = {
|
||||||
"authorizer", "busy", "cache",
|
"authorizer", "backup", "busy",
|
||||||
"changes", "close", "collate",
|
"cache", "changes", "close",
|
||||||
"collation_needed", "commit_hook", "complete",
|
"collate", "collation_needed", "commit_hook",
|
||||||
"copy", "enable_load_extension","errorcode",
|
"complete", "copy", "enable_load_extension",
|
||||||
"eval", "exists", "function",
|
"errorcode", "eval", "exists",
|
||||||
"incrblob", "interrupt", "last_insert_rowid",
|
"function", "incrblob", "interrupt",
|
||||||
"nullvalue", "onecolumn", "profile",
|
"last_insert_rowid", "nullvalue", "onecolumn",
|
||||||
"progress", "rekey", "rollback_hook",
|
"profile", "progress", "rekey",
|
||||||
"status", "timeout", "total_changes",
|
"restore", "rollback_hook", "status",
|
||||||
"trace", "transaction", "update_hook",
|
"timeout", "total_changes", "trace",
|
||||||
"version", 0
|
"transaction", "update_hook", "version",
|
||||||
|
0
|
||||||
};
|
};
|
||||||
enum DB_enum {
|
enum DB_enum {
|
||||||
DB_AUTHORIZER, DB_BUSY, DB_CACHE,
|
DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
|
||||||
DB_CHANGES, DB_CLOSE, DB_COLLATE,
|
DB_CACHE, DB_CHANGES, DB_CLOSE,
|
||||||
DB_COLLATION_NEEDED, DB_COMMIT_HOOK, DB_COMPLETE,
|
DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
|
||||||
DB_COPY, DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE,
|
DB_COMPLETE, DB_COPY, DB_ENABLE_LOAD_EXTENSION,
|
||||||
DB_EVAL, DB_EXISTS, DB_FUNCTION,
|
DB_ERRORCODE, DB_EVAL, DB_EXISTS,
|
||||||
DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID,
|
DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT,
|
||||||
DB_NULLVALUE, DB_ONECOLUMN, DB_PROFILE,
|
DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN,
|
||||||
DB_PROGRESS, DB_REKEY, DB_ROLLBACK_HOOK,
|
DB_PROFILE, DB_PROGRESS, DB_REKEY,
|
||||||
DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
|
DB_RESTORE, DB_ROLLBACK_HOOK, DB_STATUS,
|
||||||
DB_TRACE, DB_TRANSACTION, DB_UPDATE_HOOK,
|
DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
|
||||||
DB_VERSION
|
DB_TRANSACTION, DB_UPDATE_HOOK, DB_VERSION,
|
||||||
};
|
};
|
||||||
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
|
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
|
||||||
|
|
||||||
@ -1074,6 +1075,55 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
break;
|
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?
|
/* $db busy ?CALLBACK?
|
||||||
**
|
**
|
||||||
** Invoke the given callback if an SQL statement attempts to open
|
** Invoke the given callback if an SQL statement attempts to open
|
||||||
@ -2151,6 +2201,65 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
|
|||||||
break;
|
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)
|
** $db status (step|sort)
|
||||||
**
|
**
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# 2008 January 30
|
# 2009 January 30
|
||||||
#
|
#
|
||||||
# The author disclaims copyright to this source code. In place of
|
# The author disclaims copyright to this source code. In place of
|
||||||
# a legal notice, here is a blessing:
|
# a legal notice, here is a blessing:
|
||||||
@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing the sqlite3_backup_XXX API.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
|
175
test/backup2.test
Normal file
175
test/backup2.test
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
# 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
|
@ -1,4 +1,4 @@
|
|||||||
# 2008 January 30
|
# 2009 January 30
|
||||||
#
|
#
|
||||||
# The author disclaims copyright to this source code. In place of
|
# The author disclaims copyright to this source code. In place of
|
||||||
# a legal notice, here is a blessing:
|
# a legal notice, here is a blessing:
|
||||||
@ -12,7 +12,7 @@
|
|||||||
# focus of this file is testing the handling of IO errors by the
|
# focus of this file is testing the handling of IO errors by the
|
||||||
# sqlite3_backup_XXX APIs.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -284,4 +284,3 @@ for {set iError 1} {$bStop == 0} {incr iError} {
|
|||||||
catch { sdb close }
|
catch { sdb close }
|
||||||
catch { ddb close }
|
catch { ddb close }
|
||||||
finish_test
|
finish_test
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# 2008 January 30
|
# 2009 January 30
|
||||||
#
|
#
|
||||||
# The author disclaims copyright to this source code. In place of
|
# The author disclaims copyright to this source code. In place of
|
||||||
# a legal notice, here is a blessing:
|
# a legal notice, here is a blessing:
|
||||||
@ -12,7 +12,7 @@
|
|||||||
# focus of this file is testing the handling of OOM errors by the
|
# focus of this file is testing the handling of OOM errors by the
|
||||||
# sqlite3_backup_XXX APIs.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
# interface is pretty well tested. This file contains some addition
|
# interface is pretty well tested. This file contains some addition
|
||||||
# tests for fringe issues that the main test suite does not cover.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -35,7 +35,7 @@ do_test tcl-1.1 {
|
|||||||
do_test tcl-1.2 {
|
do_test tcl-1.2 {
|
||||||
set v [catch {db bogus} msg]
|
set v [catch {db bogus} msg]
|
||||||
lappend v $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 {
|
do_test tcl-1.2.1 {
|
||||||
set v [catch {db cache bogus} msg]
|
set v [catch {db cache bogus} msg]
|
||||||
lappend v $msg
|
lappend v $msg
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements some common TCL routines used for regression
|
# This file implements some common TCL routines used for regression
|
||||||
# testing the SQLite library
|
# 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
|
# What for user input before continuing. This gives an opportunity
|
||||||
@ -869,6 +869,24 @@ proc allcksum {{db db}} {
|
|||||||
return [md5 $txt]
|
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}} {
|
proc memdebug_log_sql {{filename mallocs.sql}} {
|
||||||
|
|
||||||
set data [sqlite3_memdebug_log dump]
|
set data [sqlite3_memdebug_log dump]
|
||||||
|
Loading…
Reference in New Issue
Block a user