Merge the latest trunk changes.
FossilOrigin-Name: 84da122dd6e70ed603fea781dca204ae2f668c53
This commit is contained in:
commit
7ff5d522bf
@ -24,12 +24,22 @@
|
||||
*/
|
||||
void usage(const char *zArgv0){
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-step NSTEP] TARGET-DB RBU-DB\n"
|
||||
"Usage: %s ?OPTIONS? TARGET-DB RBU-DB\n"
|
||||
"\n"
|
||||
" Argument RBU-DB must be an RBU database containing an update suitable for\n"
|
||||
" target database TARGET-DB. If NSTEP is set to less than or equal to zero\n"
|
||||
" (the default value), this program attempts to apply the entire update to\n"
|
||||
" the target database.\n"
|
||||
"Where options are:\n"
|
||||
"\n"
|
||||
" -step NSTEP\n"
|
||||
" -vacuum\n"
|
||||
"\n"
|
||||
" If the -vacuum switch is not present, argument RBU-DB must be an RBU\n"
|
||||
" database containing an update suitable for target database TARGET-DB.\n"
|
||||
" Or, if -vacuum is specified, then TARGET-DB is a database to vacuum using\n"
|
||||
" RBU, and RBU-DB is used as the state database for the vacuum (refer to\n"
|
||||
" API documentation for details).\n"
|
||||
"\n"
|
||||
" If NSTEP is set to less than or equal to zero (the default value), this \n"
|
||||
" program attempts to perform the entire update or vacuum operation before\n"
|
||||
" exiting\n"
|
||||
"\n"
|
||||
" If NSTEP is greater than zero, then a maximum of NSTEP calls are made\n"
|
||||
" to sqlite3rbu_step(). If the RBU update has not been completely applied\n"
|
||||
@ -69,29 +79,43 @@ int main(int argc, char **argv){
|
||||
char *zErrmsg; /* Error message, if any */
|
||||
sqlite3rbu *pRbu; /* RBU handle */
|
||||
int nStep = 0; /* Maximum number of step() calls */
|
||||
int bVacuum = 0;
|
||||
int rc;
|
||||
sqlite3_int64 nProgress = 0;
|
||||
int nArg = argc-2;
|
||||
|
||||
/* Process command line arguments. Following this block local variables
|
||||
** zTarget, zRbu and nStep are all set. */
|
||||
if( argc==5 ){
|
||||
size_t nArg1 = strlen(argv[1]);
|
||||
if( nArg1>5 || nArg1<2 || memcmp("-step", argv[1], nArg1) ) usage(argv[0]);
|
||||
nStep = atoi(argv[2]);
|
||||
}else if( argc!=3 ){
|
||||
usage(argv[0]);
|
||||
if( argc<3 ) usage(argv[0]);
|
||||
for(i=1; i<nArg; i++){
|
||||
const char *zArg = argv[i];
|
||||
int nArg = strlen(zArg);
|
||||
if( nArg>1 && nArg<=8 && 0==memcmp(zArg, "-vacuum", nArg) ){
|
||||
bVacuum = 1;
|
||||
}else if( nArg>1 && nArg<=5 && 0==memcmp(zArg, "-step", nArg) && i<nArg-1 ){
|
||||
i++;
|
||||
nStep = atoi(argv[i]);
|
||||
}else{
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
zTarget = argv[argc-2];
|
||||
zRbu = argv[argc-1];
|
||||
|
||||
report_default_vfs();
|
||||
|
||||
/* Open an RBU handle. If nStep is less than or equal to zero, call
|
||||
/* Open an RBU handle. A vacuum handle if -vacuum was specified, or a
|
||||
** regular RBU update handle otherwise. */
|
||||
if( bVacuum ){
|
||||
pRbu = sqlite3rbu_vacuum(zTarget, zRbu);
|
||||
}else{
|
||||
pRbu = sqlite3rbu_open(zTarget, zRbu, 0);
|
||||
}
|
||||
report_rbu_vfs(pRbu);
|
||||
|
||||
/* If nStep is less than or equal to zero, call
|
||||
** sqlite3rbu_step() until either the RBU has been completely applied
|
||||
** or an error occurs. Or, if nStep is greater than zero, call
|
||||
** sqlite3rbu_step() a maximum of nStep times. */
|
||||
pRbu = sqlite3rbu_open(zTarget, zRbu, 0);
|
||||
report_rbu_vfs(pRbu);
|
||||
for(i=0; (nStep<=0 || i<nStep) && sqlite3rbu_step(pRbu)==SQLITE_OK; i++);
|
||||
nProgress = sqlite3rbu_progress(pRbu);
|
||||
rc = sqlite3rbu_close(pRbu, &zErrmsg);
|
||||
|
98
ext/rbu/rbufault3.test
Normal file
98
ext/rbu/rbufault3.test
Normal file
@ -0,0 +1,98 @@
|
||||
# 2016 April 20
|
||||
#
|
||||
# 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 contains fault injection tests for RBU vacuum operations.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||
source $testdir/malloc_common.tcl
|
||||
set ::testprefix rbufault3
|
||||
|
||||
foreach {fault errlist} {
|
||||
oom-* {
|
||||
{1 SQLITE_NOMEM}
|
||||
{1 SQLITE_IOERR_NOMEM}
|
||||
{1 {SQLITE_NOMEM - out of memory}}
|
||||
}
|
||||
|
||||
ioerr-* {
|
||||
{1 {SQLITE_IOERR - disk I/O error}}
|
||||
{1 SQLITE_IOERR}
|
||||
{1 SQLITE_IOERR_WRITE}
|
||||
{1 SQLITE_IOERR_FSYNC}
|
||||
{1 SQLITE_IOERR_READ}
|
||||
{1 {SQLITE_IOERR - unable to open database: test.db2}}
|
||||
{1 {SQLITE_ERROR - unable to open database: test.db2}}
|
||||
{1 {SQLITE_ERROR - SQL logic error or missing database}}
|
||||
}
|
||||
|
||||
cantopen* {
|
||||
{1 {SQLITE_CANTOPEN - unable to open database: test.db2}}
|
||||
{1 {SQLITE_CANTOPEN - unable to open database: test.db2}}
|
||||
{1 {SQLITE_CANTOPEN - unable to open database file}}
|
||||
{1 SQLITE_CANTOPEN}
|
||||
}
|
||||
|
||||
} {
|
||||
|
||||
reset_db
|
||||
do_execsql_test 0 {
|
||||
CREATE TABLE target(x UNIQUE, y, z, PRIMARY KEY(y));
|
||||
INSERT INTO target VALUES(1, 2, 3);
|
||||
INSERT INTO target VALUES(4, 5, 6);
|
||||
INSERT INTO target VALUES(7, 8, 9);
|
||||
CREATE INDEX i1 ON target(z);
|
||||
}
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 1 -faults $fault -prep {
|
||||
faultsim_restore_and_reopen
|
||||
forcedelete test.db2
|
||||
} -body {
|
||||
sqlite3rbu_vacuum rbu test.db test.db2
|
||||
while {[rbu step]=="SQLITE_OK"} {}
|
||||
rbu close
|
||||
} -test {
|
||||
eval [list faultsim_test_result {0 SQLITE_DONE} {*}$::errlist]
|
||||
}
|
||||
|
||||
do_faultsim_test 2 -faults $fault -prep {
|
||||
faultsim_restore_and_reopen
|
||||
forcedelete test.db2
|
||||
} -body {
|
||||
sqlite3rbu_vacuum rbu test.db test.db2
|
||||
rbu step
|
||||
rbu close
|
||||
} -test {
|
||||
eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
|
||||
}
|
||||
|
||||
forcedelete test.db2
|
||||
sqlite3rbu_vacuum rbu test.db test.db2
|
||||
rbu step
|
||||
rbu close
|
||||
faultsim_save_and_close
|
||||
|
||||
do_faultsim_test 3 -faults $fault -prep {
|
||||
faultsim_restore_and_reopen
|
||||
forcedelete test.db2
|
||||
} -body {
|
||||
sqlite3rbu_vacuum rbu test.db test.db2
|
||||
rbu step
|
||||
rbu close
|
||||
} -test {
|
||||
eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
315
ext/rbu/rbuvacuum.test
Normal file
315
ext/rbu/rbuvacuum.test
Normal file
@ -0,0 +1,315 @@
|
||||
# 2016 April 15
|
||||
#
|
||||
# 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 contains tests for the RBU module. More specifically, it
|
||||
# contains tests to ensure that the sqlite3rbu_vacuum() API works as
|
||||
# expected.
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||
set ::testprefix rbuvacuum
|
||||
|
||||
proc do_rbu_vacuum_test {tn step} {
|
||||
uplevel [list do_test $tn.1 {
|
||||
if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db }
|
||||
while 1 {
|
||||
if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db }
|
||||
set rc [rbu step]
|
||||
if {$rc!="SQLITE_OK"} break
|
||||
if {$step==1} { rbu close }
|
||||
}
|
||||
rbu close
|
||||
} {SQLITE_DONE}]
|
||||
|
||||
uplevel [list do_execsql_test $tn.2 {
|
||||
PRAGMA integrity_check
|
||||
} ok]
|
||||
}
|
||||
|
||||
foreach step {0 1} {
|
||||
|
||||
set ::testprefix rbuvacuum-step=$step
|
||||
reset_db
|
||||
|
||||
# Simplest possible vacuum.
|
||||
do_execsql_test 1.0 {
|
||||
PRAGMA page_size = 1024;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
INSERT INTO t1 VALUES(1, 2, 3);
|
||||
INSERT INTO t1 VALUES(4, 5, 6);
|
||||
INSERT INTO t1 VALUES(7, 8, 9);
|
||||
PRAGMA integrity_check;
|
||||
} {ok}
|
||||
do_rbu_vacuum_test 1.1 $step
|
||||
|
||||
# A vacuum that actually reclaims space.
|
||||
do_execsql_test 1.2.1 {
|
||||
INSERT INTO t1 VALUES(8, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(9, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(10, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(11, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(12, randomblob(900), randomblob(900));
|
||||
PRAGMA page_count;
|
||||
} {12}
|
||||
do_execsql_test 1.2.2 {
|
||||
DELETE FROM t1 WHERE rowid BETWEEN 8 AND 11;
|
||||
PRAGMA page_count;
|
||||
} {12}
|
||||
do_rbu_vacuum_test 1.2.3 $step
|
||||
do_execsql_test 1.2.4 {
|
||||
PRAGMA page_count;
|
||||
} {3}
|
||||
|
||||
# Add an index to the table.
|
||||
do_execsql_test 1.3.1 {
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
INSERT INTO t1 VALUES(13, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(14, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(15, randomblob(900), randomblob(900));
|
||||
INSERT INTO t1 VALUES(16, randomblob(900), randomblob(900));
|
||||
PRAGMA page_count;
|
||||
} {18}
|
||||
do_execsql_test 1.3.2 {
|
||||
DELETE FROM t1 WHERE rowid BETWEEN 12 AND 15;
|
||||
PRAGMA page_count;
|
||||
} {18}
|
||||
do_rbu_vacuum_test 1.3.3 $step
|
||||
do_execsql_test 1.3.4 {
|
||||
PRAGMA page_count;
|
||||
} {5}
|
||||
|
||||
# WITHOUT ROWID table.
|
||||
do_execsql_test 1.4.1 {
|
||||
CREATE TABLE t2(a, b, c, PRIMARY KEY(a, b)) WITHOUT ROWID;
|
||||
|
||||
INSERT INTO t2 VALUES(randomblob(900), 1, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 2, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 3, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 4, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 6, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 7, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 8, randomblob(900));
|
||||
|
||||
DELETE FROM t2 WHERE b BETWEEN 2 AND 7;
|
||||
PRAGMA page_count;
|
||||
} {20}
|
||||
do_rbu_vacuum_test 1.4.2 $step
|
||||
do_execsql_test 1.4.3 {
|
||||
PRAGMA page_count;
|
||||
} {10}
|
||||
|
||||
# WITHOUT ROWID table with an index.
|
||||
do_execsql_test 1.4.1 {
|
||||
CREATE INDEX t2c ON t2(c);
|
||||
|
||||
INSERT INTO t2 VALUES(randomblob(900), 9, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 10, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 11, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 12, randomblob(900));
|
||||
INSERT INTO t2 VALUES(randomblob(900), 13, randomblob(900));
|
||||
|
||||
DELETE FROM t2 WHERE b BETWEEN 8 AND 12;
|
||||
PRAGMA page_count;
|
||||
} {35}
|
||||
do_rbu_vacuum_test 1.4.2 $step
|
||||
do_execsql_test 1.4.3 {
|
||||
PRAGMA page_count;
|
||||
} {15}
|
||||
do_execsql_test 1.4.4 {
|
||||
VACUUM;
|
||||
PRAGMA page_count;
|
||||
} {15}
|
||||
|
||||
do_execsql_test 1.5.1 {
|
||||
CREATE TABLE t3(a, b, c);
|
||||
INSERT INTO t3 VALUES('a', 'b', 'c');
|
||||
INSERT INTO t3 VALUES('d', 'e', 'f');
|
||||
INSERT INTO t3 VALUES('g', 'h', 'i');
|
||||
}
|
||||
do_rbu_vacuum_test 1.5.2 $step
|
||||
do_execsql_test 1.5.3 {
|
||||
SELECT * FROM t3
|
||||
} {a b c d e f g h i}
|
||||
do_execsql_test 1.5.4 {
|
||||
CREATE INDEX t3a ON t3(a);
|
||||
CREATE INDEX t3b ON t3(b);
|
||||
CREATE INDEX t3c ON t3(c);
|
||||
INSERT INTO t3 VALUES('j', 'k', 'l');
|
||||
DELETE FROM t3 WHERE a = 'g';
|
||||
}
|
||||
do_rbu_vacuum_test 1.5.5 $step
|
||||
do_execsql_test 1.5.6 {
|
||||
SELECT rowid, * FROM t3 ORDER BY b
|
||||
} {1 a b c 2 d e f 4 j k l}
|
||||
|
||||
do_execsql_test 1.6.1 {
|
||||
CREATE TABLE t4(a PRIMARY KEY, b, c);
|
||||
INSERT INTO t4 VALUES('a', 'b', 'c');
|
||||
INSERT INTO t4 VALUES('d', 'e', 'f');
|
||||
INSERT INTO t4 VALUES('g', 'h', 'i');
|
||||
}
|
||||
do_rbu_vacuum_test 1.6.2 $step
|
||||
do_execsql_test 1.6.3 {
|
||||
SELECT * FROM t4
|
||||
} {a b c d e f g h i}
|
||||
do_execsql_test 1.6.4 {
|
||||
CREATE INDEX t4a ON t4(a);
|
||||
CREATE INDEX t4b ON t4(b);
|
||||
CREATE INDEX t4c ON t4(c);
|
||||
|
||||
INSERT INTO t4 VALUES('j', 'k', 'l');
|
||||
DELETE FROM t4 WHERE a='g';
|
||||
}
|
||||
do_rbu_vacuum_test 1.6.5 $step
|
||||
do_execsql_test 1.6.6 {
|
||||
SELECT * FROM t4 ORDER BY b
|
||||
} {a b c d e f j k l}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 1.7.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||
INSERT INTO t1 VALUES(NULL, 'one');
|
||||
INSERT INTO t1 VALUES(NULL, 'two');
|
||||
DELETE FROM t1 WHERE a=2;
|
||||
INSERT INTO t1 VALUES(NULL, 'three');
|
||||
INSERT INTO t1 VALUES(NULL, 'four');
|
||||
DELETE FROM t1 WHERE a=4;
|
||||
INSERT INTO t1 VALUES(NULL, 'five');
|
||||
INSERT INTO t1 VALUES(NULL, 'six');
|
||||
DELETE FROM t1 WHERE a=6;
|
||||
SELECT * FROM t1;
|
||||
} {1 one 3 three 5 five}
|
||||
do_rbu_vacuum_test 1.7.1 $step
|
||||
do_execsql_test 1.7.2 {
|
||||
INSERT INTO t1 VALUES(NULL, 'seven');
|
||||
SELECT * FROM t1;
|
||||
} {1 one 3 three 5 five 7 seven}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 1.8.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||
CREATE INDEX i1 ON t1(b);
|
||||
INSERT INTO t1 VALUES(NULL, 'one');
|
||||
INSERT INTO t1 VALUES(NULL, 'two');
|
||||
INSERT INTO t1 VALUES(NULL, 'three');
|
||||
INSERT INTO t1 VALUES(NULL, 'four');
|
||||
INSERT INTO t1 VALUES(NULL, 'five');
|
||||
INSERT INTO t1 VALUES(NULL, 'six');
|
||||
ANALYZE;
|
||||
SELECT * FROM sqlite_stat1;
|
||||
} {t1 i1 {6 1}}
|
||||
do_rbu_vacuum_test 1.8.1 $step
|
||||
do_execsql_test 1.7.2 {
|
||||
SELECT * FROM sqlite_stat1;
|
||||
} {t1 i1 {6 1}}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 1.9.0 {
|
||||
PRAGMA page_size = 8192;
|
||||
PRAGMA auto_vacuum = 2;
|
||||
PRAGMA user_version = 412;
|
||||
PRAGMA application_id = 413;
|
||||
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b);
|
||||
CREATE INDEX i1 ON t1(b);
|
||||
INSERT INTO t1 VALUES(NULL, 'one');
|
||||
INSERT INTO t1 VALUES(NULL, 'two');
|
||||
INSERT INTO t1 VALUES(NULL, 'three');
|
||||
INSERT INTO t1 VALUES(NULL, 'four');
|
||||
INSERT INTO t1 VALUES(NULL, 'five');
|
||||
INSERT INTO t1 VALUES(NULL, 'six');
|
||||
|
||||
PRAGMA main.page_size;
|
||||
PRAGMA main.auto_vacuum;
|
||||
PRAGMA main.user_version;
|
||||
PRAGMA main.application_id;
|
||||
} {8192 2 412 413}
|
||||
|
||||
do_rbu_vacuum_test 1.9.1 $step
|
||||
do_execsql_test 1.9.2 {
|
||||
PRAGMA main.page_size;
|
||||
PRAGMA main.auto_vacuum;
|
||||
PRAGMA main.user_version;
|
||||
PRAGMA main.application_id;
|
||||
} {8192 2 412 413}
|
||||
|
||||
# Vacuum a database with a large sqlite_master table.
|
||||
#
|
||||
reset_db
|
||||
do_test 1.10.1 {
|
||||
for {set i 1} {$i < 50} {incr i} {
|
||||
execsql "PRAGMA page_size = 1024"
|
||||
execsql "CREATE TABLE t$i (a, b, c, PRIMARY KEY(a, b));"
|
||||
execsql "
|
||||
INSERT INTO t$i VALUES(1, 2, 3);
|
||||
INSERT INTO t$i VALUES(4, 5, 6);
|
||||
"
|
||||
}
|
||||
} {}
|
||||
do_rbu_vacuum_test 1.10.2 $step
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test some error cases:
|
||||
#
|
||||
# 2.1.* the db being vacuumed being in wal mode already.
|
||||
# 2.2.* database modified mid vacuum.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 2.1.0 {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
INSERT INTO t1 VALUES(3, 4);
|
||||
INSERT INTO t1 VALUES(5, 6);
|
||||
INSERT INTO t1 VALUES(7, 8);
|
||||
PRAGMA journal_mode = wal;
|
||||
INSERT INTO t1 VALUES(9, 10);
|
||||
} wal
|
||||
do_test 2.1.1 {
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
rbu step
|
||||
} {SQLITE_ERROR}
|
||||
do_test 2.1.2 {
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {1 {SQLITE_ERROR - cannot vacuum wal mode database}}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 2.2.0 {
|
||||
CREATE TABLE tx(a PRIMARY KEY, b BLOB);
|
||||
INSERT INTO tx VALUES(1, randomblob(900));
|
||||
INSERT INTO tx SELECT a+1, randomblob(900) FROM tx;
|
||||
INSERT INTO tx SELECT a+2, randomblob(900) FROM tx;
|
||||
INSERT INTO tx SELECT a+4, randomblob(900) FROM tx;
|
||||
INSERT INTO tx SELECT a+8, randomblob(900) FROM tx;
|
||||
}
|
||||
db_save_and_close
|
||||
for {set i 1} 1 {incr i} {
|
||||
db_restore_and_reopen
|
||||
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
for {set step 0} {$step<$i} {incr step} { rbu step }
|
||||
rbu close
|
||||
if {[file exists test.db-wal]} break
|
||||
|
||||
execsql { INSERT INTO tx VALUES(20, 20) }
|
||||
|
||||
do_test 2.2.$i.1 {
|
||||
sqlite3rbu_vacuum rbu test.db state.db
|
||||
rbu step
|
||||
} {SQLITE_BUSY}
|
||||
do_test 2.2.$i.2 {
|
||||
list [catch { rbu close } msg] $msg
|
||||
} {1 {SQLITE_BUSY - database modified during rbu vacuum}}
|
||||
}
|
||||
|
||||
catch { db close }
|
||||
finish_test
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -314,6 +314,38 @@ sqlite3rbu *sqlite3rbu_open(
|
||||
const char *zState
|
||||
);
|
||||
|
||||
/*
|
||||
** Open an RBU handle to perform an RBU vacuum on database file zTarget.
|
||||
** An RBU vacuum is similar to SQLite's built-in VACUUM command, except
|
||||
** that it can be suspended and resumed like an RBU update.
|
||||
**
|
||||
** The second argument to this function, which may not be NULL, identifies
|
||||
** a database in which to store the state of the RBU vacuum operation if
|
||||
** it is suspended. The first time sqlite3rbu_vacuum() is called, to start
|
||||
** an RBU vacuum operation, the state database should either not exist or
|
||||
** be empty (contain no tables). If an RBU vacuum is suspended by calling
|
||||
** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has
|
||||
** returned SQLITE_DONE, the vacuum state is stored in the state database.
|
||||
** The vacuum can be resumed by calling this function to open a new RBU
|
||||
** handle specifying the same target and state databases.
|
||||
**
|
||||
** This function does not delete the state database after an RBU vacuum
|
||||
** is completed, even if it created it. However, if the call to
|
||||
** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents
|
||||
** of the state tables within the state database are zeroed. This way,
|
||||
** the next call to sqlite3rbu_vacuum() opens a handle that starts a
|
||||
** new RBU vacuum operation.
|
||||
**
|
||||
** As with sqlite3rbu_open(), Zipvfs users should rever to the comment
|
||||
** describing the sqlite3rbu_create_vfs() API function below for
|
||||
** a description of the complications associated with using RBU with
|
||||
** zipvfs databases.
|
||||
*/
|
||||
sqlite3rbu *sqlite3rbu_vacuum(
|
||||
const char *zTarget,
|
||||
const char *zState
|
||||
);
|
||||
|
||||
/*
|
||||
** Internally, each RBU connection uses a separate SQLite database
|
||||
** connection to access the target and rbu update databases. This
|
||||
|
@ -187,6 +187,34 @@ static int test_sqlite3rbu(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Tclcmd: sqlite3rbu_vacuum CMD <target-db> <state-db>
|
||||
*/
|
||||
static int test_sqlite3rbu_vacuum(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3rbu *pRbu = 0;
|
||||
const char *zCmd;
|
||||
const char *zTarget;
|
||||
const char *zStateDb = 0;
|
||||
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB STATE-DB");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zCmd = Tcl_GetString(objv[1]);
|
||||
zTarget = Tcl_GetString(objv[2]);
|
||||
zStateDb = Tcl_GetString(objv[3]);
|
||||
|
||||
pRbu = sqlite3rbu_vacuum(zTarget, zStateDb);
|
||||
Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pRbu, 0);
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Tclcmd: sqlite3rbu_create_vfs ?-default? NAME PARENT
|
||||
*/
|
||||
@ -274,6 +302,7 @@ int SqliteRbu_Init(Tcl_Interp *interp){
|
||||
Tcl_ObjCmdProc *xProc;
|
||||
} aObjCmd[] = {
|
||||
{ "sqlite3rbu", test_sqlite3rbu },
|
||||
{ "sqlite3rbu_vacuum", test_sqlite3rbu_vacuum },
|
||||
{ "sqlite3rbu_create_vfs", test_sqlite3rbu_create_vfs },
|
||||
{ "sqlite3rbu_destroy_vfs", test_sqlite3rbu_destroy_vfs },
|
||||
{ "sqlite3rbu_internal_test", test_sqlite3rbu_internal_test },
|
||||
|
26
manifest
26
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sa\sproblem\swith\smixing\stemp-files\sand\smmap-mode.
|
||||
D 2016-04-23T17:24:16.091
|
||||
C Merge\sthe\slatest\strunk\schanges.
|
||||
D 2016-04-23T19:55:59.305
|
||||
F Makefile.in eba680121821b8a60940a81454316f47a341487a
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
|
||||
@ -222,7 +222,7 @@ F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
|
||||
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
F ext/rbu/rbu.c ba3983dceffa0938532e79142f391737513de023
|
||||
F ext/rbu/rbu.c b2c0b5e6ae1a89affc0edfc127ebfa5f637a0ce4
|
||||
F ext/rbu/rbu1.test 42bd835e019eff789ec241017965277baeb658b1
|
||||
F ext/rbu/rbu10.test 046b0980041d30700464a800bbf6733ed2df515d
|
||||
F ext/rbu/rbu11.test 9bc68c2d3dbeb1720153626e3bd0466dcc017702
|
||||
@ -243,12 +243,14 @@ F ext/rbu/rbucrash.test 8d2ed5d4b05fef6c00c2a6b5f7ead71fa172a695
|
||||
F ext/rbu/rbudiff.test 2df0a8a7d998ecf81764c21eeda3cde5611c5091
|
||||
F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
|
||||
F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
|
||||
F ext/rbu/rbufault3.test 54a399888ac4af44c68f9f58afbed23149428bca
|
||||
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
|
||||
F ext/rbu/rbuprogress.test 2023a7df2c523e3df1cb532eff811cda385a789a
|
||||
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
|
||||
F ext/rbu/sqlite3rbu.c 9097f1d95666dbef72ca61d5b6a13a84660735ac
|
||||
F ext/rbu/sqlite3rbu.h d7cc99350c10134f358fe1a8997d9225b3f712b2
|
||||
F ext/rbu/test_rbu.c 3505641a78b723589b8780d5f9b2faeeb73e037d
|
||||
F ext/rbu/rbuvacuum.test bcbc1dcd8e2a46a811e46477692ae1c0e8917a85
|
||||
F ext/rbu/sqlite3rbu.c 20922328dcebe89589638923bb46840df8bc7733
|
||||
F ext/rbu/sqlite3rbu.h 2acd0a6344a6079de15c8dc9d84d3df83a665930
|
||||
F ext/rbu/test_rbu.c 430b8b9520c233505371d564d3561e0b554355f4
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
@ -329,7 +331,7 @@ F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
|
||||
F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39
|
||||
F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b
|
||||
F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e
|
||||
F src/expr.c 17d4e745ef6a3fd2e4ef863f5f9a4912f1ba1198
|
||||
F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb
|
||||
F src/func.c ef4c18c8a66143413ce41a58d582d2c14ddf78e1
|
||||
@ -359,7 +361,7 @@ F src/os.c 4d83917f072ad958fba9235136fa2ed43df47905
|
||||
F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c d0b41a47eb5f0dc00e423a1723aadeab0e78c85f
|
||||
F src/os_unix.c c96826e21e897bf9c6ae896be9de8d55d63a4ed5
|
||||
F src/os_win.c 1997a873bfc8296a701bd8e2df8c3d5da5afe956
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c cbc8996b773c191107b771424b529307ffdf19ba
|
||||
@ -1484,7 +1486,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 3d61da4a76af8c9c2a293df085f3ed5a7bb447df
|
||||
R 85df4f851dc9e804fc35d28f4dbcf65b
|
||||
U dan
|
||||
Z 50e48f2ab5de65ac7aff6f1c82162e94
|
||||
P c80c5c62b2e2c5e47e0839f8e2d5b6341ca4a249 67985761aa93fb613b87d340e75371fa55b0f778
|
||||
R 473533ddbe833125ff0b6528c3bf66ad
|
||||
U drh
|
||||
Z ff31dea9151360cfbdfa017e3af26788
|
||||
|
@ -1 +1 @@
|
||||
c80c5c62b2e2c5e47e0839f8e2d5b6341ca4a249
|
||||
84da122dd6e70ed603fea781dca204ae2f668c53
|
@ -2360,7 +2360,7 @@ static void cacheEntryClear(Parse *pParse, struct yColCache *p){
|
||||
}
|
||||
p->iReg = 0;
|
||||
pParse->nColCache--;
|
||||
assert( cacheIsValid(pParse) );
|
||||
assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
|
||||
}
|
||||
|
||||
|
||||
@ -2405,7 +2405,7 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
|
||||
p->tempReg = 0;
|
||||
p->lru = pParse->iCacheCnt++;
|
||||
pParse->nColCache++;
|
||||
assert( cacheIsValid(pParse) );
|
||||
assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -5420,10 +5420,10 @@ static const char *unixTempFileDir(void){
|
||||
if( zDir==0 ) continue;
|
||||
if( osStat(zDir, &buf) ) continue;
|
||||
if( !S_ISDIR(buf.st_mode) ) continue;
|
||||
if( osAccess(zDir, 07) ) continue;
|
||||
break;
|
||||
if( osAccess(zDir, 03) ) continue;
|
||||
return zDir;
|
||||
}
|
||||
return zDir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5439,9 +5439,11 @@ static int unixGetTempname(int nBuf, char *zBuf){
|
||||
** using the io-error infrastructure to test that SQLite handles this
|
||||
** function failing.
|
||||
*/
|
||||
zBuf[0] = 0;
|
||||
SimulateIOError( return SQLITE_IOERR );
|
||||
|
||||
zDir = unixTempFileDir();
|
||||
if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH;
|
||||
do{
|
||||
u64 r;
|
||||
sqlite3_randomness(sizeof(r), &r);
|
||||
|
Loading…
x
Reference in New Issue
Block a user