]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Switch back to using a single database connection in sqlite3ota.c.
authordan <dan@noemail.net>
Fri, 5 Sep 2014 19:52:42 +0000 (19:52 +0000)
committerdan <dan@noemail.net>
Fri, 5 Sep 2014 19:52:42 +0000 (19:52 +0000)
FossilOrigin-Name: 3c2f4a078132992e33cc675173c84f8385af9cb5

ext/ota/sqlite3ota.c
manifest
manifest.uuid

index b5f6e2c436556fa6edaffe38423a36e9bb6c3731..f0fbd28d1b67f7488b20a4cc47aab0578a0d42e6 100644 (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. */
index 6cfb5e1441192f3996a795b6e5a679e2fce4e7c2..8d8f48b13bf1b63fcc135c01157155d5a5eece8a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index 71abb619b323953d1fcd0dc65efe37d3c2d5bbd7..3a256e520f27be38c3906eaa91b249ba46eb2066 100644 (file)
@@ -1 +1 @@
-98387f05697526c7740e91d8a846a31f77639406
\ No newline at end of file
+3c2f4a078132992e33cc675173c84f8385af9cb5
\ No newline at end of file