Add an API to indicate the percentage progress of an rbu update.
FossilOrigin-Name: ffc58d2c2576a5b6e1c2c7112612c5760e711afd
This commit is contained in:
parent
4b058dd4d1
commit
e42195b044
179
ext/rbu/rbuprogress.test
Normal file
179
ext/rbu/rbuprogress.test
Normal file
@ -0,0 +1,179 @@
|
||||
# 2016 March 18
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||
set ::testprefix rbuprogress
|
||||
|
||||
|
||||
# Create a simple RBU database. That expects to write to a table:
|
||||
#
|
||||
# CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
#
|
||||
proc create_rbu1 {filename} {
|
||||
forcedelete $filename
|
||||
sqlite3 rbu1 $filename
|
||||
rbu1 eval {
|
||||
CREATE TABLE data_t1(a, b, c, rbu_control);
|
||||
INSERT INTO data_t1 VALUES(1, 2, 3, 0);
|
||||
INSERT INTO data_t1 VALUES(2, 'two', 'three', 0);
|
||||
INSERT INTO data_t1 VALUES(3, NULL, 8.2, 0);
|
||||
|
||||
CREATE TABLE rbu_count(tbl, cnt);
|
||||
INSERT INTO rbu_count VALUES('data_t1', 3);
|
||||
}
|
||||
rbu1 close
|
||||
return $filename
|
||||
}
|
||||
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
}
|
||||
|
||||
do_test 1.1 {
|
||||
create_rbu1 rbu.db
|
||||
sqlite3rbu rbu test.db rbu.db
|
||||
rbu stage_progress
|
||||
} {0 0}
|
||||
do_test 1.2 { rbu step ; rbu stage_progress } {3333 0}
|
||||
do_test 1.3 { rbu step ; rbu stage_progress } {6666 0}
|
||||
do_test 1.4 { rbu step ; rbu stage_progress } {10000 0}
|
||||
do_test 1.5 { rbu step ; rbu stage_progress } {10000 0}
|
||||
do_test 1.6 { rbu step ; rbu stage_progress } {10000 0}
|
||||
do_test 1.7 { rbu step ; rbu stage_progress } {10000 5000}
|
||||
do_test 1.8 { rbu step ; rbu stage_progress } {10000 10000}
|
||||
do_test 1.9 { rbu step ; rbu stage_progress } {10000 10000}
|
||||
|
||||
do_test 1.10 {
|
||||
rbu close
|
||||
} {SQLITE_DONE}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
proc do_sp_test {tn target rbu reslist} {
|
||||
uplevel [list do_test $tn [subst -nocommands {
|
||||
sqlite3rbu rbu $target $rbu
|
||||
set res [list]
|
||||
while 1 {
|
||||
set rc [rbu step]
|
||||
if {[set rc] != "SQLITE_OK"} { error "error 1" }
|
||||
lappend res [lindex [rbu stage_progress] 0]
|
||||
if {[lindex [set res] end]==10000} break
|
||||
}
|
||||
if {[set res] != [list $reslist]} {
|
||||
error "reslist is incorrect (expect=$reslist got=[set res])"
|
||||
}
|
||||
|
||||
# One step to clean up the temporary tables used to update the only
|
||||
# target table in the rbu database. And one more to move the *-oal
|
||||
# file to *-wal.
|
||||
rbu step
|
||||
rbu step
|
||||
|
||||
# Do the checkpoint.
|
||||
while {[rbu step]=="SQLITE_OK"} { }
|
||||
|
||||
rbu close
|
||||
}] {SQLITE_DONE}]
|
||||
}
|
||||
|
||||
proc create_db_file {filename sql} {
|
||||
forcedelete $filename
|
||||
sqlite3 tmpdb $filename
|
||||
tmpdb eval $sql
|
||||
tmpdb close
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_test 2.1.0 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
}
|
||||
create_db_file rbu.db {
|
||||
CREATE TABLE data_t1(a, b, c, rbu_control);
|
||||
INSERT INTO data_t1 VALUES(4, 4, 4, 0);
|
||||
INSERT INTO data_t1 VALUES(5, 5, 5, 0);
|
||||
|
||||
CREATE TABLE rbu_count(tbl, cnt);
|
||||
INSERT INTO rbu_count VALUES('data_t1', 2);
|
||||
}
|
||||
} {}
|
||||
do_sp_test 2.1.1 test.db rbu.db {5000 10000}
|
||||
|
||||
reset_db
|
||||
do_test 2.2.0 {
|
||||
execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c) }
|
||||
create_rbu1 rbu.db
|
||||
} {rbu.db}
|
||||
do_sp_test 2.2.1 test.db rbu.db {3333 6666 10000}
|
||||
|
||||
reset_db
|
||||
do_test 2.3.0 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
CREATE INDEX i1 ON t1(b);
|
||||
INSERT INTO t1 VALUES(1, 1, 1);
|
||||
INSERT INTO t1 VALUES(2, 2, 2);
|
||||
INSERT INTO t1 VALUES(3, 3, 3);
|
||||
}
|
||||
create_db_file rbu.db {
|
||||
CREATE TABLE data_t1(a, b, c, rbu_control);
|
||||
INSERT INTO data_t1 VALUES(4, 4, 4, 0);
|
||||
INSERT INTO data_t1 VALUES(2, NULL, NULL, 1);
|
||||
INSERT INTO data_t1 VALUES(5, NULL, NULL, 1);
|
||||
|
||||
CREATE TABLE rbu_count(tbl, cnt);
|
||||
INSERT INTO rbu_count VALUES('data_t1', 3);
|
||||
}
|
||||
} {}
|
||||
do_sp_test 2.3.1 test.db rbu.db {1666 3333 6000 8000 10000}
|
||||
|
||||
reset_db
|
||||
do_test 2.4.0 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
CREATE INDEX i1 ON t1(b);
|
||||
INSERT INTO t1 VALUES(1, 1, 1);
|
||||
INSERT INTO t1 VALUES(2, 2, 2);
|
||||
INSERT INTO t1 VALUES(3, 3, 3);
|
||||
}
|
||||
create_db_file rbu.db {
|
||||
CREATE TABLE data_t1(a, b, c, rbu_control);
|
||||
INSERT INTO data_t1 VALUES(2, 4, 4, '.xx');
|
||||
|
||||
CREATE TABLE rbu_count(tbl, cnt);
|
||||
INSERT INTO rbu_count VALUES('data_t1', 1);
|
||||
}
|
||||
} {}
|
||||
do_sp_test 2.4.1 test.db rbu.db {3333 6666 10000}
|
||||
|
||||
reset_db
|
||||
do_test 2.5.0 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
CREATE INDEX i1 ON t1(b);
|
||||
INSERT INTO t1 VALUES(1, 1, 1);
|
||||
INSERT INTO t1 VALUES(2, 2, 2);
|
||||
INSERT INTO t1 VALUES(3, 3, 3);
|
||||
}
|
||||
create_db_file rbu.db {
|
||||
CREATE TABLE data_t1(a, b, c, rbu_control);
|
||||
INSERT INTO data_t1 VALUES(4, NULL, 4, '.xx');
|
||||
|
||||
CREATE TABLE rbu_count(tbl, cnt);
|
||||
INSERT INTO rbu_count VALUES('data_t1', 1);
|
||||
}
|
||||
} {}
|
||||
do_sp_test 2.5.1 test.db rbu.db {10000}
|
||||
|
||||
finish_test
|
||||
|
@ -147,14 +147,15 @@
|
||||
** RBU_STATE_OALSZ:
|
||||
** Valid if STAGE==1. The size in bytes of the *-oal file.
|
||||
*/
|
||||
#define RBU_STATE_STAGE 1
|
||||
#define RBU_STATE_TBL 2
|
||||
#define RBU_STATE_IDX 3
|
||||
#define RBU_STATE_ROW 4
|
||||
#define RBU_STATE_PROGRESS 5
|
||||
#define RBU_STATE_CKPT 6
|
||||
#define RBU_STATE_COOKIE 7
|
||||
#define RBU_STATE_OALSZ 8
|
||||
#define RBU_STATE_STAGE 1
|
||||
#define RBU_STATE_TBL 2
|
||||
#define RBU_STATE_IDX 3
|
||||
#define RBU_STATE_ROW 4
|
||||
#define RBU_STATE_PROGRESS 5
|
||||
#define RBU_STATE_CKPT 6
|
||||
#define RBU_STATE_COOKIE 7
|
||||
#define RBU_STATE_OALSZ 8
|
||||
#define RBU_STATE_PHASEONESTEP 9
|
||||
|
||||
#define RBU_STAGE_OAL 1
|
||||
#define RBU_STAGE_MOVE 2
|
||||
@ -200,6 +201,7 @@ struct RbuState {
|
||||
i64 nProgress;
|
||||
u32 iCookie;
|
||||
i64 iOalSz;
|
||||
i64 nPhaseOneStep;
|
||||
};
|
||||
|
||||
struct RbuUpdateStmt {
|
||||
@ -244,6 +246,7 @@ struct RbuObjIter {
|
||||
int iTnum; /* Root page of current object */
|
||||
int iPkTnum; /* If eType==EXTERNAL, root of PK index */
|
||||
int bUnique; /* Current index is unique */
|
||||
int nIndex; /* Number of aux. indexes on table zTbl */
|
||||
|
||||
/* Statements created by rbuObjIterPrepareAll() */
|
||||
int nCol; /* Number of columns in current object */
|
||||
@ -314,6 +317,7 @@ struct sqlite3rbu {
|
||||
const char *zVfsName; /* Name of automatically created rbu vfs */
|
||||
rbu_file *pTargetFd; /* File handle open on target db */
|
||||
i64 iOalSz;
|
||||
i64 nPhaseOneStep;
|
||||
|
||||
/* The following state variables are used as part of the incremental
|
||||
** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding
|
||||
@ -1144,6 +1148,7 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){
|
||||
);
|
||||
}
|
||||
|
||||
pIter->nIndex = 0;
|
||||
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
|
||||
const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
|
||||
sqlite3_stmt *pXInfo = 0;
|
||||
@ -1157,6 +1162,7 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){
|
||||
}
|
||||
rbuFinalize(p, pXInfo);
|
||||
bIndex = 1;
|
||||
pIter->nIndex++;
|
||||
}
|
||||
|
||||
rbuFinalize(p, pList);
|
||||
@ -1823,6 +1829,14 @@ static void rbuTmpInsertFunc(
|
||||
int rc = SQLITE_OK;
|
||||
int i;
|
||||
|
||||
assert( sqlite3_value_int(apVal[0])!=0
|
||||
|| p->objiter.eType==RBU_PK_EXTERNAL
|
||||
|| p->objiter.eType==RBU_PK_NONE
|
||||
);
|
||||
if( sqlite3_value_int(apVal[0])!=0 ){
|
||||
p->nPhaseOneStep += p->objiter.nIndex;
|
||||
}
|
||||
|
||||
for(i=0; rc==SQLITE_OK && i<nVal; i++){
|
||||
rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]);
|
||||
}
|
||||
@ -2567,6 +2581,17 @@ static void rbuStepOneOp(sqlite3rbu *p, int eType){
|
||||
|
||||
assert( p->rc==SQLITE_OK );
|
||||
assert( eType!=RBU_DELETE || pIter->zIdx==0 );
|
||||
assert( eType==RBU_DELETE || eType==RBU_IDX_DELETE
|
||||
|| eType==RBU_INSERT || eType==RBU_IDX_INSERT
|
||||
);
|
||||
|
||||
/* If this is a delete, decrement nPhaseOneStep by nIndex. If the DELETE
|
||||
** statement below does actually delete a row, nPhaseOneStep will be
|
||||
** incremented by the same amount when SQL function rbu_tmp_insert()
|
||||
** is invoked by the trigger. */
|
||||
if( eType==RBU_DELETE ){
|
||||
p->nPhaseOneStep -= p->objiter.nIndex;
|
||||
}
|
||||
|
||||
if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){
|
||||
pWriter = pIter->pDelete;
|
||||
@ -2642,7 +2667,10 @@ static int rbuStep(sqlite3rbu *p){
|
||||
rbuBadControlError(p);
|
||||
}
|
||||
else if( eType==RBU_REPLACE ){
|
||||
if( pIter->zIdx==0 ) rbuStepOneOp(p, RBU_DELETE);
|
||||
if( pIter->zIdx==0 ){
|
||||
p->nPhaseOneStep += p->objiter.nIndex;
|
||||
rbuStepOneOp(p, RBU_DELETE);
|
||||
}
|
||||
if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT);
|
||||
}
|
||||
else if( eType!=RBU_UPDATE ){
|
||||
@ -2652,6 +2680,7 @@ static int rbuStep(sqlite3rbu *p){
|
||||
sqlite3_value *pVal;
|
||||
sqlite3_stmt *pUpdate = 0;
|
||||
assert( eType==RBU_UPDATE );
|
||||
p->nPhaseOneStep -= p->objiter.nIndex;
|
||||
rbuGetUpdateStmt(p, pIter, zMask, &pUpdate);
|
||||
if( pUpdate ){
|
||||
int i;
|
||||
@ -2729,6 +2758,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
|
||||
"(%d, %d), "
|
||||
"(%d, %lld), "
|
||||
"(%d, %lld), "
|
||||
"(%d, %lld), "
|
||||
"(%d, %lld) ",
|
||||
p->zStateDb,
|
||||
RBU_STATE_STAGE, eStage,
|
||||
@ -2738,7 +2768,8 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
|
||||
RBU_STATE_PROGRESS, p->nProgress,
|
||||
RBU_STATE_CKPT, p->iWalCksum,
|
||||
RBU_STATE_COOKIE, (i64)p->pTargetFd->iCookie,
|
||||
RBU_STATE_OALSZ, p->iOalSz
|
||||
RBU_STATE_OALSZ, p->iOalSz,
|
||||
RBU_STATE_PHASEONESTEP, p->nPhaseOneStep
|
||||
)
|
||||
);
|
||||
assert( pInsert==0 || rc==SQLITE_OK );
|
||||
@ -2925,6 +2956,10 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
|
||||
pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
|
||||
break;
|
||||
|
||||
case RBU_STATE_PHASEONESTEP:
|
||||
pRet->nPhaseOneStep = (u32)sqlite3_column_int64(pStmt, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
rc = SQLITE_CORRUPT;
|
||||
break;
|
||||
@ -3032,6 +3067,97 @@ static void rbuDeleteVfs(sqlite3rbu *p){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
*/
|
||||
static void rbuIndexCntFunc(
|
||||
sqlite3_context *pCtx,
|
||||
int nVal,
|
||||
sqlite3_value **apVal
|
||||
){
|
||||
sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx);
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
char *zErrmsg = 0;
|
||||
int rc;
|
||||
|
||||
assert( nVal==1 );
|
||||
|
||||
rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg,
|
||||
sqlite3_mprintf("PRAGMA index_list = %Q", sqlite3_value_text(apVal[0]))
|
||||
);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_result_error(pCtx, zErrmsg, -1);
|
||||
}else{
|
||||
int nIndex = 0;
|
||||
while( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
nIndex++;
|
||||
}
|
||||
rc = sqlite3_finalize(pStmt);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_result_int(pCtx, nIndex);
|
||||
}else{
|
||||
sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1);
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_free(zErrmsg);
|
||||
}
|
||||
|
||||
/*
|
||||
** If the RBU database contains the rbu_count table, use it to initialize
|
||||
** the sqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table
|
||||
** is assumed to contain the same columns as:
|
||||
**
|
||||
** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID;
|
||||
**
|
||||
** There should be one row in the table for each data_xxx table in the
|
||||
** database. The 'tbl' column should contain the name of a data_xxx table,
|
||||
** and the cnt column the number of rows it contains.
|
||||
**
|
||||
** sqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt
|
||||
** for all rows in the rbu_count table, where nIndex is the number of
|
||||
** indexes on the corresponding target database table.
|
||||
*/
|
||||
static void rbuInitPhaseOneSteps(sqlite3rbu *p){
|
||||
if( p->rc==SQLITE_OK ){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
int bExists = 0; /* True if rbu_count exists */
|
||||
|
||||
p->nPhaseOneStep = -1;
|
||||
|
||||
p->rc = sqlite3_create_function(p->dbRbu,
|
||||
"rbu_index_cnt", 1, SQLITE_UTF8, (void*)p, rbuIndexCntFunc, 0, 0
|
||||
);
|
||||
|
||||
/* Check for the rbu_count table. If it does not exist, or if an error
|
||||
** occurs, nPhaseOneStep will be left set to -1. */
|
||||
if( p->rc==SQLITE_OK ){
|
||||
p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
|
||||
"SELECT 1 FROM sqlite_master WHERE tbl_name = 'rbu_count'"
|
||||
);
|
||||
}
|
||||
if( p->rc==SQLITE_OK ){
|
||||
if( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
bExists = 1;
|
||||
}
|
||||
p->rc = sqlite3_finalize(pStmt);
|
||||
}
|
||||
|
||||
if( p->rc==SQLITE_OK && bExists ){
|
||||
p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg,
|
||||
"SELECT sum(cnt * (1 + rbu_index_cnt(rbu_target_name(tbl))))"
|
||||
"FROM rbu_count"
|
||||
);
|
||||
if( p->rc==SQLITE_OK ){
|
||||
if( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
p->nPhaseOneStep = sqlite3_column_int64(pStmt, 0);
|
||||
}
|
||||
p->rc = sqlite3_finalize(pStmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Open and return a new RBU handle.
|
||||
*/
|
||||
@ -3077,6 +3203,7 @@ sqlite3rbu *sqlite3rbu_open(
|
||||
|
||||
if( pState->eStage==0 ){
|
||||
rbuDeleteOalFile(p);
|
||||
rbuInitPhaseOneSteps(p);
|
||||
p->eStage = RBU_STAGE_OAL;
|
||||
}else{
|
||||
p->eStage = pState->eStage;
|
||||
@ -3243,6 +3370,38 @@ sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu){
|
||||
return pRbu->nProgress;
|
||||
}
|
||||
|
||||
void sqlite3rbu_stage_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){
|
||||
const int MAX_PROGRESS = 10000;
|
||||
switch( p->eStage ){
|
||||
case RBU_STAGE_OAL:
|
||||
if( p->nPhaseOneStep>0 ){
|
||||
*pnOne = (int)(MAX_PROGRESS * (i64)p->nProgress/(i64)p->nPhaseOneStep);
|
||||
}else{
|
||||
*pnOne = -1;
|
||||
}
|
||||
*pnTwo = 0;
|
||||
break;
|
||||
|
||||
case RBU_STAGE_MOVE:
|
||||
*pnOne = MAX_PROGRESS;
|
||||
*pnTwo = 0;
|
||||
break;
|
||||
|
||||
case RBU_STAGE_CKPT:
|
||||
*pnOne = MAX_PROGRESS;
|
||||
*pnTwo = (int)(MAX_PROGRESS * (i64)p->nStep / (i64)p->nFrame);
|
||||
break;
|
||||
|
||||
case RBU_STAGE_DONE:
|
||||
*pnOne = MAX_PROGRESS;
|
||||
*pnTwo = MAX_PROGRESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
int sqlite3rbu_savestate(sqlite3rbu *p){
|
||||
int rc = p->rc;
|
||||
|
||||
|
@ -400,6 +400,8 @@ int sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg);
|
||||
*/
|
||||
sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu);
|
||||
|
||||
void sqlite3rbu_stage_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo);
|
||||
|
||||
/*
|
||||
** Create an RBU VFS named zName that accesses the underlying file-system
|
||||
** via existing VFS zParent. Or, if the zParent parameter is passed NULL,
|
||||
|
@ -66,6 +66,7 @@ static int test_sqlite3rbu_cmd(
|
||||
{"create_rbu_delta", 2, ""}, /* 2 */
|
||||
{"savestate", 2, ""}, /* 3 */
|
||||
{"dbMain_eval", 3, "SQL"}, /* 4 */
|
||||
{"stage_progress", 2, ""}, /* 5 */
|
||||
{0,0,0}
|
||||
};
|
||||
int iCmd;
|
||||
@ -136,6 +137,18 @@ static int test_sqlite3rbu_cmd(
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: /* stage_progress */ {
|
||||
int one, two;
|
||||
Tcl_Obj *pObj;
|
||||
sqlite3rbu_stage_progress(pRbu, &one, &two);
|
||||
|
||||
pObj = Tcl_NewObj();
|
||||
Tcl_ListObjAppendElement(interp, pObj, Tcl_NewIntObj(one));
|
||||
Tcl_ListObjAppendElement(interp, pObj, Tcl_NewIntObj(two));
|
||||
Tcl_SetObjResult(interp, pObj);
|
||||
break;
|
||||
}
|
||||
|
||||
default: /* seems unlikely */
|
||||
assert( !"cannot happen" );
|
||||
break;
|
||||
|
23
manifest
23
manifest
@ -1,5 +1,5 @@
|
||||
C The\sprepared\sstatements\sfor\ssome\spragmas\scan\snow\sbe\sreused\swithout\sinvoking\nan\sautomatic\sreprepare.
|
||||
D 2016-03-16T21:29:54.761
|
||||
C Add\san\sAPI\sto\sindicate\sthe\spercentage\sprogress\sof\san\srbu\supdate.
|
||||
D 2016-03-17T21:06:42.412
|
||||
F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66
|
||||
@ -242,10 +242,11 @@ F ext/rbu/rbudiff.test 6cc806dc36389292f2a8f5842d0103721df4a07d
|
||||
F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
|
||||
F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
|
||||
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
|
||||
F ext/rbu/rbuprogress.test d63b70f838a20422dce6445bcaed10890e506d02
|
||||
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
|
||||
F ext/rbu/sqlite3rbu.c 5956f8bee63b5ab2b04e65c1801ea0f5920dac92
|
||||
F ext/rbu/sqlite3rbu.h 0bdeb3be211aaba7d85445fa36f4701a25a3dbde
|
||||
F ext/rbu/test_rbu.c 4a4cdcef4ef9379fc2a21f008805c80b27bcf573
|
||||
F ext/rbu/sqlite3rbu.c 9bcf35b2f1d8eaf1c82b47bead114b2289ea06c6
|
||||
F ext/rbu/sqlite3rbu.h f8ee94f95fc80a35b7cb7ef3f2f5ea740b662477
|
||||
F ext/rbu/test_rbu.c 5b6d31af188193d929234d1cd08ee967df092f66
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 0b870ccb7b58b734a2a8e1e2755a7c0ded070920
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
@ -1456,8 +1457,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 10a3e2a01db9f80452a2a3369fd25b6fd9798274 db1ce7e13e656fcd2766f1b1f225cbfefe8f73ad
|
||||
R 2716c51dfa2bfe8ed5e18127e51ae3c8
|
||||
T +closed db1ce7e13e656fcd2766f1b1f225cbfefe8f73ad
|
||||
U drh
|
||||
Z e3b23194e47816995dbce6c752704ef0
|
||||
P 97b0e88cc7c3d677217d0bfab4cb4a34a4abb238
|
||||
R 9de86de419de6ede9128347e06885dfc
|
||||
T *branch * rbu-percent-progress
|
||||
T *sym-rbu-percent-progress *
|
||||
T -sym-trunk *
|
||||
U dan
|
||||
Z f4146c58d33c341586c7f6e824f90dbe
|
||||
|
@ -1 +1 @@
|
||||
97b0e88cc7c3d677217d0bfab4cb4a34a4abb238
|
||||
ffc58d2c2576a5b6e1c2c7112612c5760e711afd
|
Loading…
x
Reference in New Issue
Block a user