Switch back to using a single database connection in sqlite3ota.c.

FossilOrigin-Name: 3c2f4a078132992e33cc675173c84f8385af9cb5
This commit is contained in:
dan 2014-09-05 19:52:42 +00:00
parent 0c4ba2662e
commit 4e9246e9db
3 changed files with 57 additions and 62 deletions

View File

@ -35,7 +35,7 @@
** "progress" -> total number of key/value b-tree operations performed
** so far as part of this ota update.
*/
#define OTA_CREATE_STATE "CREATE TABLE IF NOT EXISTS ota_state" \
#define OTA_CREATE_STATE "CREATE TABLE IF NOT EXISTS ota.ota_state" \
"(tbl, idx, row, progress)"
typedef struct OtaState OtaState;
@ -83,13 +83,10 @@ struct OtaObjIter {
** OTA handle.
*/
struct sqlite3ota {
sqlite3 *dbDest; /* Target db */
sqlite3 *dbOta; /* Ota db */
sqlite3 *db; /* "main" -> target db, "ota" -> ota db */
char *zTarget; /* Path to target db */
int rc; /* Value returned by last ota_step() call */
char *zErrmsg; /* Error message if rc!=SQLITE_OK */
int nStep; /* Rows processed for current object */
OtaObjIter objiter;
};
@ -262,14 +259,14 @@ static int otaObjIterFirst(sqlite3ota *p, OtaObjIter *pIter){
int rc;
memset(pIter, 0, sizeof(OtaObjIter));
rc = prepareAndCollectError(p->dbOta, &pIter->pTblIter, &p->zErrmsg,
"SELECT substr(name, 6) FROM sqlite_master "
rc = prepareAndCollectError(p->db, &pIter->pTblIter, &p->zErrmsg,
"SELECT substr(name, 6) FROM ota.sqlite_master "
"WHERE type='table' AND name LIKE 'data_%'"
);
if( rc==SQLITE_OK ){
rc = prepareAndCollectError(p->dbDest, &pIter->pIdxIter, &p->zErrmsg,
"SELECT name FROM sqlite_master "
rc = prepareAndCollectError(p->db, &pIter->pIdxIter, &p->zErrmsg,
"SELECT name FROM main.sqlite_master "
"WHERE type='index' AND tbl_name = ?"
);
}
@ -325,8 +322,8 @@ static int otaObjIterGetCols(sqlite3ota *p, OtaObjIter *pIter){
int bSeenPk = 0;
int rc2; /* sqlite3_finalize() return value */
zSql = sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl);
p->rc = prepareFreeAndCollectError(p->dbDest, &pStmt, &p->zErrmsg, zSql);
zSql = sqlite3_mprintf("PRAGMA main.table_info(%Q)", pIter->zTbl);
p->rc = prepareFreeAndCollectError(p->db, &pStmt, &p->zErrmsg, zSql);
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
if( (nCol % 8)==0 ){
int nByte = sizeof(char*) * (nCol+8);
@ -429,16 +426,16 @@ static int otaObjIterPrepareAll(
/* Create the index writer */
if( p->rc==SQLITE_OK ){
p->rc = sqlite3_index_writer(
p->dbDest, 0, zIdx, &pIter->pInsert, &aiCol, &pIter->nCol
p->db, 0, zIdx, &pIter->pInsert, &aiCol, &pIter->nCol
);
}
/* Create the SELECT statement to read keys in sorted order */
zCollist = otaObjIterGetCollist(p, pIter, pIter->nCol, aiCol);
if( p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(p->dbOta, &pIter->pSelect, pz,
p->rc = prepareFreeAndCollectError(p->db, &pIter->pSelect, pz,
sqlite3_mprintf(
"SELECT %s FROM 'data_%q' ORDER BY %s%s",
"SELECT %s FROM ota.'data_%q' ORDER BY %s%s",
zCollist, pIter->zTbl, zCollist, zLimit
)
);
@ -450,18 +447,19 @@ static int otaObjIterPrepareAll(
/* Create the SELECT statement to read keys from data_xxx */
if( p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(p->dbOta, &pIter->pSelect, pz,
p->rc = prepareFreeAndCollectError(p->db, &pIter->pSelect, pz,
sqlite3_mprintf(
"SELECT %s FROM 'data_%q'%s",
"SELECT %s FROM ota.'data_%q'%s",
zCollist, pIter->zTbl, zLimit)
);
}
/* Create the INSERT statement to write to the target PK b-tree */
if( p->rc==SQLITE_OK ){
p->rc = prepareFreeAndCollectError(p->dbDest, &pIter->pInsert, pz,
p->rc = prepareFreeAndCollectError(p->db, &pIter->pInsert, pz,
sqlite3_mprintf(
"INSERT INTO %Q(%s) VALUES(%s)", pIter->zTbl, zCollist, zBindings
"INSERT INTO main.%Q(%s) VALUES(%s)",
pIter->zTbl, zCollist, zBindings
)
);
}
@ -534,35 +532,38 @@ int sqlite3ota_step(sqlite3ota *p){
return p->rc;
}
static void otaOpenDatabase(sqlite3ota *p, sqlite3 **pDb, const char *zFile){
/*
** Argument zFmt is a sqlite3_mprintf() style format string. The trailing
** arguments are the usual subsitution values. This function performs
** the printf() style substitutions and executes the result as an SQL
** statement on the OTA handles database.
**
** If an error occurs, an error code and error message is stored in the
** OTA handle. If an error has already occurred when this function is
** called, it is a no-op.
*/
static int otaMPrintfExec(sqlite3ota *p, const char *zFmt, ...){
va_list ap;
va_start(ap, zFmt);
if( p->rc==SQLITE_OK ){
p->rc = sqlite3_open(zFile, pDb);
if( p->rc ){
const char *zErr = sqlite3_errmsg(*pDb);
p->zErrmsg = sqlite3_mprintf("sqlite3_open(): %s", zErr);
char *zSql = sqlite3_vmprintf(zFmt, ap);
if( zSql==0 ){
p->rc = SQLITE_NOMEM;
}else{
p->rc = sqlite3_exec(p->db, zSql, 0, 0, &p->zErrmsg);
sqlite3_free(zSql);
}
}
va_end(ap);
return p->rc;
}
static void otaSaveTransactionState(sqlite3ota *p){
char *zInsert;
zInsert = sqlite3_mprintf(
"INSERT OR REPLACE INTO ota_state(rowid, tbl, idx, row, progress)"
otaMPrintfExec(p,
"INSERT OR REPLACE INTO ota.ota_state(rowid, tbl, idx, row, progress)"
"VALUES(1, %Q, %Q, %d, NULL)",
p->objiter.zTbl, p->objiter.zIdx, p->nStep
);
if( zInsert==0 ){
p->rc = SQLITE_NOMEM;
}else{
p->rc = sqlite3_exec(p->dbOta, zInsert, 0, 0, &p->zErrmsg);
if( p->rc==SQLITE_OK ){
p->rc = sqlite3_exec(p->dbOta, "COMMIT", 0, 0, &p->zErrmsg);
}
}
sqlite3_free(zInsert);
}
/*
@ -575,13 +576,13 @@ static void otaSaveTransactionState(sqlite3ota *p){
** and return NULL.
*/
static OtaState *otaLoadState(sqlite3ota *p){
const char *zSelect = "SELECT tbl, idx, row, progress FROM ota_state";
const char *zSelect = "SELECT tbl, idx, row, progress FROM ota.ota_state";
OtaState *pRet = 0;
sqlite3_stmt *pStmt;
int rc;
assert( p->rc==SQLITE_OK );
rc = prepareAndCollectError(p->dbOta, &pStmt, &p->zErrmsg, zSelect);
rc = prepareAndCollectError(p->db, &pStmt, &p->zErrmsg, zSelect);
if( rc==SQLITE_OK ){
if( sqlite3_step(pStmt)==SQLITE_ROW ){
const char *zIdx = (const char*)sqlite3_column_text(pStmt, 1);
@ -700,12 +701,15 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){
memset(p, 0, sizeof(sqlite3ota));
p->zTarget = (char*)&p[1];
memcpy(p->zTarget, zTarget, nTarget+1);
otaOpenDatabase(p, &p->dbDest, zTarget);
otaOpenDatabase(p, &p->dbOta, zOta);
p->rc = sqlite3_open(zTarget, &p->db);
if( p->rc ){
p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
}
otaMPrintfExec(p, "ATTACH %Q AS ota", zOta);
/* 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);
p->rc = sqlite3_exec(p->db, OTA_CREATE_STATE, 0, 0, &p->zErrmsg);
}
if( p->rc==SQLITE_OK ){
@ -722,12 +726,7 @@ sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta){
"PRAGMA ota_mode=1;"
"BEGIN IMMEDIATE;"
;
p->rc = sqlite3_exec(p->dbDest, zScript, 0, 0, &p->zErrmsg);
}
if( p->rc==SQLITE_OK ){
const char *zScript = "BEGIN IMMEDIATE";
p->rc = sqlite3_exec(p->dbOta, zScript, 0, 0, &p->zErrmsg);
p->rc = sqlite3_exec(p->db, zScript, 0, 0, &p->zErrmsg);
}
/* Point the object iterator at the first object */
@ -766,16 +765,12 @@ int sqlite3ota_close(sqlite3ota *p, char **pzErrmsg){
/* Commit the transaction to the *-oal file. */
if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){
rc = sqlite3_exec(p->dbDest, "COMMIT", 0, 0, &p->zErrmsg);
rc = sqlite3_exec(p->db, "COMMIT", 0, 0, &p->zErrmsg);
if( rc!=SQLITE_OK ) p->rc = rc;
}
assert( sqlite3_next_stmt(p->dbDest, 0)==0 );
assert( sqlite3_next_stmt(p->dbOta, 0)==0 );
/* Close the open database handles */
sqlite3_close(p->dbDest);
sqlite3_close(p->dbOta);
sqlite3_close(p->db);
/* If the OTA has been completely applied and no error occurred, move
** the *-oal file to *-wal. */

View File

@ -1,5 +1,5 @@
C Reorganize\sthe\scode\sin\ssqlite3ota.c\sin\spreparation\sfor\sadding\ssupport\sfor\supdate\sand\sdelete\soperations.
D 2014-09-05T19:31:15.782
C Switch\sback\sto\susing\sa\ssingle\sdatabase\sconnection\sin\ssqlite3ota.c.
D 2014-09-05T19:52:42.359
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -124,7 +124,7 @@ F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
F ext/ota/ota.c d37097e92a005d3915883adefbb93019ea6f8841
F ext/ota/ota1.test 0bbdffa5cb4c4bc26be5dae55c834830c7e8e5e3
F ext/ota/ota2.test 13f76922446c62ed96192e938b8e625ebf0142fa
F ext/ota/sqlite3ota.c c400c9e9ef188cedb9bada263145aaad47d90e75
F ext/ota/sqlite3ota.c 3ddf5f8122f9ab3270541f61bde5d95ef7b631d5
F ext/ota/sqlite3ota.h 545f0008b5f02f2595899cb9841caddada5c17c0
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 57bec53e1a677ab74217fe1f20a58c3a47261d6b
@ -1198,7 +1198,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 9ae44447256b425b5704a1cab3f6796befb92251
R f29d93e4faa0368c9015e32b108d56ba
P 98387f05697526c7740e91d8a846a31f77639406
R cd4982d2f447b7a01026d09e8721c98f
U dan
Z f9daeef70873e6c36444c084d50eac94
Z 303c253ac0315bace60d825e70dc4fdd

View File

@ -1 +1 @@
98387f05697526c7740e91d8a846a31f77639406
3c2f4a078132992e33cc675173c84f8385af9cb5