Allow OTA update state data to be stored in a database separate from the OTA update database.
FossilOrigin-Name: 5af8db56af457d60ea030d84666ca7fffb6821fe
This commit is contained in:
parent
b387e63707
commit
a6fb464878
@ -129,6 +129,25 @@ proc step_ota_uri {target ota} {
|
||||
set rc
|
||||
}
|
||||
|
||||
# Same as [step_ota], except using an external state database - "state.db"
|
||||
#
|
||||
proc step_ota_state {target ota} {
|
||||
while 1 {
|
||||
sqlite3ota ota $target $ota state.db
|
||||
set rc [ota step]
|
||||
ota close
|
||||
if {$rc != "SQLITE_OK"} break
|
||||
}
|
||||
set rc
|
||||
}
|
||||
|
||||
proc dbfilecksum {file} {
|
||||
sqlite3 ck $file
|
||||
set cksum [dbcksum ck main]
|
||||
ck close
|
||||
set cksum
|
||||
}
|
||||
|
||||
foreach {tn3 create_vfs destroy_vfs} {
|
||||
1 {} {}
|
||||
2 {
|
||||
@ -140,7 +159,10 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
|
||||
eval $create_vfs
|
||||
|
||||
foreach {tn2 cmd} {1 run_ota 2 step_ota 3 step_ota_uri} {
|
||||
foreach {tn2 cmd} {
|
||||
1 run_ota
|
||||
2 step_ota 3 step_ota_uri 4 step_ota_state
|
||||
} {
|
||||
foreach {tn schema} {
|
||||
1 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
@ -218,9 +240,11 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
} {
|
||||
reset_db
|
||||
execsql $schema
|
||||
create_ota1 ota.db
|
||||
set check [dbfilecksum ota.db]
|
||||
forcedelete state.db
|
||||
|
||||
do_test $tn3.1.$tn2.$tn.1 {
|
||||
create_ota1 ota.db
|
||||
$cmd test.db ota.db
|
||||
} {SQLITE_DONE}
|
||||
|
||||
@ -241,6 +265,14 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
}
|
||||
|
||||
do_execsql_test $tn3.1.$tn2.$tn.5 { PRAGMA integrity_check } ok
|
||||
|
||||
if {$cmd=="step_ota_state"} {
|
||||
do_test $tn3.1.$tn2.$tn.6 { file exists state.db } 1
|
||||
do_test $tn3.1.$tn2.$tn.7 { expr {$check == [dbfilecksum ota.db]} } 1
|
||||
} else {
|
||||
do_test $tn3.1.$tn2.$tn.8 { file exists state.db } 0
|
||||
do_test $tn3.1.$tn2.$tn.9 { expr {$check == [dbfilecksum ota.db]} } 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,7 +357,7 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
foreach {tn2 cmd} {1 run_ota 2 step_ota} {
|
||||
foreach {tn2 cmd} {1 run_ota 2 step_ota 3 step_ota_state } {
|
||||
foreach {tn schema} {
|
||||
1 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
|
||||
@ -373,9 +405,12 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
INSERT INTO t1 VALUES(4, 'hello', 'planet');
|
||||
INSERT INTO t1 VALUES(6, 'hello', 'xyz');
|
||||
}
|
||||
|
||||
create_ota4 ota.db
|
||||
set check [dbfilecksum ota.db]
|
||||
forcedelete state.db
|
||||
|
||||
do_test $tn3.4.$tn2.$tn.1 {
|
||||
create_ota4 ota.db
|
||||
$cmd test.db ota.db
|
||||
} {SQLITE_DONE}
|
||||
|
||||
@ -388,10 +423,18 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
}
|
||||
|
||||
do_execsql_test $tn3.4.$tn2.$tn.3 { PRAGMA integrity_check } ok
|
||||
|
||||
if {$cmd=="step_ota_state"} {
|
||||
do_test $tn3.4.$tn2.$tn.4 { file exists state.db } 1
|
||||
do_test $tn3.4.$tn2.$tn.5 { expr {$check == [dbfilecksum ota.db]} } 1
|
||||
} else {
|
||||
do_test $tn3.4.$tn2.$tn.6 { file exists state.db } 0
|
||||
do_test $tn3.4.$tn2.$tn.7 { expr {$check == [dbfilecksum ota.db]} } 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach {tn2 cmd} {1 run_ota 2 step_ota} {
|
||||
foreach {tn2 cmd} {1 run_ota 2 step_ota 3 step_ota_state} {
|
||||
foreach {tn schema} {
|
||||
1 {
|
||||
CREATE TABLE t1(c, b, '(a)' INTEGER PRIMARY KEY);
|
||||
@ -411,13 +454,16 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
INSERT INTO t1('(a)', b, c) VALUES(4, 'hello', 'planet');
|
||||
INSERT INTO t1('(a)', b, c) VALUES(6, 'hello', 'xyz');
|
||||
}
|
||||
|
||||
create_ota4b ota.db
|
||||
set check [dbfilecksum ota.db]
|
||||
forcedelete state.db
|
||||
|
||||
do_test $tn3.4.$tn2.$tn.1 {
|
||||
create_ota4b ota.db
|
||||
do_test $tn3.5.$tn2.$tn.1 {
|
||||
$cmd test.db ota.db
|
||||
} {SQLITE_DONE}
|
||||
|
||||
do_execsql_test $tn3.4.$tn2.$tn.2 {
|
||||
do_execsql_test $tn3.5.$tn2.$tn.2 {
|
||||
SELECT * FROM t1 ORDER BY "(a)" ASC;
|
||||
} {
|
||||
3 2 1
|
||||
@ -426,12 +472,20 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
}
|
||||
|
||||
do_execsql_test $tn3.4.$tn2.$tn.3 { PRAGMA integrity_check } ok
|
||||
|
||||
if {$cmd=="step_ota_state"} {
|
||||
do_test $tn3.5.$tn2.$tn.4 { file exists state.db } 1
|
||||
do_test $tn3.5.$tn2.$tn.5 { expr {$check == [dbfilecksum ota.db]} } 1
|
||||
} else {
|
||||
do_test $tn3.5.$tn2.$tn.6 { file exists state.db } 0
|
||||
do_test $tn3.5.$tn2.$tn.7 { expr {$check == [dbfilecksum ota.db]} } 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
foreach {tn2 cmd} {1 run_ota 2 step_ota} {
|
||||
foreach {tn2 cmd} {1 run_ota 2 step_ota 3 step_ota_state} {
|
||||
foreach {tn schema} {
|
||||
1 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
|
||||
@ -472,8 +526,11 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
INSERT INTO t1 VALUES(3, 8, 9, 10);
|
||||
}
|
||||
|
||||
create_ota5 ota.db
|
||||
set check [dbfilecksum ota.db]
|
||||
forcedelete state.db
|
||||
|
||||
do_test $tn3.5.$tn2.$tn.1 {
|
||||
create_ota5 ota.db
|
||||
$cmd test.db ota.db
|
||||
} {SQLITE_DONE}
|
||||
|
||||
@ -485,7 +542,15 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
3 11 9 10
|
||||
}
|
||||
|
||||
do_execsql_test $tn3.5.$tn2.$tn.3 { PRAGMA integrity_check } ok
|
||||
do_execsql_test $tn3.6.$tn2.$tn.3 { PRAGMA integrity_check } ok
|
||||
|
||||
if {$cmd=="step_ota_state"} {
|
||||
do_test $tn3.6.$tn2.$tn.4 { file exists state.db } 1
|
||||
do_test $tn3.6.$tn2.$tn.5 { expr {$check == [dbfilecksum ota.db]} } 1
|
||||
} else {
|
||||
do_test $tn3.6.$tn2.$tn.6 { file exists state.db } 0
|
||||
do_test $tn3.6.$tn2.$tn.7 { expr {$check == [dbfilecksum ota.db]} } 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -566,7 +631,7 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
execsql { ATTACH 'ota.db' AS ota }
|
||||
execsql $schema
|
||||
|
||||
do_test $tn3.6.$tn {
|
||||
do_test $tn3.7.$tn {
|
||||
list [catch { run_ota test.db ota.db } msg] $msg
|
||||
} [list 1 $error]
|
||||
}
|
||||
@ -576,7 +641,7 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
# correctly.
|
||||
reset_db
|
||||
forcedelete ota.db
|
||||
do_test $tn3.7 {
|
||||
do_test $tn3.8 {
|
||||
list [catch { run_ota test.db ota.db } msg] $msg
|
||||
} {0 SQLITE_DONE}
|
||||
|
||||
@ -584,7 +649,7 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
#
|
||||
reset_db
|
||||
forcedelete ota.db
|
||||
do_execsql_test $tn3.8.1 {
|
||||
do_execsql_test $tn3.9.1 {
|
||||
CREATE TABLE t1(a PRIMARY KEY, b, c);
|
||||
CREATE INDEX i1 ON t1(b, c);
|
||||
INSERT INTO t1 VALUES(1, 1, NULL);
|
||||
@ -597,14 +662,14 @@ foreach {tn3 create_vfs destroy_vfs} {
|
||||
INSERT INTO data_t1 VALUES(3, NULL, NULL, 1);
|
||||
} {}
|
||||
|
||||
do_test $tn3.8.2 {
|
||||
do_test $tn3.9.2 {
|
||||
list [catch { run_ota test.db ota.db } msg] $msg
|
||||
} {0 SQLITE_DONE}
|
||||
|
||||
do_execsql_test $tn3.8.3 {
|
||||
do_execsql_test $tn3.9.3 {
|
||||
SELECT * FROM t1
|
||||
} {2 {} 2}
|
||||
do_execsql_test $tn3.8.4 { PRAGMA integrity_check } {ok}
|
||||
do_execsql_test $tn3.9.4 { PRAGMA integrity_check } {ok}
|
||||
|
||||
catch { db close }
|
||||
eval $destroy_vfs
|
||||
|
@ -160,8 +160,8 @@
|
||||
#define OTA_STAGE_DONE 5
|
||||
|
||||
|
||||
#define OTA_CREATE_STATE "CREATE TABLE IF NOT EXISTS ota_state" \
|
||||
"(k INTEGER PRIMARY KEY, v)"
|
||||
#define OTA_CREATE_STATE \
|
||||
"CREATE TABLE IF NOT EXISTS %s.ota_state(k INTEGER PRIMARY KEY, v)"
|
||||
|
||||
typedef struct OtaFrame OtaFrame;
|
||||
typedef struct OtaObjIter OtaObjIter;
|
||||
@ -299,6 +299,8 @@ struct sqlite3ota {
|
||||
sqlite3 *dbOta; /* ota database handle */
|
||||
char *zTarget; /* Path to target db */
|
||||
char *zOta; /* Path to ota db */
|
||||
char *zState; /* Path to state db (or NULL if zOta) */
|
||||
char zStateDb[5]; /* Db name for state ("stat" or "main") */
|
||||
int rc; /* Value returned by last ota_step() call */
|
||||
char *zErrmsg; /* Error message if rc!=SQLITE_OK */
|
||||
int nStep; /* Rows processed for current object */
|
||||
@ -1512,8 +1514,8 @@ static void otaObjIterPrepareTmpInsert(
|
||||
assert( pIter->pTmpInsert==0 );
|
||||
p->rc = prepareFreeAndCollectError(
|
||||
p->dbOta, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf(
|
||||
"INSERT INTO 'ota_tmp_%q'(ota_control,%s%s) VALUES(%z)",
|
||||
pIter->zTbl, zCollist, zOtaRowid, zBind
|
||||
"INSERT INTO %s.'ota_tmp_%q'(ota_control,%s%s) VALUES(%z)",
|
||||
p->zStateDb, pIter->zTbl, zCollist, zOtaRowid, zBind
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -1608,8 +1610,8 @@ static int otaObjIterPrepareAll(
|
||||
char *zSql;
|
||||
if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
|
||||
zSql = sqlite3_mprintf(
|
||||
"SELECT %s, ota_control FROM 'ota_tmp_%q' ORDER BY %s%s",
|
||||
zCollist, pIter->zTbl,
|
||||
"SELECT %s, ota_control FROM %s.'ota_tmp_%q' ORDER BY %s%s",
|
||||
zCollist, p->zStateDb, pIter->zTbl,
|
||||
zCollist, zLimit
|
||||
);
|
||||
}else{
|
||||
@ -1617,10 +1619,10 @@ static int otaObjIterPrepareAll(
|
||||
"SELECT %s, ota_control FROM 'data_%q' "
|
||||
"WHERE typeof(ota_control)='integer' AND ota_control!=1 "
|
||||
"UNION ALL "
|
||||
"SELECT %s, ota_control FROM 'ota_tmp_%q' "
|
||||
"SELECT %s, ota_control FROM %s.'ota_tmp_%q' "
|
||||
"ORDER BY %s%s",
|
||||
zCollist, pIter->zTbl,
|
||||
zCollist, pIter->zTbl,
|
||||
zCollist, p->zStateDb, pIter->zTbl,
|
||||
zCollist, zLimit
|
||||
);
|
||||
}
|
||||
@ -1686,8 +1688,9 @@ static int otaObjIterPrepareAll(
|
||||
|
||||
/* Create the ota_tmp_xxx table and the triggers to populate it. */
|
||||
otaMPrintfExec(p, p->dbOta,
|
||||
"CREATE TABLE IF NOT EXISTS 'ota_tmp_%q' AS "
|
||||
"CREATE TABLE IF NOT EXISTS %s.'ota_tmp_%q' AS "
|
||||
"SELECT *%s FROM 'data_%q' WHERE 0;"
|
||||
, p->zStateDb
|
||||
, zTbl, (pIter->eType==OTA_PK_EXTERNAL ? ", 0 AS ota_rowid" : "")
|
||||
, zTbl
|
||||
);
|
||||
@ -1840,6 +1843,15 @@ static void otaOpenDatabase(sqlite3ota *p){
|
||||
p->dbMain = otaOpenDbhandle(p, p->zTarget);
|
||||
p->dbOta = otaOpenDbhandle(p, p->zOta);
|
||||
|
||||
/* If using separate OTA and state databases, attach the state database to
|
||||
** the OTA db handle now. */
|
||||
if( p->zState ){
|
||||
otaMPrintfExec(p, p->dbOta, "ATTACH %Q AS stat", p->zState);
|
||||
memcpy(p->zStateDb, "stat", 4);
|
||||
}else{
|
||||
memcpy(p->zStateDb, "main", 4);
|
||||
}
|
||||
|
||||
if( p->rc==SQLITE_OK ){
|
||||
p->rc = sqlite3_create_function(p->dbMain,
|
||||
"ota_tmp_insert", -1, SQLITE_UTF8, (void*)p, otaTmpInsertFunc, 0, 0
|
||||
@ -2340,7 +2352,7 @@ static void otaSaveState(sqlite3ota *p, int eStage){
|
||||
assert( p->zErrmsg==0 );
|
||||
rc = prepareFreeAndCollectError(p->dbOta, &pInsert, &p->zErrmsg,
|
||||
sqlite3_mprintf(
|
||||
"INSERT OR REPLACE INTO ota_state(k, v) VALUES "
|
||||
"INSERT OR REPLACE INTO %s.ota_state(k, v) VALUES "
|
||||
"(%d, %d), "
|
||||
"(%d, %Q), "
|
||||
"(%d, %Q), "
|
||||
@ -2349,6 +2361,7 @@ static void otaSaveState(sqlite3ota *p, int eStage){
|
||||
"(%d, %lld), "
|
||||
"(%d, %lld), "
|
||||
"(%d, %lld) ",
|
||||
p->zStateDb,
|
||||
OTA_STATE_STAGE, eStage,
|
||||
OTA_STATE_TBL, p->objiter.zTbl,
|
||||
OTA_STATE_IDX, p->objiter.zIdx,
|
||||
@ -2385,8 +2398,9 @@ int sqlite3ota_step(sqlite3ota *p){
|
||||
** cannot be dropped as there are currently active SQL statements.
|
||||
** But the contents can be deleted. */
|
||||
if( pIter->abIndexed ){
|
||||
const char *zTbl = pIter->zTbl;
|
||||
otaMPrintfExec(p, p->dbOta, "DELETE FROM 'ota_tmp_%q'", zTbl);
|
||||
otaMPrintfExec(p, p->dbOta,
|
||||
"DELETE FROM %s.'ota_tmp_%q'", p->zStateDb, pIter->zTbl
|
||||
);
|
||||
}
|
||||
}else{
|
||||
otaObjIterPrepareAll(p, pIter, 0);
|
||||
@ -2491,7 +2505,6 @@ static void otaFreeState(OtaState *p){
|
||||
** and return NULL.
|
||||
*/
|
||||
static OtaState *otaLoadState(sqlite3ota *p){
|
||||
const char *zSelect = "SELECT k, v FROM ota_state";
|
||||
OtaState *pRet = 0;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
int rc;
|
||||
@ -2500,7 +2513,9 @@ static OtaState *otaLoadState(sqlite3ota *p){
|
||||
pRet = (OtaState*)otaMalloc(p, sizeof(OtaState));
|
||||
if( pRet==0 ) return 0;
|
||||
|
||||
rc = prepareAndCollectError(p->dbOta, &pStmt, &p->zErrmsg, zSelect);
|
||||
rc = prepareFreeAndCollectError(p->dbOta, &pStmt, &p->zErrmsg,
|
||||
sqlite3_mprintf("SELECT k, v FROM %s.ota_state", p->zStateDb)
|
||||
);
|
||||
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
switch( sqlite3_column_int(pStmt, 0) ){
|
||||
case OTA_STATE_STAGE:
|
||||
@ -2645,15 +2660,17 @@ static void otaDeleteVfs(sqlite3ota *p){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Open and return a new OTA handle.
|
||||
*/
|
||||
sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){
|
||||
static sqlite3ota *otaOpen(
|
||||
const char *zTarget,
|
||||
const char *zOta,
|
||||
const char *zState
|
||||
){
|
||||
sqlite3ota *p;
|
||||
int nTarget = strlen(zTarget);
|
||||
int nOta = strlen(zOta);
|
||||
int nState = zState ? strlen(zState) : 0;
|
||||
|
||||
p = (sqlite3ota*)sqlite3_malloc(sizeof(sqlite3ota)+nTarget+1+nOta+1);
|
||||
p = (sqlite3ota*)sqlite3_malloc(sizeof(sqlite3ota)+nTarget+1+nOta+1+nState+1);
|
||||
if( p ){
|
||||
OtaState *pState = 0;
|
||||
|
||||
@ -2667,13 +2684,15 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){
|
||||
memcpy(p->zTarget, zTarget, nTarget+1);
|
||||
p->zOta = &p->zTarget[nTarget+1];
|
||||
memcpy(p->zOta, zOta, nOta+1);
|
||||
if( zState ){
|
||||
p->zState = &p->zOta[nOta+1];
|
||||
memcpy(p->zState, zState, nState+1);
|
||||
}
|
||||
otaOpenDatabase(p);
|
||||
}
|
||||
|
||||
/* If it has not already been created, create the ota_state table */
|
||||
if( p->rc==SQLITE_OK ){
|
||||
p->rc = sqlite3_exec(p->dbOta, OTA_CREATE_STATE, 0, 0, &p->zErrmsg);
|
||||
}
|
||||
otaMPrintfExec(p, p->dbOta, OTA_CREATE_STATE, p->zStateDb);
|
||||
|
||||
if( p->rc==SQLITE_OK ){
|
||||
pState = otaLoadState(p);
|
||||
@ -2756,6 +2775,28 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Open and return a new OTA handle.
|
||||
*/
|
||||
sqlite3ota *sqlite3ota_open_v2(
|
||||
const char *zDb,
|
||||
const char *zOta,
|
||||
const char *zState
|
||||
){
|
||||
return otaOpen(zDb, zOta, zState);
|
||||
}
|
||||
|
||||
/*
|
||||
** Open and return a new OTA handle.
|
||||
*/
|
||||
sqlite3ota *sqlite3ota_open(
|
||||
const char *zDb,
|
||||
const char *zOta
|
||||
){
|
||||
return otaOpen(zDb, zOta, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the database handle used by pOta.
|
||||
*/
|
||||
|
@ -272,6 +272,37 @@ typedef struct sqlite3ota sqlite3ota;
|
||||
*/
|
||||
sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta);
|
||||
|
||||
/*
|
||||
** Open an OTA handle with an auxiliary state file.
|
||||
**
|
||||
** This API is similar to sqlite3ota_open(), except that it allows the user
|
||||
** to specify a separate SQLite database in which to store the OTA update
|
||||
** state.
|
||||
**
|
||||
** While executing, the OTA extension usually stores the current state
|
||||
** of the update (how many rows have been updated, which indexes are yet
|
||||
** to be updated etc.) within the OTA database itself. This can be
|
||||
** convenient, as it means that the OTA application does not need to
|
||||
** organize removing a separate state file after the update is concluded.
|
||||
** However, it can also be inconvenient - for example if the OTA update
|
||||
** database is sto be stored on a read-only media.
|
||||
**
|
||||
** If an OTA update started using a handle opened with this function is
|
||||
** suspended, the application must use this function to resume it, and
|
||||
** must pass the same zState argument each time the update is resumed.
|
||||
** Attempting to resume an sqlite3ota_open_v2() update using sqlite3ota_open(),
|
||||
** or with a call to sqlite3ota_open_v2() specifying a different zState
|
||||
** argument leads to undefined behaviour.
|
||||
**
|
||||
** Once the OTA update is finished, the OTA extension does not
|
||||
** automatically remove the zState database file, even if it created it.
|
||||
*/
|
||||
sqlite3ota *sqlite3ota_open_v2(
|
||||
const char *zTarget,
|
||||
const char *zOta,
|
||||
const char *zState
|
||||
);
|
||||
|
||||
/*
|
||||
** Internally, each OTA connection uses a separate SQLite database
|
||||
** connection to access the target and ota update databases. This
|
||||
|
@ -112,7 +112,7 @@ static int test_sqlite3ota_cmd(
|
||||
}
|
||||
|
||||
/*
|
||||
** Tclcmd: sqlite3ota CMD <target-db> <ota-db>
|
||||
** Tclcmd: sqlite3ota CMD <target-db> <ota-db> ?<state-db>?
|
||||
*/
|
||||
static int test_sqlite3ota(
|
||||
ClientData clientData,
|
||||
@ -125,15 +125,20 @@ static int test_sqlite3ota(
|
||||
const char *zTarget;
|
||||
const char *zOta;
|
||||
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB OTA-DB");
|
||||
if( objc!=4 && objc!=5 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB OTA-DB ?STATE-DB?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zCmd = Tcl_GetString(objv[1]);
|
||||
zTarget = Tcl_GetString(objv[2]);
|
||||
zOta = Tcl_GetString(objv[3]);
|
||||
|
||||
pOta = sqlite3ota_open(zTarget, zOta);
|
||||
if( objc==4 ){
|
||||
pOta = sqlite3ota_open(zTarget, zOta);
|
||||
}else{
|
||||
const char *zStateDb = Tcl_GetString(objv[4]);
|
||||
pOta = sqlite3ota_open_v2(zTarget, zOta, zStateDb);
|
||||
}
|
||||
Tcl_CreateObjCommand(interp, zCmd, test_sqlite3ota_cmd, (ClientData)pOta, 0);
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
|
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Merge\slatest\strunk\schanges\swith\sthis\sbranch.
|
||||
D 2015-05-19T14:14:57.988
|
||||
C Allow\sOTA\supdate\sstate\sdata\sto\sbe\sstored\sin\sa\sdatabase\sseparate\sfrom\sthe\sOTA\supdate\sdatabase.
|
||||
D 2015-05-19T16:22:58.978
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 0a6ae26396ec696221021780dffbb894ff3cead7
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -124,7 +124,7 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
|
||||
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
F ext/ota/ota.c c47352838b967384a81eda5de75c352922a0dd6e
|
||||
F ext/ota/ota1.test 960418e4171a989426f8b1ad8ee31770e0f94fb8
|
||||
F ext/ota/ota1.test abdcbe746db4c7f7b51e842b576cacb33eef28f5
|
||||
F ext/ota/ota10.test 85e0f6e7964db5007590c1b299e75211ed4240d4
|
||||
F ext/ota/ota11.test 2f606cd2b4af260a86b549e91b9f395450fc75cb
|
||||
F ext/ota/ota12.test 0dff44474de448fb4b0b28c20da63273a4149abb
|
||||
@ -139,9 +139,9 @@ F ext/ota/otaA.test ab67f7f53670b81c750dcc946c5b704f51c429a4
|
||||
F ext/ota/otacrash.test 8346192b2d46cbe7787d5d65904d81d3262a3cbf
|
||||
F ext/ota/otafault.test 8c43586c2b96ca16bbce00b5d7e7d67316126db8
|
||||
F ext/ota/otafault2.test fa202a98ca221faec318f3e5c5f39485b1256561
|
||||
F ext/ota/sqlite3ota.c 5bfd677bd956d0ea9f0022b010ac70409e8e9bf6
|
||||
F ext/ota/sqlite3ota.h 7faa45e080b9c136e666c383187ff6e39d88135b
|
||||
F ext/ota/test_ota.c e34c801c665d64b4b9e00b71f1acf8c652404b2b
|
||||
F ext/ota/sqlite3ota.c 89530008cff5825072ef455eb45cf04d497d6399
|
||||
F ext/ota/sqlite3ota.h ebde09505ccfff78def3c67b02cfebe27f830925
|
||||
F ext/ota/test_ota.c ba5d936190713d15919502d6ee6f287cada279ae
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 0c207fd8b814a35537d96681cbf57436e200b75e
|
||||
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
|
||||
@ -1278,7 +1278,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 16ab9cafd00ea5df7e6f75d6a6740237828b888d 5df4056448fee1c766f8f79c735ed12abdce5101
|
||||
R ca0828efa06faab3b9677740d6592df2
|
||||
P 6055a6725cb24469c10de9a04f3614dcc79193c6
|
||||
R 2b87c978f295a3b27fab33174a5bc3b2
|
||||
U dan
|
||||
Z 5e45a187c4752901348a44d76452f100
|
||||
Z 5cb8f8d4aed58cbcc0b1d560014c2a0f
|
||||
|
@ -1 +1 @@
|
||||
6055a6725cb24469c10de9a04f3614dcc79193c6
|
||||
5af8db56af457d60ea030d84666ca7fffb6821fe
|
Loading…
x
Reference in New Issue
Block a user