/ Changes On Branch ota-update
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch ota-update Excluding Merge-Ins

This is equivalent to a diff from 5df4056448 to efa20f8e41

2015-05-19
16:50
Merge the ota-update branch with trunk. (check-in: 08e2864ed7 user: dan tags: trunk)
16:26
Add a comment for SQLITE_FCNTL_OTA to sqlite.h.in. (Closed-Leaf check-in: efa20f8e41 user: dan tags: ota-update)
16:22
Allow OTA update state data to be stored in a database separate from the OTA update database. (check-in: 5af8db56af user: dan tags: ota-update)
14:14
Merge latest trunk changes with this branch. (check-in: 6055a6725c user: dan tags: ota-update)
2015-05-18
12:28
Transitive constraints should only work if operands have compatible affinities and collating sequences. (check-in: 5df4056448 user: drh tags: trunk)
12:18
Use an ALWAY() on conditionals in the transitive constraint logic that are always true as far as we know. (Closed-Leaf check-in: 204e567f68 user: drh tags: transitive-constraints)
04:24
Make a hard copy of the results of a subquery lest the result of the subquery be referenced after a change to the table that generated the subquery result. (check-in: 9c0d80907b user: drh tags: trunk)

Changes to Makefile.in.

   335    335     $(TOP)/ext/fts3/fts3_write.c
   336    336   SRC += \
   337    337     $(TOP)/ext/icu/sqliteicu.h \
   338    338     $(TOP)/ext/icu/icu.c
   339    339   SRC += \
   340    340     $(TOP)/ext/rtree/rtree.h \
   341    341     $(TOP)/ext/rtree/rtree.c
          342  +SRC += \
          343  +  $(TOP)/ext/ota/sqlite3ota.h \
          344  +  $(TOP)/ext/ota/sqlite3ota.c
   342    345   
   343    346   
   344    347   # Generated source code files
   345    348   #
   346    349   SRC += \
   347    350     keywordhash.h \
   348    351     opcodes.c \
................................................................................
   391    394     $(TOP)/src/test_superlock.c \
   392    395     $(TOP)/src/test_syscall.c \
   393    396     $(TOP)/src/test_tclvar.c \
   394    397     $(TOP)/src/test_thread.c \
   395    398     $(TOP)/src/test_vfs.c \
   396    399     $(TOP)/src/test_wsd.c       \
   397    400     $(TOP)/ext/fts3/fts3_term.c \
   398         -  $(TOP)/ext/fts3/fts3_test.c 
          401  +  $(TOP)/ext/fts3/fts3_test.c \
          402  +  $(TOP)/ext/ota/test_ota.c 
   399    403   
   400    404   # Statically linked extensions
   401    405   #
   402    406   TESTSRC += \
   403    407     $(TOP)/ext/misc/amatch.c \
   404    408     $(TOP)/ext/misc/closure.c \
   405    409     $(TOP)/ext/misc/eval.c \

Added ext/ota/ota.c.

            1  +/*
            2  +** 2014 August 30
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +** This file contains a command-line application that uses the OTA 
           14  +** extension. See the usage() function below for an explanation.
           15  +*/
           16  +
           17  +#include "sqlite3ota.h"
           18  +#include <stdio.h>
           19  +#include <stdlib.h>
           20  +#include <string.h>
           21  +
           22  +/*
           23  +** Print a usage message and exit.
           24  +*/
           25  +void usage(const char *zArgv0){
           26  +  fprintf(stderr, 
           27  +"Usage: %s [-step NSTEP] TARGET-DB OTA-DB\n"
           28  +"\n"
           29  +"  Argument OTA-DB must be an OTA database containing an update suitable for\n"
           30  +"  target database TARGET-DB. If NSTEP is set to less than or equal to zero\n"
           31  +"  (the default value), this program attempts to apply the entire update to\n"
           32  +"  the target database.\n"
           33  +"\n"
           34  +"  If NSTEP is greater than zero, then a maximum of NSTEP calls are made\n"
           35  +"  to sqlite3ota_step(). If the OTA update has not been completely applied\n"
           36  +"  after the NSTEP'th call is made, the state is saved in the database OTA-DB\n"
           37  +"  and the program exits. Subsequent invocations of this (or any other OTA)\n"
           38  +"  application will use this state to resume applying the OTA update to the\n"
           39  +"  target db.\n"
           40  +"\n"
           41  +, zArgv0);
           42  +  exit(1);
           43  +}
           44  +
           45  +void report_default_vfs(){
           46  +  sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
           47  +  fprintf(stdout, "default vfs is \"%s\"\n", pVfs->zName);
           48  +}
           49  +
           50  +void report_ota_vfs(sqlite3ota *pOta){
           51  +  sqlite3 *db = sqlite3ota_db(pOta, 0);
           52  +  if( db ){
           53  +    char *zName = 0;
           54  +    sqlite3_file_control(db, "main", SQLITE_FCNTL_VFSNAME, &zName);
           55  +    if( zName ){
           56  +      fprintf(stdout, "using vfs \"%s\"\n", zName);
           57  +    }else{
           58  +      fprintf(stdout, "vfs name not available\n");
           59  +    }
           60  +    sqlite3_free(zName);
           61  +  }
           62  +}
           63  +
           64  +int main(int argc, char **argv){
           65  +  int i;
           66  +  const char *zTarget;            /* Target database to apply OTA to */
           67  +  const char *zOta;               /* Database containing OTA */
           68  +  char *zErrmsg;                  /* Error message, if any */
           69  +  sqlite3ota *pOta;               /* OTA handle */
           70  +  int nStep = 0;                  /* Maximum number of step() calls */
           71  +  int rc;
           72  +  sqlite3_int64 nProgress = 0;
           73  +
           74  +  /* Process command line arguments. Following this block local variables 
           75  +  ** zTarget, zOta and nStep are all set. */
           76  +  if( argc==5 ){
           77  +    int nArg1 = strlen(argv[1]);
           78  +    if( nArg1>5 || nArg1<2 || memcmp("-step", argv[1], nArg1) ) usage(argv[0]);
           79  +    nStep = atoi(argv[2]);
           80  +  }else if( argc!=3 ){
           81  +    usage(argv[0]);
           82  +  }
           83  +  zTarget = argv[argc-2];
           84  +  zOta = argv[argc-1];
           85  +
           86  +  report_default_vfs();
           87  +
           88  +  /* Open an OTA handle. If nStep is less than or equal to zero, call
           89  +  ** sqlite3ota_step() until either the OTA has been completely applied
           90  +  ** or an error occurs. Or, if nStep is greater than zero, call
           91  +  ** sqlite3ota_step() a maximum of nStep times.  */
           92  +  pOta = sqlite3ota_open(zTarget, zOta);
           93  +  report_ota_vfs(pOta);
           94  +  for(i=0; (nStep<=0 || i<nStep) && sqlite3ota_step(pOta)==SQLITE_OK; i++);
           95  +  nProgress = sqlite3ota_progress(pOta);
           96  +  rc = sqlite3ota_close(pOta, &zErrmsg);
           97  +
           98  +  /* Let the user know what happened. */
           99  +  switch( rc ){
          100  +    case SQLITE_OK:
          101  +      fprintf(stdout, 
          102  +          "SQLITE_OK: ota update incomplete (%lld operations so far)\n",
          103  +          nProgress
          104  +      );
          105  +      break;
          106  +
          107  +    case SQLITE_DONE:
          108  +      fprintf(stdout, 
          109  +          "SQLITE_DONE: ota update completed (%lld operations)\n",
          110  +          nProgress
          111  +      );
          112  +      break;
          113  +
          114  +    default:
          115  +      fprintf(stderr, "error=%d: %s\n", rc, zErrmsg);
          116  +      break;
          117  +  }
          118  +
          119  +  sqlite3_free(zErrmsg);
          120  +  return (rc==SQLITE_OK || rc==SQLITE_DONE) ? 0 : 1;
          121  +}
          122  +

Added ext/ota/ota1.test.

            1  +# 2014 August 30
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +if {![info exists testdir]} {
           14  +  set testdir [file join [file dirname [info script]] .. .. test]
           15  +}
           16  +source $testdir/tester.tcl
           17  +set ::testprefix ota1
           18  +
           19  +db close
           20  +sqlite3_shutdown
           21  +sqlite3_config_uri 1
           22  +
           23  +# Create a simple OTA database. That expects to write to a table:
           24  +#
           25  +#   CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
           26  +#
           27  +proc create_ota1 {filename} {
           28  +  forcedelete $filename
           29  +  sqlite3 ota1 $filename  
           30  +  ota1 eval {
           31  +    CREATE TABLE data_t1(a, b, c, ota_control);
           32  +    INSERT INTO data_t1 VALUES(1, 2, 3, 0);
           33  +    INSERT INTO data_t1 VALUES(2, 'two', 'three', 0);
           34  +    INSERT INTO data_t1 VALUES(3, NULL, 8.2, 0);
           35  +  }
           36  +  ota1 close
           37  +  return $filename
           38  +}
           39  +
           40  +# Create a simple OTA database. That expects to write to a table:
           41  +#
           42  +#   CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
           43  +#
           44  +# This OTA includes both insert and delete operations.
           45  +#
           46  +proc create_ota4 {filename} {
           47  +  forcedelete $filename
           48  +  sqlite3 ota1 $filename  
           49  +  ota1 eval {
           50  +    CREATE TABLE data_t1(a, b, c, ota_control);
           51  +    INSERT INTO data_t1 VALUES(1, 2, 3, 0);
           52  +    INSERT INTO data_t1 VALUES(2, NULL, 5, 1);
           53  +    INSERT INTO data_t1 VALUES(3, 8, 9, 0);
           54  +    INSERT INTO data_t1 VALUES(4, NULL, 11, 1);
           55  +  }
           56  +  ota1 close
           57  +  return $filename
           58  +}
           59  +#
           60  +# Create a simple OTA database. That expects to write to a table:
           61  +#
           62  +#   CREATE TABLE t1(c, b, '(a)' INTEGER PRIMARY KEY);
           63  +#
           64  +# This OTA includes both insert and delete operations.
           65  +#
           66  +proc create_ota4b {filename} {
           67  +  forcedelete $filename
           68  +  sqlite3 ota1 $filename  
           69  +  ota1 eval {
           70  +    CREATE TABLE data_t1(c, b, '(a)', ota_control);
           71  +    INSERT INTO data_t1 VALUES(3, 2, 1, 0);
           72  +    INSERT INTO data_t1 VALUES(5, NULL, 2, 1);
           73  +    INSERT INTO data_t1 VALUES(9, 8, 3, 0);
           74  +    INSERT INTO data_t1 VALUES(11, NULL, 4, 1);
           75  +  }
           76  +  ota1 close
           77  +  return $filename
           78  +}
           79  +
           80  +# Create a simple OTA database. That expects to write to a table:
           81  +#
           82  +#   CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
           83  +#
           84  +# This OTA includes update statements.
           85  +#
           86  +proc create_ota5 {filename} {
           87  +  forcedelete $filename
           88  +  sqlite3 ota5 $filename  
           89  +  ota5 eval {
           90  +    CREATE TABLE data_t1(a, b, c, d, ota_control);
           91  +    INSERT INTO data_t1 VALUES(1, NULL, NULL, 5, '...x');  -- SET d = 5
           92  +    INSERT INTO data_t1 VALUES(2, NULL, 10, 5, '..xx');    -- SET c=10, d = 5
           93  +    INSERT INTO data_t1 VALUES(3, 11, NULL, NULL, '.x..'); -- SET b=11
           94  +  }
           95  +  ota5 close
           96  +  return $filename
           97  +}
           98  +
           99  +# Run the OTA in file $ota on target database $target until completion.
          100  +#
          101  +proc run_ota {target ota} {
          102  +  sqlite3ota ota $target $ota
          103  +  while 1 {
          104  +    set rc [ota step]
          105  +    if {$rc!="SQLITE_OK"} break
          106  +  }
          107  +  ota close
          108  +}
          109  +
          110  +proc step_ota {target ota} {
          111  +  while 1 {
          112  +    sqlite3ota ota $target $ota
          113  +    set rc [ota step]
          114  +    ota close
          115  +    if {$rc != "SQLITE_OK"} break
          116  +  }
          117  +  set rc
          118  +}
          119  +
          120  +# Same as [step_ota], except using a URI to open the target db.
          121  +#
          122  +proc step_ota_uri {target ota} {
          123  +  while 1 {
          124  +    sqlite3ota ota file:$target?xyz=&abc=123 $ota
          125  +    set rc [ota step]
          126  +    ota close
          127  +    if {$rc != "SQLITE_OK"} break
          128  +  }
          129  +  set rc
          130  +}
          131  +
          132  +# Same as [step_ota], except using an external state database - "state.db"
          133  +#
          134  +proc step_ota_state {target ota} {
          135  +  while 1 {
          136  +    sqlite3ota ota $target $ota state.db
          137  +    set rc [ota step]
          138  +    ota close
          139  +    if {$rc != "SQLITE_OK"} break
          140  +  }
          141  +  set rc
          142  +}
          143  +
          144  +proc dbfilecksum {file} {
          145  +  sqlite3 ck $file
          146  +  set cksum [dbcksum ck main]
          147  +  ck close
          148  +  set cksum
          149  +}
          150  +
          151  +foreach {tn3 create_vfs destroy_vfs} {
          152  +  1 {} {}
          153  +  2 {
          154  +    sqlite3ota_create_vfs -default myota ""
          155  +  } {
          156  +    sqlite3ota_destroy_vfs myota
          157  +  }
          158  +} {
          159  +
          160  +  eval $create_vfs
          161  +
          162  +  foreach {tn2 cmd} {
          163  +      1 run_ota 
          164  +      2 step_ota 3 step_ota_uri 4 step_ota_state
          165  +  } {
          166  +    foreach {tn schema} {
          167  +      1 {
          168  +        CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
          169  +      }
          170  +      2 { 
          171  +        CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
          172  +        CREATE INDEX i1 ON t1(b);
          173  +      }
          174  +      3 { 
          175  +        CREATE TABLE t1(a PRIMARY KEY, b, c) WITHOUT ROWID;
          176  +      }
          177  +      4 { 
          178  +        CREATE TABLE t1(a PRIMARY KEY, b, c) WITHOUT ROWID;
          179  +        CREATE INDEX i1 ON t1(b);
          180  +      }
          181  +      5 { 
          182  +        CREATE TABLE t1(a, b, c, PRIMARY KEY(a, c)) WITHOUT ROWID;
          183  +        CREATE INDEX i1 ON t1(b);
          184  +      }
          185  +      6 { 
          186  +        CREATE TABLE t1(a, b, c, PRIMARY KEY(c)) WITHOUT ROWID;
          187  +        CREATE INDEX i1 ON t1(b, a);
          188  +      }
          189  +      7 { 
          190  +        CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
          191  +        CREATE INDEX i1 ON t1(b, c);
          192  +        CREATE INDEX i2 ON t1(c, b);
          193  +        CREATE INDEX i3 ON t1(a, b, c, a, b, c);
          194  +      }
          195  +
          196  +      8 { 
          197  +        CREATE TABLE t1(a PRIMARY KEY, b, c);
          198  +        CREATE INDEX i1 ON t1(b, c);
          199  +        CREATE INDEX i2 ON t1(c, b);
          200  +        CREATE INDEX i3 ON t1(a, b, c, a, b, c);
          201  +      }
          202  +
          203  +      9 { 
          204  +        CREATE TABLE t1(a, b, c, PRIMARY KEY(a, c));
          205  +        CREATE INDEX i1 ON t1(b);
          206  +      }
          207  +
          208  +      10 { 
          209  +        CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
          210  +        CREATE INDEX i1 ON t1(b DESC);
          211  +      }
          212  +
          213  +      11 { 
          214  +        CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
          215  +        CREATE INDEX i1 ON t1(b DESC, a ASC, c DESC);
          216  +      }
          217  +
          218  +      12 { 
          219  +        CREATE TABLE t1(a INT PRIMARY KEY DESC, b, c) WITHOUT ROWID; 
          220  +      }
          221  +
          222  +      13 { 
          223  +        CREATE TABLE t1(a INT, b, c, PRIMARY KEY(a DESC)) WITHOUT ROWID; 
          224  +      }
          225  +
          226  +      14 { 
          227  +        CREATE TABLE t1(a, b, c, PRIMARY KEY(a DESC, c)) WITHOUT ROWID;
          228  +        CREATE INDEX i1 ON t1(b);
          229  +      }
          230  +
          231  +      15 { 
          232  +        CREATE TABLE t1(a, b, c, PRIMARY KEY(a, c DESC)) WITHOUT ROWID;
          233  +        CREATE INDEX i1 ON t1(b);
          234  +      }
          235  +
          236  +      16 { 
          237  +        CREATE TABLE t1(a, b, c, PRIMARY KEY(c DESC, a)) WITHOUT ROWID;
          238  +        CREATE INDEX i1 ON t1(b DESC, c, a);
          239  +      }
          240  +    } {
          241  +      reset_db
          242  +      execsql $schema
          243  +      create_ota1 ota.db
          244  +      set check [dbfilecksum ota.db]
          245  +      forcedelete state.db
          246  +
          247  +      do_test $tn3.1.$tn2.$tn.1 {
          248  +        $cmd test.db ota.db
          249  +      } {SQLITE_DONE}
          250  +
          251  +      do_execsql_test $tn3.1.$tn2.$tn.2 { SELECT * FROM t1 ORDER BY a ASC } {
          252  +        1 2 3 
          253  +        2 two three 
          254  +        3 {} 8.2
          255  +      }
          256  +      do_execsql_test $tn3.1.$tn2.$tn.3 { SELECT * FROM t1 ORDER BY b ASC } {
          257  +        3 {} 8.2
          258  +        1 2 3 
          259  +        2 two three 
          260  +      }
          261  +      do_execsql_test $tn3.1.$tn2.$tn.4 { SELECT * FROM t1 ORDER BY c ASC } {
          262  +        1 2 3 
          263  +        3 {} 8.2
          264  +        2 two three 
          265  +      }
          266  +   
          267  +      do_execsql_test $tn3.1.$tn2.$tn.5 { PRAGMA integrity_check } ok
          268  +
          269  +      if {$cmd=="step_ota_state"} {
          270  +        do_test $tn3.1.$tn2.$tn.6 { file exists state.db } 1
          271  +        do_test $tn3.1.$tn2.$tn.7 { expr {$check == [dbfilecksum ota.db]} } 1
          272  +      } else {
          273  +        do_test $tn3.1.$tn2.$tn.8 { file exists state.db } 0
          274  +        do_test $tn3.1.$tn2.$tn.9 { expr {$check == [dbfilecksum ota.db]} } 0
          275  +      }
          276  +    }
          277  +  }
          278  +
          279  +  #-------------------------------------------------------------------------
          280  +  # Check that an OTA cannot be applied to a table that has no PK.
          281  +  #
          282  +  # UPDATE: At one point OTA required that all tables featured either
          283  +  # explicit IPK columns or were declared WITHOUT ROWID. This has been
          284  +  # relaxed so that external PRIMARY KEYs on tables with automatic rowids
          285  +  # are now allowed.
          286  +  #
          287  +  # UPDATE 2: Tables without any PRIMARY KEY declaration are now allowed.
          288  +  # However the input table must feature an "ota_rowid" column.
          289  +  #
          290  +  reset_db
          291  +  create_ota1 ota.db
          292  +  do_execsql_test $tn3.2.1 { CREATE TABLE t1(a, b, c) }
          293  +  do_test $tn3.2.2 {
          294  +    sqlite3ota ota test.db ota.db
          295  +    ota step
          296  +  } {SQLITE_ERROR}
          297  +  do_test $tn3.2.3 {
          298  +    list [catch { ota close } msg] $msg
          299  +  } {1 {SQLITE_ERROR - table data_t1 requires ota_rowid column}}
          300  +  reset_db
          301  +  do_execsql_test $tn3.2.4 { CREATE TABLE t1(a PRIMARY KEY, b, c) }
          302  +  do_test $tn3.2.5 {
          303  +    sqlite3ota ota test.db ota.db
          304  +    ota step
          305  +  } {SQLITE_OK}
          306  +  do_test $tn3.2.6 {
          307  +    list [catch { ota close } msg] $msg
          308  +  } {0 SQLITE_OK}
          309  +
          310  +  #-------------------------------------------------------------------------
          311  +  # Check that if a UNIQUE constraint is violated the current and all 
          312  +  # subsequent [ota step] calls return SQLITE_CONSTRAINT. And that the OTA 
          313  +  # transaction is rolled back by the [ota close] that deletes the ota 
          314  +  # handle.
          315  +  #
          316  +  foreach {tn errcode errmsg schema} {
          317  +    1 SQLITE_CONSTRAINT "UNIQUE constraint failed: t1.a" {
          318  +      CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
          319  +      INSERT INTO t1 VALUES(3, 2, 1);
          320  +    } 
          321  +
          322  +    2 SQLITE_CONSTRAINT "UNIQUE constraint failed: t1.c" {
          323  +      CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c UNIQUE);
          324  +      INSERT INTO t1 VALUES(4, 2, 'three');
          325  +    } 
          326  +
          327  +    3 SQLITE_CONSTRAINT "UNIQUE constraint failed: t1.a" {
          328  +      CREATE TABLE t1(a PRIMARY KEY, b, c);
          329  +      INSERT INTO t1 VALUES(3, 2, 1);
          330  +    } 
          331  +
          332  +    4 SQLITE_CONSTRAINT "UNIQUE constraint failed: t1.c" {
          333  +      CREATE TABLE t1(a PRIMARY KEY, b, c UNIQUE);
          334  +      INSERT INTO t1 VALUES(4, 2, 'three');
          335  +    } 
          336  +
          337  +  } {
          338  +    reset_db
          339  +    execsql $schema
          340  +    set cksum [dbcksum db main]
          341  +
          342  +    do_test $tn3.3.$tn.1 {
          343  +      create_ota1 ota.db
          344  +      sqlite3ota ota test.db ota.db
          345  +      while {[set res [ota step]]=="SQLITE_OK"} {}
          346  +      set res
          347  +    } $errcode
          348  +
          349  +    do_test $tn3.3.$tn.2 { ota step } $errcode
          350  +
          351  +    do_test $tn3.3.$tn.3 { 
          352  +      list [catch { ota close } msg] $msg
          353  +    } [list 1 "$errcode - $errmsg"]
          354  +
          355  +    do_test $tn3.3.$tn.4 { dbcksum db main } $cksum
          356  +  }
          357  +
          358  +  #-------------------------------------------------------------------------
          359  +  #
          360  +  foreach {tn2 cmd} {1 run_ota 2 step_ota 3 step_ota_state } {
          361  +    foreach {tn schema} {
          362  +      1 {
          363  +        CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
          364  +      }
          365  +      2 {
          366  +        CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
          367  +        CREATE INDEX i1 ON t1(b);
          368  +      }
          369  +      3 {
          370  +        CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
          371  +        CREATE INDEX i1 ON t1(b);
          372  +        CREATE INDEX i2 ON t1(c, b);
          373  +        CREATE INDEX i3 ON t1(c, b, c);
          374  +      }
          375  +      4 {
          376  +        CREATE TABLE t1(a INT PRIMARY KEY, b, c) WITHOUT ROWID;
          377  +        CREATE INDEX i1 ON t1(b);
          378  +        CREATE INDEX i2 ON t1(c, b);
          379  +        CREATE INDEX i3 ON t1(c, b, c);
          380  +      }
          381  +      5 {
          382  +        CREATE TABLE t1(a INT PRIMARY KEY, b, c);
          383  +        CREATE INDEX i1 ON t1(b);
          384  +        CREATE INDEX i2 ON t1(c, b);
          385  +        CREATE INDEX i3 ON t1(c, b, c);
          386  +      }
          387  +
          388  +      6 {
          389  +        CREATE TABLE t1(a INT PRIMARY KEY DESC, b, c);
          390  +        CREATE INDEX i1 ON t1(b DESC);
          391  +        CREATE INDEX i2 ON t1(c, b);
          392  +        CREATE INDEX i3 ON t1(c DESC, b, c);
          393  +      }
          394  +      7 {
          395  +        CREATE TABLE t1(a INT PRIMARY KEY DESC, b, c) WITHOUT ROWID;
          396  +        CREATE INDEX i1 ON t1(b);
          397  +        CREATE INDEX i2 ON t1(c, b);
          398  +        CREATE INDEX i3 ON t1(c, b, c);
          399  +      }
          400  +    } {
          401  +      reset_db
          402  +      execsql $schema
          403  +      execsql {
          404  +        INSERT INTO t1 VALUES(2, 'hello', 'world');
          405  +        INSERT INTO t1 VALUES(4, 'hello', 'planet');
          406  +        INSERT INTO t1 VALUES(6, 'hello', 'xyz');
          407  +      }
          408  +
          409  +      create_ota4 ota.db
          410  +      set check [dbfilecksum ota.db]
          411  +      forcedelete state.db
          412  +    
          413  +      do_test $tn3.4.$tn2.$tn.1 {
          414  +        $cmd test.db ota.db
          415  +      } {SQLITE_DONE}
          416  +      
          417  +      do_execsql_test $tn3.4.$tn2.$tn.2 {
          418  +        SELECT * FROM t1 ORDER BY a ASC;
          419  +      } {
          420  +        1 2 3 
          421  +        3 8 9
          422  +        6 hello xyz
          423  +      }
          424  +    
          425  +      do_execsql_test $tn3.4.$tn2.$tn.3 { PRAGMA integrity_check } ok
          426  +
          427  +      if {$cmd=="step_ota_state"} {
          428  +        do_test $tn3.4.$tn2.$tn.4 { file exists state.db } 1
          429  +        do_test $tn3.4.$tn2.$tn.5 { expr {$check == [dbfilecksum ota.db]} } 1
          430  +      } else {
          431  +        do_test $tn3.4.$tn2.$tn.6 { file exists state.db } 0
          432  +        do_test $tn3.4.$tn2.$tn.7 { expr {$check == [dbfilecksum ota.db]} } 0
          433  +      }
          434  +    }
          435  +  }
          436  +
          437  +  foreach {tn2 cmd} {1 run_ota 2 step_ota 3 step_ota_state} {
          438  +    foreach {tn schema} {
          439  +      1 {
          440  +        CREATE TABLE t1(c, b, '(a)' INTEGER PRIMARY KEY);
          441  +        CREATE INDEX i1 ON t1(c, b);
          442  +      }
          443  +      2 {
          444  +        CREATE TABLE t1(c, b, '(a)' PRIMARY KEY);
          445  +      }
          446  +      3 {
          447  +        CREATE TABLE t1(c, b, '(a)' PRIMARY KEY) WITHOUT ROWID;
          448  +      }
          449  +    } {
          450  +      reset_db
          451  +      execsql $schema
          452  +      execsql {
          453  +        INSERT INTO t1('(a)', b, c) VALUES(2, 'hello', 'world');
          454  +        INSERT INTO t1('(a)', b, c) VALUES(4, 'hello', 'planet');
          455  +        INSERT INTO t1('(a)', b, c) VALUES(6, 'hello', 'xyz');
          456  +      }
          457  +
          458  +      create_ota4b ota.db
          459  +      set check [dbfilecksum ota.db]
          460  +      forcedelete state.db
          461  +    
          462  +      do_test $tn3.5.$tn2.$tn.1 {
          463  +        $cmd test.db ota.db
          464  +      } {SQLITE_DONE}
          465  +      
          466  +      do_execsql_test $tn3.5.$tn2.$tn.2 {
          467  +        SELECT * FROM t1 ORDER BY "(a)" ASC;
          468  +      } {
          469  +        3 2 1
          470  +        9 8 3
          471  +        xyz hello 6
          472  +      }
          473  +    
          474  +      do_execsql_test $tn3.4.$tn2.$tn.3 { PRAGMA integrity_check } ok
          475  +
          476  +      if {$cmd=="step_ota_state"} {
          477  +        do_test $tn3.5.$tn2.$tn.4 { file exists state.db } 1
          478  +        do_test $tn3.5.$tn2.$tn.5 { expr {$check == [dbfilecksum ota.db]} } 1
          479  +      } else {
          480  +        do_test $tn3.5.$tn2.$tn.6 { file exists state.db } 0
          481  +        do_test $tn3.5.$tn2.$tn.7 { expr {$check == [dbfilecksum ota.db]} } 0
          482  +      }
          483  +    }
          484  +  }
          485  +
          486  +  #-------------------------------------------------------------------------
          487  +  #
          488  +  foreach {tn2 cmd} {1 run_ota 2 step_ota 3 step_ota_state} {
          489  +    foreach {tn schema} {
          490  +      1 {
          491  +        CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
          492  +      }
          493  +      2 {
          494  +        CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d);
          495  +        CREATE INDEX i1 ON t1(d);
          496  +        CREATE INDEX i2 ON t1(d, c);
          497  +        CREATE INDEX i3 ON t1(d, c, b);
          498  +        CREATE INDEX i4 ON t1(b);
          499  +        CREATE INDEX i5 ON t1(c);
          500  +        CREATE INDEX i6 ON t1(c, b);
          501  +      }
          502  +      3 {
          503  +        CREATE TABLE t1(a PRIMARY KEY, b, c, d) WITHOUT ROWID;
          504  +        CREATE INDEX i1 ON t1(d);
          505  +        CREATE INDEX i2 ON t1(d, c);
          506  +        CREATE INDEX i3 ON t1(d, c, b);
          507  +        CREATE INDEX i4 ON t1(b);
          508  +        CREATE INDEX i5 ON t1(c);
          509  +        CREATE INDEX i6 ON t1(c, b);
          510  +      }
          511  +      4 {
          512  +        CREATE TABLE t1(a PRIMARY KEY, b, c, d);
          513  +        CREATE INDEX i1 ON t1(d);
          514  +        CREATE INDEX i2 ON t1(d, c);
          515  +        CREATE INDEX i3 ON t1(d, c, b);
          516  +        CREATE INDEX i4 ON t1(b);
          517  +        CREATE INDEX i5 ON t1(c);
          518  +        CREATE INDEX i6 ON t1(c, b);
          519  +      }
          520  +    } {
          521  +      reset_db
          522  +      execsql $schema
          523  +      execsql {
          524  +        INSERT INTO t1 VALUES(1, 2, 3, 4);
          525  +        INSERT INTO t1 VALUES(2, 5, 6, 7);
          526  +        INSERT INTO t1 VALUES(3, 8, 9, 10);
          527  +      }
          528  +    
          529  +      create_ota5 ota.db
          530  +      set check [dbfilecksum ota.db]
          531  +      forcedelete state.db
          532  +
          533  +      do_test $tn3.5.$tn2.$tn.1 {
          534  +        $cmd test.db ota.db
          535  +      } {SQLITE_DONE}
          536  +      
          537  +      do_execsql_test $tn3.5.$tn2.$tn.2 {
          538  +        SELECT * FROM t1 ORDER BY a ASC;
          539  +      } {
          540  +        1 2 3 5
          541  +        2 5 10 5
          542  +        3 11 9 10
          543  +      }
          544  +    
          545  +      do_execsql_test $tn3.6.$tn2.$tn.3 { PRAGMA integrity_check } ok
          546  +
          547  +      if {$cmd=="step_ota_state"} {
          548  +        do_test $tn3.6.$tn2.$tn.4 { file exists state.db } 1
          549  +        do_test $tn3.6.$tn2.$tn.5 { expr {$check == [dbfilecksum ota.db]} } 1
          550  +      } else {
          551  +        do_test $tn3.6.$tn2.$tn.6 { file exists state.db } 0
          552  +        do_test $tn3.6.$tn2.$tn.7 { expr {$check == [dbfilecksum ota.db]} } 0
          553  +      }
          554  +    }
          555  +  }
          556  +
          557  +  #-------------------------------------------------------------------------
          558  +  # Test some error cases:
          559  +  # 
          560  +  #   * A virtual table with no ota_rowid column.
          561  +  #   * A no-PK table with no ota_rowid column.
          562  +  #   * A PK table with an ota_rowid column.
          563  +  #
          564  +  #   6: An update string of the wrong length
          565  +  #
          566  +  ifcapable fts3 {
          567  +    foreach {tn schema error} {
          568  +       1 {
          569  +         CREATE TABLE t1(a, b);
          570  +         CREATE TABLE ota.data_t1(a, b, ota_control);
          571  +       } {SQLITE_ERROR - table data_t1 requires ota_rowid column}
          572  +    
          573  +       2 {
          574  +         CREATE VIRTUAL TABLE t1 USING fts4(a, b);
          575  +         CREATE TABLE ota.data_t1(a, b, ota_control);
          576  +       } {SQLITE_ERROR - table data_t1 requires ota_rowid column}
          577  +    
          578  +       3 {
          579  +         CREATE TABLE t1(a PRIMARY KEY, b);
          580  +         CREATE TABLE ota.data_t1(a, b, ota_rowid, ota_control);
          581  +       } {SQLITE_ERROR - table data_t1 may not have ota_rowid column}
          582  +    
          583  +       4 {
          584  +         CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
          585  +         CREATE TABLE ota.data_t1(a, b, ota_rowid, ota_control);
          586  +       } {SQLITE_ERROR - table data_t1 may not have ota_rowid column}
          587  +    
          588  +       5 {
          589  +         CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID;
          590  +         CREATE TABLE ota.data_t1(a, b, ota_rowid, ota_control);
          591  +       } {SQLITE_ERROR - table data_t1 may not have ota_rowid column}
          592  +
          593  +       6 {
          594  +         CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID;
          595  +         CREATE TABLE ota.data_t1(a, b, ota_control);
          596  +         INSERT INTO ota.data_t1 VALUES(1, 2, 'x.x');
          597  +       } {SQLITE_ERROR - invalid ota_control value}
          598  +
          599  +       7 {
          600  +         CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID;
          601  +         CREATE TABLE ota.data_t1(a, b, ota_control);
          602  +         INSERT INTO ota.data_t1 VALUES(1, 2, NULL);
          603  +       } {SQLITE_ERROR - invalid ota_control value}
          604  +
          605  +       8 {
          606  +         CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID;
          607  +         CREATE TABLE ota.data_t1(a, b, ota_control);
          608  +         INSERT INTO ota.data_t1 VALUES(1, 2, 4);
          609  +       } {SQLITE_ERROR - invalid ota_control value}
          610  +
          611  +       9 {
          612  +         CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID;
          613  +         CREATE TABLE ota.data_t1(a, b, ota_control);
          614  +         INSERT INTO ota.data_t1 VALUES(1, 2, 2);
          615  +       } {SQLITE_ERROR - invalid ota_control value}
          616  +
          617  +       10 {
          618  +         CREATE TABLE t2(a, b);
          619  +         CREATE TABLE ota.data_t1(a, b, ota_control);
          620  +         INSERT INTO ota.data_t1 VALUES(1, 2, 2);
          621  +       } {SQLITE_ERROR - no such table: t1}
          622  +
          623  +       11 {
          624  +         CREATE TABLE ota.data_t2(a, b, ota_control);
          625  +         INSERT INTO ota.data_t2 VALUES(1, 2, 2);
          626  +       } {SQLITE_ERROR - no such table: t2}
          627  +
          628  +    } {
          629  +      reset_db
          630  +      forcedelete ota.db
          631  +      execsql { ATTACH 'ota.db' AS ota }
          632  +      execsql $schema
          633  +
          634  +      do_test $tn3.7.$tn {
          635  +        list [catch { run_ota test.db ota.db } msg] $msg
          636  +      } [list 1 $error]
          637  +    }
          638  +  }
          639  +
          640  +  # Test that an OTA database containing no input tables is handled
          641  +  # correctly.
          642  +  reset_db
          643  +  forcedelete ota.db
          644  +  do_test $tn3.8 {
          645  +    list [catch { run_ota test.db ota.db } msg] $msg
          646  +  } {0 SQLITE_DONE}
          647  +  
          648  +  # Test that OTA can update indexes containing NULL values.
          649  +  #
          650  +  reset_db
          651  +  forcedelete ota.db
          652  +  do_execsql_test $tn3.9.1 {
          653  +    CREATE TABLE t1(a PRIMARY KEY, b, c);
          654  +    CREATE INDEX i1 ON t1(b, c);
          655  +    INSERT INTO t1 VALUES(1, 1, NULL);
          656  +    INSERT INTO t1 VALUES(2, NULL, 2);
          657  +    INSERT INTO t1 VALUES(3, NULL, NULL);
          658  +
          659  +    ATTACH 'ota.db' AS ota;
          660  +    CREATE TABLE ota.data_t1(a, b, c, ota_control);
          661  +    INSERT INTO data_t1 VALUES(1, NULL, NULL, 1);
          662  +    INSERT INTO data_t1 VALUES(3, NULL, NULL, 1);
          663  +  } {}
          664  +
          665  +  do_test $tn3.9.2 {
          666  +    list [catch { run_ota test.db ota.db } msg] $msg
          667  +  } {0 SQLITE_DONE}
          668  +
          669  +  do_execsql_test $tn3.9.3 {
          670  +    SELECT * FROM t1
          671  +  } {2 {} 2}
          672  +  do_execsql_test $tn3.9.4 { PRAGMA integrity_check } {ok}
          673  +
          674  +  catch { db close }
          675  +  eval $destroy_vfs
          676  +}
          677  +
          678  +
          679  +finish_test
          680  +

Added ext/ota/ota10.test.

            1  +# 2014 August 30
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +if {![info exists testdir]} {
           14  +  set testdir [file join [file dirname [info script]] .. .. test]
           15  +}
           16  +source $testdir/tester.tcl
           17  +set ::testprefix ota10
           18  +
           19  +
           20  +#--------------------------------------------------------------------
           21  +# Test that UPDATE commands work even if the input columns are in a 
           22  +# different order to the output columns. 
           23  +#
           24  +do_execsql_test 1.0 {
           25  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
           26  +  INSERT INTO t1 VALUES(1, 'b', 'c');
           27  +}
           28  +
           29  +proc apply_ota {sql} {
           30  +  forcedelete ota.db
           31  +  sqlite3 db2 ota.db
           32  +  db2 eval $sql
           33  +  db2 close
           34  +  sqlite3ota ota test.db ota.db
           35  +  while { [ota step]=="SQLITE_OK" } {}
           36  +  ota close
           37  +}
           38  +
           39  +do_test 1.1 {
           40  +  apply_ota {
           41  +    CREATE TABLE data_t1(a, c, b, ota_control);
           42  +    INSERT INTO data_t1 VALUES(1, 'xxx', NULL, '.x.');
           43  +  }
           44  +  db eval { SELECT * FROM t1 }
           45  +} {1 b xxx}
           46  +
           47  +#--------------------------------------------------------------------
           48  +# Test that the hidden languageid column of an fts4 table can be 
           49  +# written.
           50  +#
           51  +ifcapable fts3 {
           52  +  do_execsql_test 2.0 {
           53  +    CREATE VIRTUAL TABLE ft USING fts4(a, b, languageid='langid');
           54  +  }
           55  +  do_test 2.1 {
           56  +    apply_ota {
           57  +      CREATE TABLE data_ft(a, b, ota_rowid, langid, ota_control);
           58  +      INSERT INTO data_ft VALUES('a', 'b', 22, 1, 0);    -- insert
           59  +      INSERT INTO data_ft VALUES('a', 'b', 23, 10, 0);   -- insert
           60  +      INSERT INTO data_ft VALUES('a', 'b', 24, 100, 0);  -- insert
           61  +    }
           62  +    db eval { SELECT a, b, rowid, langid FROM ft }
           63  +  } [list {*}{
           64  +    a b 22 1
           65  +    a b 23 10
           66  +    a b 24 100
           67  +  }]
           68  +  
           69  +  # Or not - this data_xxx table has no langid column, so langid 
           70  +  # defaults to 0.
           71  +  #
           72  +  do_test 2.2 {
           73  +    apply_ota {
           74  +      CREATE TABLE data_ft(a, b, ota_rowid, ota_control);
           75  +      INSERT INTO data_ft VALUES('a', 'b', 25, 0);    -- insert
           76  +    }
           77  +    db eval { SELECT a, b, rowid, langid FROM ft }
           78  +  } [list {*}{
           79  +    a b 22 1
           80  +    a b 23 10
           81  +    a b 24 100
           82  +    a b 25 0
           83  +  }]
           84  +  
           85  +  # Update langid.
           86  +  #
           87  +  do_test 2.3 {
           88  +    apply_ota {
           89  +      CREATE TABLE data_ft(a, b, ota_rowid, langid, ota_control);
           90  +      INSERT INTO data_ft VALUES(NULL, NULL, 23, 50, '..x');
           91  +      INSERT INTO data_ft VALUES(NULL, NULL, 25, 500, '..x');
           92  +    }
           93  +    db eval { SELECT a, b, rowid, langid FROM ft }
           94  +  } [list {*}{
           95  +    a b 22 1
           96  +    a b 23 50
           97  +    a b 24 100
           98  +    a b 25 500
           99  +  }]
          100  +}
          101  +
          102  +#--------------------------------------------------------------------
          103  +# Test that if writing a hidden virtual table column is an error, 
          104  +# attempting to do so via ota is also an error.
          105  +#
          106  +ifcapable fts3 {
          107  +  do_execsql_test 3.0 {
          108  +    CREATE VIRTUAL TABLE xt USING fts4(a);
          109  +  }
          110  +  do_test 3.1 {
          111  +    list [catch {
          112  +      apply_ota {
          113  +        CREATE TABLE data_xt(a, xt, ota_rowid, ota_control);
          114  +        INSERT INTO data_xt VALUES('a', 'b', 1, 0);
          115  +      }
          116  +    } msg] $msg
          117  +  } {1 {SQLITE_ERROR - SQL logic error or missing database}}
          118  +}
          119  +
          120  +#--------------------------------------------------------------------
          121  +# Test that it is not possible to violate a NOT NULL constraint by
          122  +# applying an OTA update.
          123  +#
          124  +do_execsql_test 4.1 {
          125  +  CREATE TABLE t2(a INTEGER NOT NULL, b TEXT NOT NULL, c PRIMARY KEY);
          126  +  CREATE TABLE t3(a INTEGER NOT NULL, b TEXT NOT NULL, c INTEGER PRIMARY KEY);
          127  +  CREATE TABLE t4(a, b, PRIMARY KEY(a, b)) WITHOUT ROWID;
          128  +
          129  +  INSERT INTO t2 VALUES(10, 10, 10);
          130  +  INSERT INTO t3 VALUES(10, 10, 10);
          131  +  INSERT INTO t4 VALUES(10, 10);
          132  +}
          133  +
          134  +foreach {tn error ota} {
          135  +  2 {SQLITE_CONSTRAINT - NOT NULL constraint failed: t2.a} {
          136  +    INSERT INTO data_t2 VALUES(NULL, 'abc', 1, 0);
          137  +  }
          138  +  3 {SQLITE_CONSTRAINT - NOT NULL constraint failed: t2.b} {
          139  +    INSERT INTO data_t2 VALUES(2, NULL, 1, 0);
          140  +  }
          141  +  4 {SQLITE_CONSTRAINT - NOT NULL constraint failed: t2.c} {
          142  +    INSERT INTO data_t2 VALUES(1, 'abc', NULL, 0);
          143  +  }
          144  +
          145  +  5 {SQLITE_MISMATCH - datatype mismatch} {
          146  +    INSERT INTO data_t3 VALUES(1, 'abc', NULL, 0);
          147  +  }
          148  +
          149  +  6 {SQLITE_CONSTRAINT - NOT NULL constraint failed: t4.b} {
          150  +    INSERT INTO data_t4 VALUES('a', NULL, 0);
          151  +  }
          152  +  7 {SQLITE_CONSTRAINT - NOT NULL constraint failed: t4.a} {
          153  +    INSERT INTO data_t4 VALUES(NULL, 'a', 0);
          154  +  }
          155  +  8  {SQLITE_CONSTRAINT - NOT NULL constraint failed: t2.a} {
          156  +    INSERT INTO data_t2 VALUES(NULL, 0, 10, 'x..');
          157  +  }
          158  +  9  {SQLITE_CONSTRAINT - NOT NULL constraint failed: t3.b} {
          159  +    INSERT INTO data_t3 VALUES(10, NULL, 10, '.x.');
          160  +  }
          161  +
          162  +  10 {SQLITE_MISMATCH - datatype mismatch} {
          163  +    INSERT INTO data_t3 VALUES(1, 'abc', 'text', 0);
          164  +  }
          165  +} {
          166  +  set ota "
          167  +    CREATE TABLE data_t2(a, b, c, ota_control);
          168  +    CREATE TABLE data_t3(a, b, c, ota_control);
          169  +    CREATE TABLE data_t4(a, b, ota_control);
          170  +    $ota
          171  +  "
          172  +  do_test 4.2.$tn {
          173  +    list [catch { apply_ota $ota } msg] $msg
          174  +  } [list 1 $error]
          175  +}
          176  +
          177  +do_test 4.3 {
          178  +  set ota {
          179  +    CREATE TABLE data_t3(a, b, c, ota_control);
          180  +    INSERT INTO data_t3 VALUES(1, 'abc', '5', 0);
          181  +    INSERT INTO data_t3 VALUES(1, 'abc', '-6.0', 0);
          182  +  }
          183  +  list [catch { apply_ota $ota } msg] $msg
          184  +} {0 SQLITE_DONE}
          185  +
          186  +
          187  +finish_test
          188  +

Added ext/ota/ota11.test.

            1  +# 2015 February 16
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +if {![info exists testdir]} {
           14  +  set testdir [file join [file dirname [info script]] .. .. test]
           15  +}
           16  +source $testdir/tester.tcl
           17  +set ::testprefix ota11
           18  +
           19  +
           20  +#--------------------------------------------------------------------
           21  +# Test that the xAccess() method of an ota vfs handles queries other
           22  +# than SQLITE_ACCESS_EXISTS correctly. The test code below causes
           23  +# SQLite to call xAccess(SQLITE_ACCESS_READWRITE) on the directory
           24  +# path argument passed to "PRAGMA temp_store_directory".
           25  +#
           26  +do_test 1.1 {
           27  +  sqlite3ota_create_vfs -default ota ""
           28  +  reset_db
           29  +  catchsql { PRAGMA temp_store_directory = '/no/such/directory' }
           30  +} {1 {not a writable directory}}
           31  +
           32  +do_test 1.2 {
           33  +  catchsql " PRAGMA temp_store_directory = '[pwd]' "
           34  +} {0 {}}
           35  +
           36  +do_test 1.3 {
           37  +  catchsql " PRAGMA temp_store_directory = '' "
           38  +} {0 {}}
           39  +
           40  +do_test 1.4 {
           41  +  db close
           42  +  sqlite3ota_destroy_vfs ota
           43  +} {}
           44  +
           45  +#--------------------------------------------------------------------
           46  +# Try to trick ota into operating on a database opened in wal mode.
           47  +#
           48  +reset_db
           49  +do_execsql_test 2.1 {
           50  +  CREATE TABLE t1(a PRIMARY KEY, b, c);
           51  +  INSERT INTO t1 VALUES(1, 2, 3);
           52  +  PRAGMA journal_mode = 'wal';
           53  +  CREATE TABLE t2(d PRIMARY KEY, e, f);
           54  +} {wal}
           55  +
           56  +do_test 2.2 {
           57  +  db_save 
           58  +  db close
           59  +
           60  +  forcedelete ota.db
           61  +  sqlite3 dbo ota.db
           62  +  dbo eval {
           63  +    CREATE TABLE data_t1(a, b, c, ota_control);
           64  +    INSERT INTO data_t1 VALUES(4, 5, 6, 0);
           65  +    INSERT INTO data_t1 VALUES(7, 8, 9, 0);
           66  +  }
           67  +  dbo close
           68  +
           69  +  db_restore 
           70  +  hexio_write test.db 18 0101
           71  +  file exists test.db-wal
           72  +} {1}
           73  +
           74  +do_test 2.3 {
           75  +  sqlite3ota ota test.db ota.db
           76  +  ota step
           77  +} {SQLITE_ERROR}
           78  +
           79  +do_test 2.4 {
           80  +  list [catch {ota close} msg] $msg
           81  +} {1 {SQLITE_ERROR - cannot update wal mode database}}
           82  +
           83  +#--------------------------------------------------------------------
           84  +# Test a constraint violation message with an unusual table name. 
           85  +# Specifically, one for which the first character is a codepoint
           86  +# smaller than 30 (character '0').
           87  +#
           88  +reset_db
           89  +do_execsql_test 3.1 {
           90  +  CREATE TABLE "(t1)"(a PRIMARY KEY, b, c);
           91  +  INSERT INTO "(t1)" VALUES(1, 2, 3);
           92  +  INSERT INTO "(t1)" VALUES(4, 5, 6);
           93  +}
           94  +db close
           95  +
           96  +do_test 3.2 {
           97  +  forcedelete ota.db
           98  +  sqlite3 dbo ota.db
           99  +  dbo eval {
          100  +    CREATE TABLE "data_(t1)"(a, b, c, ota_control);
          101  +    INSERT INTO "data_(t1)" VALUES(4, 8, 9, 0);
          102  +  }
          103  +  dbo close
          104  +
          105  +  sqlite3ota ota test.db ota.db
          106  +  ota step
          107  +  ota step
          108  +} {SQLITE_CONSTRAINT}
          109  +
          110  +do_test 3.3 {
          111  +  list [catch {ota close} msg] $msg
          112  +} {1 {SQLITE_CONSTRAINT - UNIQUE constraint failed: (t1).a}}
          113  +
          114  +#--------------------------------------------------------------------
          115  +# Check that once an OTA update has been applied, attempting to apply
          116  +# it a second time is a no-op (as the state stored in the OTA database is
          117  +# "all steps completed").
          118  +#
          119  +reset_db
          120  +do_execsql_test 4.1 {
          121  +  CREATE TABLE "(t1)"(a, b, c, PRIMARY KEY(c, b, a));
          122  +  INSERT INTO "(t1)" VALUES(1, 2, 3);
          123  +  INSERT INTO "(t1)" VALUES(4, 5, 6);
          124  +}
          125  +db close
          126  +
          127  +do_test 4.2 {
          128  +  forcedelete ota.db
          129  +  sqlite3 dbo ota.db
          130  +  dbo eval {
          131  +    CREATE TABLE "data_(t1)"(a, b, c, ota_control);
          132  +    INSERT INTO "data_(t1)" VALUES(7, 8, 9, 0);
          133  +    INSERT INTO "data_(t1)" VALUES(1, 2, 3, 1);
          134  +  }
          135  +  dbo close
          136  +
          137  +  sqlite3ota ota test.db ota.db
          138  +  while {[ota step]=="SQLITE_OK"} { }
          139  +  ota close
          140  +} {SQLITE_DONE}
          141  +
          142  +do_test 4.3 {
          143  +  sqlite3ota ota test.db ota.db
          144  +  ota step
          145  +} {SQLITE_DONE}
          146  +
          147  +do_test 4.4 {
          148  +  ota close
          149  +} {SQLITE_DONE}
          150  +
          151  +do_test 4.5.1 {
          152  +  sqlite3 dbo ota.db
          153  +  dbo eval { INSERT INTO ota_state VALUES(100, 100) }
          154  +  dbo close
          155  +  sqlite3ota ota test.db ota.db
          156  +  ota step
          157  +} {SQLITE_CORRUPT}
          158  +do_test 4.5.2 {
          159  +  list [catch {ota close} msg] $msg
          160  +} {1 SQLITE_CORRUPT}
          161  +do_test 4.5.3 {
          162  +  sqlite3 dbo ota.db
          163  +  dbo eval { DELETE FROM ota_state WHERE k = 100 }
          164  +  dbo close 
          165  +} {}
          166  +
          167  +# Also, check that an invalid state value in the ota_state table is
          168  +# detected and reported as corruption.
          169  +do_test 4.6.1 {
          170  +  sqlite3 dbo ota.db
          171  +  dbo eval { UPDATE ota_state SET v = v*-1 WHERE k = 1 }
          172  +  dbo close
          173  +  sqlite3ota ota test.db ota.db
          174  +  ota step
          175  +} {SQLITE_CORRUPT}
          176  +do_test 4.6.2 {
          177  +  list [catch {ota close} msg] $msg
          178  +} {1 SQLITE_CORRUPT}
          179  +do_test 4.6.3 {
          180  +  sqlite3 dbo ota.db
          181  +  dbo eval { UPDATE ota_state SET v = v*-1 WHERE k = 1 }
          182  +  dbo close 
          183  +} {}
          184  +
          185  +do_test 4.7.1 {
          186  +  sqlite3 dbo ota.db
          187  +  dbo eval { UPDATE ota_state SET v = 1 WHERE k = 1 }
          188  +  dbo eval { UPDATE ota_state SET v = 'nosuchtable' WHERE k = 2 }
          189  +  dbo close
          190  +  sqlite3ota ota test.db ota.db
          191  +  ota step
          192  +} {SQLITE_ERROR}
          193  +do_test 4.7.2 {
          194  +  list [catch {ota close} msg] $msg
          195  +} {1 {SQLITE_ERROR - ota_state mismatch error}}
          196  +
          197  +finish_test
          198  +

Added ext/ota/ota12.test.

            1  +# 2015 February 16
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +if {![info exists testdir]} {
           14  +  set testdir [file join [file dirname [info script]] .. .. test]
           15  +}
           16  +source $testdir/tester.tcl
           17  +source $testdir/lock_common.tcl
           18  +set ::testprefix ota12
           19  +
           20  +set setup_sql {
           21  +  DROP TABLE IF EXISTS xx;
           22  +  DROP TABLE IF EXISTS xy;
           23  +  CREATE TABLE xx(a, b, c PRIMARY KEY);
           24  +  INSERT INTO xx VALUES(1, 2, 3);
           25  +  CREATE TABLE xy(a, b, c PRIMARY KEY);
           26  +
           27  +  ATTACH 'ota.db' AS ota;
           28  +    DROP TABLE IF EXISTS data_xx;
           29  +    CREATE TABLE ota.data_xx(a, b, c, ota_control);
           30  +    INSERT INTO data_xx VALUES(4, 5, 6, 0);
           31  +    INSERT INTO data_xx VALUES(7, 8, 9, 0);
           32  +    CREATE TABLE ota.data_xy(a, b, c, ota_control);
           33  +    INSERT INTO data_xy VALUES(10, 11, 12, 0);
           34  +  DETACH ota;
           35  +}
           36  +
           37  +do_multiclient_test tn {
           38  +
           39  +  # Initialize a target (test.db) and ota (ota.db) database.
           40  +  #
           41  +  forcedelete ota.db
           42  +  sql1 $setup_sql
           43  +
           44  +  # Using connection 2, open a read transaction on the target database.
           45  +  # OTA will still be able to generate "test.db-oal", but it will not be
           46  +  # able to rename it to "test.db-wal".
           47  +  #
           48  +  do_test 1.$tn.1 {
           49  +    sql2 { BEGIN; SELECT * FROM xx; }
           50  +  } {1 2 3}
           51  +  do_test 1.$tn.2 {
           52  +    sqlite3ota ota test.db ota.db
           53  +    while 1 {
           54  +      set res [ota step]
           55  +      if {$res!="SQLITE_OK"} break
           56  +    }
           57  +    set res
           58  +  } {SQLITE_BUSY}
           59  +
           60  +  do_test 1.$tn.3 { sql2 { SELECT * FROM xx; } } {1 2 3}
           61  +  do_test 1.$tn.4 { sql2 { SELECT * FROM xy; } } {}
           62  +  do_test 1.$tn.5 {
           63  +    list [file exists test.db-wal] [file exists test.db-oal]
           64  +  } {0 1}
           65  +  do_test 1.$tn.6 { sql2 COMMIT } {}
           66  +
           67  +  # The ota object that hit the SQLITE_BUSY error above cannot be reused.
           68  +  # It is stuck in a permanent SQLITE_BUSY state at this point.
           69  +  #
           70  +  do_test 1.$tn.7 { ota step } {SQLITE_BUSY}
           71  +  do_test 1.$tn.8 { 
           72  +    list [catch { ota close } msg] $msg 
           73  +  } {1 SQLITE_BUSY}
           74  +
           75  +  do_test 1.$tn.9.1 { sql2 { BEGIN EXCLUSIVE } } {}
           76  +  do_test 1.$tn.9.2 {
           77  +    sqlite3ota ota test.db ota.db
           78  +    ota step
           79  +  } {SQLITE_BUSY}
           80  +  do_test 1.$tn.9.3 {
           81  +    list [catch { ota close } msg] $msg 
           82  +  } {1 {SQLITE_BUSY - database is locked}}
           83  +  do_test 1.$tn.9.4 { sql2 COMMIT } {}
           84  +
           85  +  sqlite3ota ota test.db ota.db
           86  +  do_test 1.$tn.10.1 { sql2 { BEGIN EXCLUSIVE } } {}
           87  +  do_test 1.$tn.10.2 {
           88  +    ota step
           89  +  } {SQLITE_BUSY}
           90  +  do_test 1.$tn.10.3 {
           91  +    list [catch { ota close } msg] $msg 
           92  +  } {1 SQLITE_BUSY}
           93  +  do_test 1.$tn.10.4 { sql2 COMMIT } {}
           94  +
           95  +  # A new ota object can finish the work though.
           96  +  #
           97  +  do_test 1.$tn.11 {
           98  +    sqlite3ota ota test.db ota.db
           99  +    ota step
          100  +  } {SQLITE_OK}
          101  +  do_test 1.$tn.12 {
          102  +    list [file exists test.db-wal] [file exists test.db-oal]
          103  +  } {1 0}
          104  +  do_test 1.$tn.13 {
          105  +    while 1 {
          106  +      set res [ota step]
          107  +      if {$res!="SQLITE_OK"} break
          108  +    }
          109  +    set res
          110  +  } {SQLITE_DONE}
          111  +
          112  +  do_test 1.$tn.14 {
          113  +    ota close
          114  +  } {SQLITE_DONE}
          115  +}
          116  +
          117  +do_multiclient_test tn {
          118  +
          119  +  # Initialize a target (test.db) and ota (ota.db) database.
          120  +  #
          121  +  forcedelete ota.db
          122  +  sql1 $setup_sql
          123  +
          124  +  do_test 2.$tn.1 {
          125  +    sqlite3ota ota test.db ota.db
          126  +    while {[file exists test.db-wal]==0} {
          127  +      if {[ota step]!="SQLITE_OK"} {error "problem here...."}
          128  +    }
          129  +    ota close
          130  +  } {SQLITE_OK}
          131  +
          132  +
          133  +  do_test 2.$tn.2 { sql2 { BEGIN IMMEDIATE } } {}
          134  +
          135  +  do_test 2.$tn.3 { 
          136  +    sqlite3ota ota test.db ota.db
          137  +    ota step 
          138  +  } {SQLITE_BUSY}
          139  +
          140  +  do_test 2.$tn.4 { list [catch { ota close } msg] $msg } {1 SQLITE_BUSY}
          141  +
          142  +  do_test 2.$tn.5 { 
          143  +    sql2 { SELECT * FROM xx ; COMMIT }
          144  +  } {1 2 3 4 5 6 7 8 9}
          145  +
          146  +  do_test 2.$tn.6 {
          147  +    sqlite3ota ota test.db ota.db
          148  +    ota step
          149  +    ota close
          150  +  } {SQLITE_OK}
          151  +
          152  +  do_test 2.$tn.7 { sql2 { BEGIN EXCLUSIVE } } {}
          153  +
          154  +  do_test 2.$tn.8 { 
          155  +    sqlite3ota ota test.db ota.db
          156  +    ota step 
          157  +  } {SQLITE_BUSY}
          158  +  do_test 2.$tn.9 { list [catch { ota close } msg] $msg } {1 SQLITE_BUSY}
          159  +  do_test 2.$tn.10 { 
          160  +    sql2 { SELECT * FROM xx ; COMMIT }
          161  +  } {1 2 3 4 5 6 7 8 9}
          162  +
          163  +  do_test 2.$tn.11 {
          164  +    sqlite3ota ota test.db ota.db
          165  +    while {[ota step]=="SQLITE_OK"} {}
          166  +    ota close
          167  +  } {SQLITE_DONE}
          168  +
          169  +}
          170  +
          171  +finish_test
          172  +

Added ext/ota/ota13.test.

            1  +# 2015 February 16
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# Test an OTA update that features lots of different ota_control strings
           13  +# for UPDATE statements. This tests OTA's internal UPDATE statement cache.
           14  +#
           15  +
           16  +if {![info exists testdir]} {
           17  +  set testdir [file join [file dirname [info script]] .. .. test]
           18  +}
           19  +source $testdir/tester.tcl
           20  +source $testdir/lock_common.tcl
           21  +set ::testprefix ota13
           22  +
           23  +do_execsql_test 1.0 {
           24  +  CREATE TABLE t1(a PRIMARY KEY, b, c, d, e, f, g, h);
           25  +  WITH ii(i) AS (SELECT 0 UNION ALL SELECT i+1 FROM ii WHERE i<127)
           26  +  INSERT INTO t1 SELECT i, 0, 0, 0, 0, 0, 0, 0 FROM ii;
           27  +}
           28  +
           29  +forcedelete ota.db
           30  +do_execsql_test 1.1 {
           31  +  ATTACH 'ota.db' AS ota;
           32  +  CREATE TABLE ota.data_t1(a, b, c, d, e, f, g, h, ota_control);
           33  +}
           34  +
           35  +do_test 1.2 {
           36  +  for {set i 0} {$i<128} {incr i} {
           37  +    set control "."
           38  +    for {set bit 6} {$bit>=0} {incr bit -1} {
           39  +      if { $i & (1<<$bit) } {
           40  +        append control "x"
           41  +      } else {
           42  +        append control "."
           43  +      }
           44  +    }
           45  +    execsql { INSERT INTO data_t1 VALUES($i, 1, 1, 1, 1, 1, 1, 1, $control) }
           46  +  }
           47  +} {}
           48  +
           49  +do_test 1.3 {
           50  +  sqlite3ota ota test.db ota.db
           51  +  while 1 {
           52  +    set rc [ota step]
           53  +    if {$rc!="SQLITE_OK"} break
           54  +  }
           55  +  ota close
           56  +} {SQLITE_DONE}
           57  +
           58  +do_execsql_test 1.4 {
           59  +  SELECT count(*) FROM t1 WHERE
           60  +  a == ( (b<<6) + (c<<5) + (d<<4) + (e<<3) + (f<<2) + (g<<1) + (h<<0) )
           61  +} {128}
           62  +
           63  +
           64  +finish_test
           65  +

Added ext/ota/ota3.test.

            1  +# 2014 August 30
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +if {![info exists testdir]} {
           14  +  set testdir [file join [file dirname [info script]] .. .. test]
           15  +}
           16  +source $testdir/tester.tcl
           17  +set ::testprefix ota3
           18  +
           19  +
           20  +# Run the OTA in file $ota on target database $target until completion.
           21  +#
           22  +proc run_ota {target ota} {
           23  +  sqlite3ota ota $target $ota
           24  +  while { [ota step]=="SQLITE_OK" } {}
           25  +  ota close
           26  +}
           27  +
           28  +forcedelete test.db-oal ota.db
           29  +db close
           30  +sqlite3_shutdown
           31  +sqlite3_config_uri 1
           32  +reset_db
           33  +
           34  +#--------------------------------------------------------------------
           35  +# Test that for an OTA to be applied, no corruption results if the
           36  +# affinities on the source and target table do not match.
           37  +#
           38  +do_execsql_test 1.0 {
           39  +  CREATE TABLE x1(a INTEGER PRIMARY KEY, b TEXT, c REAL);
           40  +  CREATE INDEX i1 ON x1(b, c);
           41  +} {}
           42  +
           43  +do_test 1.1 {
           44  +  sqlite3 db2 ota.db
           45  +  db2 eval {
           46  +    CREATE TABLE data_x1(a, b, c, ota_control);
           47  +    INSERT INTO data_x1 VALUES(1, '123', '123', 0);
           48  +    INSERT INTO data_x1 VALUES(2, 123, 123, 0);
           49  +  }
           50  +  db2 close
           51  +  run_ota test.db ota.db
           52  +} {SQLITE_DONE}
           53  +
           54  +do_execsql_test 1.2 {
           55  +  PRAGMA integrity_check;
           56  +} {ok}
           57  +
           58  +#--------------------------------------------------------------------
           59  +# Test that NULL values may not be inserted into INTEGER PRIMARY KEY
           60  +# columns.
           61  +#
           62  +forcedelete ota.db
           63  +reset_db
           64  +
           65  +do_execsql_test 2.0 {
           66  +  CREATE TABLE x1(a INTEGER PRIMARY KEY, b TEXT, c REAL);
           67  +  CREATE INDEX i1 ON x1(b, c);
           68  +} {}
           69  +
           70  +foreach {tn otadb} {
           71  +  1 {
           72  +    CREATE TABLE data_x1(a, b, c, ota_control);
           73  +    INSERT INTO data_x1 VALUES(NULL, 'a', 'b', 0);
           74  +  }
           75  +
           76  +  2 {
           77  +    CREATE TABLE data_x1(c, b, a, ota_control);
           78  +    INSERT INTO data_x1 VALUES('b', 'a', NULL, 0);
           79  +  }
           80  +} {
           81  +  do_test 2.$tn.1 {
           82  +    forcedelete ota.db
           83  +    sqlite3 db2 ota.db
           84  +    db2 eval $otadb
           85  +    db2 close
           86  +    list [catch { run_ota test.db ota.db } msg] $msg
           87  +  } {1 {SQLITE_MISMATCH - datatype mismatch}}
           88  +
           89  +  do_execsql_test 2.1.2 {
           90  +    PRAGMA integrity_check;
           91  +  } {ok}
           92  +}
           93  +
           94  +#--------------------------------------------------------------------
           95  +# Test that missing columns are detected.
           96  +#
           97  +forcedelete ota.db
           98  +reset_db
           99  +
          100  +do_execsql_test 2.0 {
          101  +  CREATE TABLE x1(a INTEGER PRIMARY KEY, b, c);
          102  +  CREATE INDEX i1 ON x1(b, c);
          103  +} {}
          104  +
          105  +do_test 2.1 {
          106  +  sqlite3 db2 ota.db
          107  +  db2 eval {
          108  +    CREATE TABLE data_x1(a, b, ota_control);
          109  +    INSERT INTO data_x1 VALUES(1, 'a', 0);
          110  +  }
          111  +  db2 close
          112  +  list [catch { run_ota test.db ota.db } msg] $msg
          113  +} {1 {SQLITE_ERROR - column missing from data_x1: c}}
          114  +
          115  +do_execsql_test 2.2 {
          116  +  PRAGMA integrity_check;
          117  +} {ok}
          118  +
          119  +# Also extra columns.
          120  +#
          121  +do_execsql_test 2.3 {
          122  +  CREATE TABLE x2(a INTEGER PRIMARY KEY, b, c);
          123  +  CREATE INDEX i2 ON x2(b, c);
          124  +} {}
          125  +
          126  +do_test 2.4 {
          127  +  forcedelete ota.db
          128  +  sqlite3 db2 ota.db
          129  +  db2 eval {
          130  +    CREATE TABLE data_x2(a, b, c, d, ota_control);
          131  +    INSERT INTO data_x2 VALUES(1, 'a', 2, 3, 0);
          132  +  }
          133  +  db2 close
          134  +  list [catch { run_ota test.db ota.db } msg] $msg
          135  +} {1 SQLITE_ERROR}
          136  +
          137  +do_execsql_test 2.5 {
          138  +  PRAGMA integrity_check;
          139  +} {ok}
          140  +
          141  +
          142  +#-------------------------------------------------------------------------
          143  +# Test that sqlite3ota_create_vfs() returns an error if the requested 
          144  +# parent VFS is unknown.
          145  +#
          146  +# And that nothing disasterous happens if a VFS name passed to
          147  +# sqlite3ota_destroy_vfs() is unknown or not an OTA vfs.
          148  +#
          149  +do_test 3.1 {
          150  +  list [catch {sqlite3ota_create_vfs xyz nosuchparent} msg] $msg
          151  +} {1 SQLITE_NOTFOUND}
          152  +
          153  +do_test 3.2 {
          154  +  sqlite3ota_destroy_vfs nosuchvfs
          155  +  sqlite3ota_destroy_vfs unix
          156  +  sqlite3ota_destroy_vfs win32
          157  +} {}
          158  +
          159  +#-------------------------------------------------------------------------
          160  +# Test that it is an error to specify an explicit VFS that does not 
          161  +# include ota VFS functionality.
          162  +#
          163  +do_test 4.1 {
          164  +  testvfs tvfs
          165  +  sqlite3ota ota file:test.db?vfs=tvfs ota.db 
          166  +  list [catch { ota step } msg] $msg
          167  +} {0 SQLITE_ERROR}
          168  +do_test 4.2 {
          169  +  list [catch { ota close } msg] $msg
          170  +} {1 {SQLITE_ERROR - ota vfs not found}}
          171  +tvfs delete
          172  +
          173  +#-------------------------------------------------------------------------
          174  +# Test a large ota update to ensure that wal_autocheckpoint does not get
          175  +# in the way.
          176  +#
          177  +forcedelete ota.db
          178  +reset_db
          179  +do_execsql_test 5.1 {
          180  +  CREATE TABLE x1(a, b, c, PRIMARY KEY(a)) WITHOUT ROWID;
          181  +  CREATE INDEX i1 ON x1(a);
          182  +
          183  +  ATTACH 'ota.db' AS ota;
          184  +  CREATE TABLE ota.data_x1(a, b, c, ota_control);
          185  +  WITH s(a, b, c) AS (
          186  +    SELECT randomblob(300), randomblob(300), 1
          187  +    UNION ALL
          188  +    SELECT randomblob(300), randomblob(300), c+1 FROM s WHERE c<2000
          189  +  )
          190  +  INSERT INTO data_x1 SELECT a, b, c, 0 FROM s;
          191  +}
          192  +
          193  +do_test 5.2 {
          194  +  sqlite3ota ota test.db ota.db
          195  +  while {[ota step]=="SQLITE_OK" && [file exists test.db-wal]==0} {}
          196  +  ota close
          197  +} {SQLITE_OK}
          198  +
          199  +do_test 5.3 {
          200  +  expr {[file size test.db-wal] > (1024 * 1200)}
          201  +} 1
          202  +
          203  +do_test 6.1 { sqlite3ota_internal_test } {}
          204  +
          205  +finish_test
          206  +
          207  +

Added ext/ota/ota5.test.

            1  +# 2014 August 30
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# Test some properties of the pager_ota_mode and ota_mode pragmas.
           13  +#
           14  +
           15  +if {![info exists testdir]} {
           16  +  set testdir [file join [file dirname [info script]] .. .. test]
           17  +}
           18  +source $testdir/tester.tcl
           19  +set ::testprefix ota5
           20  +
           21  +
           22  +# Run the OTA in file $ota on target database $target until completion.
           23  +#
           24  +proc run_ota {target ota} {
           25  +  sqlite3ota ota $target $ota
           26  +  while { [ota step]=="SQLITE_OK" } {}
           27  +  ota close
           28  +}
           29  +
           30  +
           31  +# Run the OTA in file $ota on target database $target one step at a
           32  +# time until completion.
           33  +#
           34  +proc step_ota {target ota} {
           35  +  while 1 {
           36  +    sqlite3ota ota $target $ota
           37  +    set rc [ota step]
           38  +    ota close
           39  +    if {$rc != "SQLITE_OK"} break
           40  +  }
           41  +  set rc
           42  +}
           43  +
           44  +# Return a list of the primary key columns for table $tbl in the database
           45  +# opened by database handle $db.
           46  +#
           47  +proc pkcols {db tbl} {
           48  +  set ret [list]
           49  +  $db eval "PRAGMA table_info = '$tbl'" {
           50  +    if {$pk} { lappend ret $name }
           51  +  }
           52  +  return $ret
           53  +}
           54  +
           55  +# Return a list of all columns for table $tbl in the database opened by 
           56  +# database handle $db.
           57  +#
           58  +proc allcols {db tbl} {
           59  +  set ret [list]
           60  +  $db eval "PRAGMA table_info = '$tbl'" {
           61  +    lappend ret $name
           62  +  }
           63  +  return $ret
           64  +}
           65  +
           66  +# Return a checksum on all tables and data in the main database attached
           67  +# to database handle $db. It is possible to add indexes without changing
           68  +# the checksum.
           69  +#
           70  +proc datacksum {db} {
           71  +
           72  +  $db eval { SELECT name FROM sqlite_master WHERE type='table' } {
           73  +    append txt $name
           74  +    set cols [list]
           75  +    set order [list]
           76  +    set cnt 0
           77  +    $db eval "PRAGMA table_info = $name" x {
           78  +      lappend cols "quote($x(name))"
           79  +      lappend order [incr cnt]
           80  +    }
           81  +    set cols [join $cols ,]
           82  +    set order [join $order ,]
           83  +    append txt [$db eval "SELECT $cols FROM $name ORDER BY $order"]
           84  +  }
           85  +  return "[string length $txt]-[md5 $txt]"
           86  +}
           87  +
           88  +proc ucontrol {args} {
           89  +  set ret ""
           90  +  foreach a $args {
           91  +    if {$a} {
           92  +      append ret .
           93  +    } else {
           94  +      append ret x
           95  +    }
           96  +  }
           97  +  return $ret
           98  +}
           99  +
          100  +# Argument $target is the name of an SQLite database file. $sql is an SQL
          101  +# script containing INSERT, UPDATE and DELETE statements to execute against
          102  +# it. This command creates an OTA update database in file $ota that has
          103  +# the same effect as the script. The target database is not modified by
          104  +# this command.
          105  +#
          106  +proc generate_ota_db {target ota sql} {
          107  +
          108  +  forcedelete $ota
          109  +  forcecopy $target copy.db
          110  +
          111  +  # Evaluate the SQL script to modify the contents of copy.db.
          112  +  #
          113  +  sqlite3 dbOta copy.db
          114  +  dbOta eval $sql
          115  +
          116  +  dbOta function ucontrol ucontrol
          117  +  
          118  +  # Evaluate the SQL script to modify the contents of copy.db.
          119  +  set ret [datacksum dbOta]
          120  +
          121  +  dbOta eval { ATTACH $ota AS ota }
          122  +  dbOta eval { ATTACH $target AS orig }
          123  +
          124  +  dbOta eval { SELECT name AS tbl FROM sqlite_master WHERE type = 'table' } {
          125  +    set pk [pkcols dbOta $tbl]
          126  +    set cols [allcols dbOta $tbl]
          127  +
          128  +    # A WHERE clause to test that the PK columns match.
          129  +    #
          130  +    set where [list]
          131  +    foreach c $pk { lappend where "main.$tbl.$c IS orig.$tbl.$c" }
          132  +    set where [join $where " AND "]
          133  +    
          134  +    # A WHERE clause to test that all columns match.
          135  +    #
          136  +    set where2 [list]
          137  +    foreach c $cols { lappend where2 "main.$tbl.$c IS orig.$tbl.$c" }
          138  +    set ucontrol "ucontrol([join $where2 ,])"
          139  +    set where2 [join $where2 " AND "]
          140  +
          141  +    # Create a data_xxx table in the OTA update database.
          142  +    dbOta eval "
          143  +      CREATE TABLE ota.data_$tbl AS SELECT *, '' AS ota_control 
          144  +      FROM main.$tbl LIMIT 0
          145  +    "
          146  +
          147  +    # Find all new rows INSERTed by the script.
          148  +    dbOta eval "
          149  +      INSERT INTO ota.data_$tbl 
          150  +          SELECT *, 0 AS ota_control FROM main.$tbl
          151  +          WHERE NOT EXISTS (
          152  +            SELECT 1 FROM orig.$tbl WHERE $where
          153  +          )
          154  +    "
          155  +    
          156  +    # Find all old rows DELETEd by the script.
          157  +    dbOta eval "
          158  +      INSERT INTO ota.data_$tbl 
          159  +          SELECT *, 1 AS ota_control FROM orig.$tbl
          160  +          WHERE NOT EXISTS (
          161  +            SELECT 1 FROM main.$tbl WHERE $where
          162  +          )
          163  +    "
          164  +    
          165  +    # Find all rows UPDATEd by the script.
          166  +    set origcols [list]
          167  +    foreach c $cols { lappend origcols "main.$tbl.$c" }
          168  +    set origcols [join $origcols ,]
          169  +    dbOta eval "
          170  +      INSERT INTO ota.data_$tbl
          171  +          SELECT $origcols, $ucontrol AS ota_control 
          172  +          FROM orig.$tbl, main.$tbl
          173  +          WHERE $where AND NOT ($where2)
          174  +    "
          175  +
          176  +  }
          177  +
          178  +  dbOta close
          179  +  forcedelete copy.db
          180  +
          181  +  return $ret
          182  +}
          183  +
          184  +#-------------------------------------------------------------------------
          185  +#
          186  +do_execsql_test 1.0 {
          187  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
          188  +  CREATE TABLE t2(x, y, z, PRIMARY KEY(y, z)) WITHOUT ROWID;
          189  +
          190  +  INSERT INTO t1 VALUES(1, 2, 3);
          191  +  INSERT INTO t1 VALUES(2, 4, 6);
          192  +  INSERT INTO t1 VALUES(3, 6, 9);
          193  +
          194  +  INSERT INTO t2 VALUES(1, 2, 3);
          195  +  INSERT INTO t2 VALUES(2, 4, 6);
          196  +  INSERT INTO t2 VALUES(3, 6, 9);
          197  +}
          198  +db close
          199  +
          200  +set cksum [generate_ota_db test.db ota.db {
          201  +  INSERT INTO t1 VALUES(4, 8, 12);
          202  +  DELETE FROM t1 WHERE a = 2;
          203  +  UPDATE t1 SET c = 15 WHERE a=3;
          204  +
          205  +  INSERT INTO t2 VALUES(4, 8, 12);
          206  +  DELETE FROM t2 WHERE x = 2;
          207  +  UPDATE t2 SET x = 15 WHERE z=9;
          208  +}]
          209  +
          210  +foreach {tn idx} {
          211  +  1 {
          212  +  }
          213  +  2 {
          214  +    CREATE INDEX i1 ON t1(a, b, c);
          215  +    CREATE INDEX i2 ON t2(x, y, z);
          216  +  }
          217  +} {
          218  +  foreach cmd {run step} {
          219  +    forcecopy test.db test.db2
          220  +    forcecopy ota.db ota.db2
          221  +
          222  +    sqlite3 db test.db2
          223  +    db eval $idx
          224  +
          225  +    do_test 1.$tn.$cmd.1 {
          226  +      ${cmd}_ota test.db2 ota.db2
          227  +      datacksum db
          228  +    } $cksum
          229  +
          230  +    do_test 1.$tn.$cmd.2 {
          231  +      db eval { PRAGMA integrity_check } 
          232  +    } {ok}
          233  +
          234  +    db close
          235  +  }
          236  +}
          237  +
          238  +#-------------------------------------------------------------------------
          239  +#
          240  +reset_db
          241  +do_execsql_test 2.0 {
          242  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d, e);
          243  +  INSERT INTO t1 VALUES(-750250,'fyetckfaagjkzqjx',-185831,X'FEAD',444258.29);
          244  +  INSERT INTO t1 VALUES(649081,NULL,X'7DF25BF78778',-342324.63,'akvspktocwozo');
          245  +  INSERT INTO t1 VALUES(-133045,-44822.31,X'',287935,NULL);
          246  +  INSERT INTO t1 VALUES(202132,NULL,X'5399','cujsjtspryqeyovcdpz','m');
          247  +  INSERT INTO t1 VALUES(302910,NULL,'dvdhivtfkaedzhdcnn',-717113.41,688487);
          248  +  INSERT INTO t1 VALUES(-582327,X'7A267A',X'7E6B3CFE5CB9','zacuzilrok',-196478);
          249  +  INSERT INTO t1 VALUES(-190462,X'D1A087E7D68D9578','lsmleti',NULL,-928094);
          250  +  INSERT INTO t1 VALUES(-467665,176344.57,-536684.23,828876.22,X'903E');
          251  +  INSERT INTO t1 VALUES(-629138,632630.29,X'28D6',-774501,X'819BBBFC65');
          252  +  INSERT INTO t1 VALUES(-828110,-54379.24,-881121.44,X'',X'8D5A894F0D');
          253  +
          254  +  CREATE TABLE t2(a PRIMARY KEY, b, c, d, e) WITHOUT ROWID;
          255  +  INSERT INTO t2 VALUES(-65174,X'AC1DBFFE27310F',-194471.08,347988,X'84041BA6F9BDDE86A8');
          256  +  INSERT INTO t2 VALUES('bzbpi',-952693.69,811628.25,NULL,-817434);
          257  +  INSERT INTO t2 VALUES(-643830,NULL,'n',NULL,'dio');
          258  +  INSERT INTO t2 VALUES('rovoenxxj',NULL,'owupbtdcoxxnvg',-119676,X'55431DFA');
          259  +  INSERT INTO t2 VALUES(899770,'jlygdl',X'DBCA4D1A',NULL,-631773);
          260  +  INSERT INTO t2 VALUES(334698.80,NULL,-697585.58,-89277,-817352);
          261  +  INSERT INTO t2 VALUES(X'1A9EB7547A4AAF38','aiprdhkpzdz','anw','szvjbwdvzucybpwwqjt',X'53');
          262  +  INSERT INTO t2 VALUES(713220,NULL,'hfcqhqzjuqplvkum',X'20B076075649DE','fthgpvqdyy');
          263  +  INSERT INTO t2 VALUES(763908,NULL,'xgslzcpvwfknbr',X'75',X'668146');
          264  +  INSERT INTO t2 VALUES(X'E1BA2B6BA27278','wjbpd',NULL,139341,-290086.15);
          265  +}
          266  +db close
          267  +
          268  +set cksum [generate_ota_db test.db ota.db {
          269  +INSERT INTO t2 VALUES(222916.23,'idh',X'472C517405',X'E3',X'7C4F31824669');
          270  +INSERT INTO t2 VALUES('xcndjwafcoxwxizoktd',-319567.21,NULL,-720906.43,-577170);
          271  +INSERT INTO t2 VALUES(376369.99,-536058,'yoaiurfqupdscwc',X'29EC8A2542EC3953E9',-740485.22);
          272  +INSERT INTO t2 VALUES(X'0EFB4DC50693',-175590.83,X'1779E253CAB5B1789E',X'BC6903',NULL);
          273  +INSERT INTO t2 VALUES(-288299,'hfrp',NULL,528477,730676.77);
          274  +DELETE FROM t2 WHERE a < -60000;
          275  +
          276  +UPDATE t2 SET b = 'pgnnaaoflnw' WHERE a = 'bzbpi';
          277  +UPDATE t2 SET c = -675583 WHERE a = 'rovoenxxj';
          278  +UPDATE t2 SET d = X'09CDF2B2C241' WHERE a = 713220;
          279  +
          280  +INSERT INTO t1 VALUES(224938,'bmruycvfznhhnfmgqys','fr',854381,789143);
          281  +INSERT INTO t1 VALUES(-863931,-1386.26,X'2A058540C2FB5C',NULL,X'F9D5990A');
          282  +INSERT INTO t1 VALUES(673696,X'97301F0AC5735F44B5',X'440C',227999.92,-709599.79);
          283  +INSERT INTO t1 VALUES(-243640,NULL,-71718.11,X'1EEFEB38',X'8CC7C55D95E142FBA5');
          284  +INSERT INTO t1 VALUES(275893,X'',375606.30,X'0AF9EC334711FB',-468194);
          285  +DELETE FROM t1 WHERE a > 200000;
          286  +
          287  +UPDATE t1 SET b = 'pgnnaaoflnw' WHERE a = -190462;
          288  +UPDATE t1 SET c = -675583 WHERE a = -467665;
          289  +UPDATE t1 SET d = X'09CDF2B2C241' WHERE a = -133045;
          290  +
          291  +}]
          292  +
          293  +foreach {tn idx} {
          294  +  1 {
          295  +  }
          296  +  2 {
          297  +    CREATE UNIQUE INDEX i1 ON t1(b, c, d);
          298  +    CREATE UNIQUE INDEX i2 ON t1(d, e, a);
          299  +    CREATE UNIQUE INDEX i3 ON t1(e, d, c, b);
          300  +
          301  +    CREATE UNIQUE INDEX i4 ON t2(b, c, d);
          302  +    CREATE UNIQUE INDEX i5 ON t2(d, e, a);
          303  +    CREATE UNIQUE INDEX i6 ON t2(e, d, c, b);
          304  +  }
          305  +} {
          306  +  foreach cmd {run step} {
          307  +    forcecopy test.db test.db2
          308  +    forcecopy ota.db ota.db2
          309  +
          310  +    sqlite3 db test.db2
          311  +    db eval $idx
          312  +
          313  +    do_test 2.$tn.$cmd.1 {
          314  +      ${cmd}_ota test.db2 ota.db2
          315  +      datacksum db
          316  +    } $cksum
          317  +
          318  +    do_test 2.$tn.$cmd.2 {
          319  +      db eval { PRAGMA integrity_check } 
          320  +    } {ok}
          321  +
          322  +    db close
          323  +  }
          324  +}
          325  +
          326  +
          327  +finish_test
          328  +
          329  +
          330  +
          331  +

Added ext/ota/ota6.test.

            1  +# 2014 October 21
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This file contains tests for the OTA module. Specifically, it tests the
           13  +# outcome of some other client writing to the database while an OTA update
           14  +# is being applied.
           15  +
           16  +if {![info exists testdir]} {
           17  +  set testdir [file join [file dirname [info script]] .. .. test]
           18  +}
           19  +source $testdir/tester.tcl
           20  +set ::testprefix ota6
           21  +
           22  +proc setup_test {} {
           23  +  reset_db
           24  +  execsql {
           25  +    CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE);
           26  +    CREATE TABLE t2(a INTEGER PRIMARY KEY, b UNIQUE);
           27  +    CREATE TABLE t3(a INTEGER PRIMARY KEY, b UNIQUE);
           28  +  }
           29  +  db close
           30  +
           31  +  forcedelete ota.db
           32  +  sqlite3 ota ota.db
           33  +  ota eval {
           34  +    CREATE TABLE data_t1(a, b, ota_control);
           35  +    CREATE TABLE data_t2(a, b, ota_control);
           36  +    CREATE TABLE data_t3(a, b, ota_control);
           37  +    INSERT INTO data_t1 VALUES(1, 't1', 0);
           38  +    INSERT INTO data_t2 VALUES(2, 't2', 0);
           39  +    INSERT INTO data_t3 VALUES(3, 't3', 0);
           40  +  }
           41  +  ota close
           42  +}
           43  +
           44  +# Test the outcome of some other client writing the db while the *-oal 
           45  +# file is being generated. Once this has happened, the update cannot be
           46  +# progressed.
           47  +#
           48  +for {set nStep 1} {$nStep < 8} {incr nStep} {
           49  +  do_test 1.$nStep.1 {
           50  +    setup_test
           51  +    sqlite3ota ota test.db ota.db
           52  +    for {set i 0} {$i<$nStep} {incr i} {ota step}
           53  +
           54  +    ota close
           55  +    sqlite3 db test.db
           56  +    execsql { INSERT INTO t1 VALUES(5, 'hello') }
           57  +    sqlite3ota ota test.db ota.db
           58  +    ota step
           59  +  } {SQLITE_BUSY}
           60  +  do_test 1.$nStep.2 {
           61  +    ota step
           62  +  } {SQLITE_BUSY}
           63  +  do_test 1.$nStep.3 {
           64  +    list [file exists test.db-oal] [file exists test.db-wal]
           65  +  } {1 0}
           66  +  do_test 1.$nStep.4 {
           67  +    list [catch { ota close } msg] $msg
           68  +  } {1 {SQLITE_BUSY - database modified during ota update}}
           69  +}
           70  +
           71  +# Test the outcome of some other client writing the db after the *-oal
           72  +# file has been copied to the *-wal path. Once this has happened, any
           73  +# other client writing to the db causes OTA to consider its job finished.
           74  +#
           75  +for {set nStep 8} {$nStep < 20} {incr nStep} {
           76  +  do_test 1.$nStep.1 {
           77  +    setup_test
           78  +    sqlite3ota ota test.db ota.db
           79  +    for {set i 0} {$i<$nStep} {incr i} {ota step}
           80  +    ota close
           81  +    sqlite3 db test.db
           82  +    execsql { INSERT INTO t1 VALUES(5, 'hello') }
           83  +    sqlite3ota ota test.db ota.db
           84  +    ota step
           85  +  } {SQLITE_DONE}
           86  +  do_test 1.$nStep.2 {
           87  +    ota step
           88  +  } {SQLITE_DONE}
           89  +  do_test 1.$nStep.3 {
           90  +    file exists test.db-oal
           91  +  } {0}
           92  +  do_test 1.$nStep.4 {
           93  +    list [catch { ota close } msg] $msg
           94  +  } {0 SQLITE_DONE}
           95  +
           96  +  do_execsql_test 1.$nStep.5 {
           97  +    SELECT * FROM t1;
           98  +  } {1 t1 5 hello}
           99  +}
          100  +
          101  +
          102  +finish_test
          103  +

Added ext/ota/ota7.test.

            1  +# 2014 October 21
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This file contains tests for the OTA module.
           13  +#
           14  +
           15  +
           16  +if {![info exists testdir]} {
           17  +  set testdir [file join [file dirname [info script]] .. .. test]
           18  +}
           19  +source $testdir/tester.tcl
           20  +set ::testprefix ota7
           21  +
           22  +# Test index:
           23  +#
           24  +#   1.*: That affinities are correctly applied to values within the 
           25  +#        OTA database.
           26  +#
           27  +#   2.*: Tests for multi-column primary keys.
           28  +#
           29  +
           30  +do_test 1.0 {
           31  +  execsql {
           32  +    CREATE TABLE t1(a INT PRIMARY KEY, b) WITHOUT ROWID;
           33  +    INSERT INTO t1 VALUES(1, 'abc');
           34  +    INSERT INTO t1 VALUES(2, 'def');
           35  +  }
           36  +
           37  +  forcedelete ota.db
           38  +  sqlite3 ota ota.db
           39  +  ota eval {
           40  +    CREATE TABLE data_t1(a, b, ota_control);
           41  +    INSERT INTO data_t1 VALUES('1', NULL, 1);
           42  +  }
           43  +  ota close
           44  +} {}
           45  +
           46  +do_test 1.1 {
           47  +  sqlite3ota ota test.db ota.db
           48  +  while { [ota step]=="SQLITE_OK" } {}
           49  +  ota close
           50  +} {SQLITE_DONE}
           51  +
           52  +sqlite3 db test.db
           53  +do_execsql_test 1.2 {
           54  +  SELECT * FROM t1
           55  +} {2 def}
           56  +
           57  +#-------------------------------------------------------------------------
           58  +#
           59  +foreach {tn tbl} {
           60  +  1 { CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b)) WITHOUT ROWID }
           61  +  2 { CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b)) }
           62  +} {
           63  +  reset_db
           64  +
           65  +  execsql $tbl
           66  +  do_execsql_test 2.$tn.1 {
           67  +    CREATE INDEX t1c ON t1(c);
           68  +    INSERT INTO t1 VALUES(1, 1, 'a');
           69  +    INSERT INTO t1 VALUES(1, 2, 'b');
           70  +    INSERT INTO t1 VALUES(2, 1, 'c');
           71  +    INSERT INTO t1 VALUES(2, 2, 'd');
           72  +  }
           73  +
           74  +  do_test 2.$tn.2 {
           75  +    forcedelete ota.db
           76  +    sqlite3 ota ota.db
           77  +    execsql {
           78  +      CREATE TABLE data_t1(a, b, c, ota_control);
           79  +      INSERT INTO data_t1 VALUES(3, 1, 'e', 0);
           80  +      INSERT INTO data_t1 VALUES(3, 2, 'f', 0);
           81  +      INSERT INTO data_t1 VALUES(1, 2, NULL, 1);
           82  +      INSERT INTO data_t1 VALUES(2, 1, 'X', '..x');
           83  +    } ota
           84  +    ota close
           85  +  } {}
           86  +
           87  +  do_test 2.$tn.3 {
           88  +    set rc "SQLITE_OK"
           89  +    while {$rc == "SQLITE_OK"} {
           90  +      sqlite3ota ota test.db ota.db
           91  +      ota step
           92  +      set rc [ota close]
           93  +    } 
           94  +    set rc
           95  +  } {SQLITE_DONE}
           96  +
           97  +  do_execsql_test 2.$tn.1 {
           98  +    SELECT * FROM t1 ORDER BY a, b
           99  +  } {
          100  +    1 1 a
          101  +    2 1 X
          102  +    2 2 d
          103  +    3 1 e
          104  +    3 2 f
          105  +  }
          106  +}
          107  +
          108  +finish_test
          109  +
          110  +

Added ext/ota/ota8.test.

            1  +# 2014 November 20
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# Test the ota_delta() feature.
           13  +#
           14  +
           15  +if {![info exists testdir]} {
           16  +  set testdir [file join [file dirname [info script]] .. .. test]
           17  +}
           18  +source $testdir/tester.tcl
           19  +set ::testprefix ota8
           20  +
           21  +do_execsql_test 1.0 {
           22  +  CREATE TABLE t1(x, y PRIMARY KEY, z);
           23  +  INSERT INTO t1 VALUES(NULL, 1, 'one');
           24  +  INSERT INTO t1 VALUES(NULL, 2, 'two');
           25  +  INSERT INTO t1 VALUES(NULL, 3, 'three');
           26  +  CREATE INDEX i1z ON t1(z, x);
           27  +}
           28  +
           29  +do_test 1.1 {
           30  +  forcedelete ota.db
           31  +  sqlite3 db2 ota.db
           32  +  db2 eval {
           33  +    CREATE TABLE data_t1(x, y, z, ota_control);
           34  +    INSERT INTO data_t1 VALUES('a',    1, '_i'      , 'x.d');
           35  +    INSERT INTO data_t1 VALUES('b',    2, 2         , '..x');
           36  +    INSERT INTO data_t1 VALUES('_iii', 3, '-III'    , 'd.d');
           37  +  }
           38  +  db2 close
           39  +} {}
           40  +
           41  +do_test 1.2.1 {
           42  +  sqlite3ota ota test.db ota.db
           43  +  ota step
           44  +} {SQLITE_ERROR}
           45  +do_test 1.2.2 {
           46  +  list [catch {ota close} msg] $msg
           47  +} {1 {SQLITE_ERROR - no such function: ota_delta}}
           48  +
           49  +proc ota_delta {orig new} {
           50  + return "${orig}${new}"
           51  +}
           52  +
           53  +do_test 1.3.1 {
           54  +  while 1 {
           55  +    sqlite3ota ota test.db ota.db
           56  +    ota create_ota_delta
           57  +    set rc [ota step]
           58  +    if {$rc != "SQLITE_OK"} break
           59  +    ota close
           60  +  }
           61  +  ota close
           62  +} {SQLITE_DONE}
           63  +
           64  +do_execsql_test 1.3.2 {
           65  +  SELECT * FROM t1
           66  +} {
           67  +  a    1 one_i
           68  +  {}   2 2
           69  +  _iii 3 three-III
           70  +}
           71  +integrity_check 1.3.3
           72  +
           73  +
           74  +finish_test
           75  +

Added ext/ota/ota9.test.

            1  +# 2014 November 21
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# Test OTA with virtual tables. And tables with no PRIMARY KEY declarations.
           13  +#
           14  +
           15  +if {![info exists testdir]} {
           16  +  set testdir [file join [file dirname [info script]] .. .. test]
           17  +}
           18  +source $testdir/tester.tcl
           19  +set ::testprefix ota9
           20  +
           21  +ifcapable !fts3 {
           22  +  finish_test
           23  +  return
           24  +}
           25  +
           26  +do_execsql_test 1.1 {
           27  +  CREATE VIRTUAL TABLE f1 USING fts4(a, b, c);
           28  +  INSERT INTO f1(rowid, a, b, c) VALUES(11, 'a', 'b', 'c');
           29  +  INSERT INTO f1(rowid, a, b, c) VALUES(12, 'd', 'e', 'f');
           30  +  INSERT INTO f1(rowid, a, b, c) VALUES(13, 'g', 'h', 'i');
           31  +}
           32  +
           33  +do_test 1.1 {
           34  +  forcedelete ota.db
           35  +  sqlite3 db2 ota.db
           36  +  db2 eval {
           37  +    CREATE TABLE data_f1(ota_rowid, a, b, c, ota_control);
           38  +    INSERT INTO data_f1 VALUES(14, 'x', 'y', 'z', 0);         -- INSERT
           39  +    INSERT INTO data_f1 VALUES(11, NULL, NULL, NULL, 1);      -- DELETE
           40  +    INSERT INTO data_f1 VALUES(13, NULL, NULL, 'X', '..x');   -- UPDATE
           41  +  }
           42  +  db2 close
           43  +} {}
           44  +
           45  +do_test 1.2.1 {
           46  +  while 1 {
           47  +    sqlite3ota ota test.db ota.db
           48  +    set rc [ota step]
           49  +    if {$rc != "SQLITE_OK"} break
           50  +    ota close
           51  +  }
           52  +  ota close
           53  +} {SQLITE_DONE}
           54  +
           55  +do_execsql_test 1.2.2 { SELECT rowid, * FROM f1 } { 
           56  +  12 d e f
           57  +  13 g h X
           58  +  14 x y z
           59  +}
           60  +do_execsql_test 1.2.3 { INSERT INTO f1(f1) VALUES('integrity-check') }
           61  +integrity_check 1.2.4
           62  +
           63  +#-------------------------------------------------------------------------
           64  +# Tables with no PK declaration.
           65  +#
           66  +
           67  +# Run the OTA in file $ota on target database $target until completion.
           68  +#
           69  +proc run_ota {target ota} {
           70  +  sqlite3ota ota $target $ota
           71  +  while { [ota step]=="SQLITE_OK" } {}
           72  +  ota close
           73  +}
           74  +
           75  +foreach {tn idx} {
           76  +  1 { }
           77  +  2 { 
           78  +    CREATE INDEX i1 ON t1(a);
           79  +  }
           80  +  3 { 
           81  +    CREATE INDEX i1 ON t1(b, c);
           82  +    CREATE INDEX i2 ON t1(c, b);
           83  +    CREATE INDEX i3 ON t1(a, a, a, b, b, b, c, c, c);
           84  +  }
           85  +} {
           86  +
           87  +  reset_db
           88  +  do_execsql_test 2.$tn.1 {
           89  +    CREATE TABLE t1(a, b, c);
           90  +    INSERT INTO t1 VALUES(1, 2, 3);
           91  +    INSERT INTO t1 VALUES(4, 5, 6);
           92  +    INSERT INTO t1(rowid, a, b, c) VALUES(-1, 'a', 'b', 'c');
           93  +    INSERT INTO t1(rowid, a, b, c) VALUES(-2, 'd', 'e', 'f');
           94  +  }
           95  +
           96  +  db eval $idx
           97  +  
           98  +  do_test 2.$tn.2 {
           99  +    forcedelete ota.db
          100  +    sqlite3 db2 ota.db
          101  +    db2 eval {
          102  +      CREATE TABLE data_t1(ota_rowid, a, b, c, ota_control);
          103  +      INSERT INTO data_t1 VALUES(3, 'x', 'y', 'z', 0);
          104  +      INSERT INTO data_t1 VALUES(NULL, 'X', 'Y', 'Z', 0);
          105  +      INSERT INTO data_t1 VALUES('1', NULL, NULL, NULL, 1);
          106  +      INSERT INTO data_t1 VALUES(-2, NULL, NULL, 'fff', '..x');
          107  +    }
          108  +    db2 close
          109  +  } {}
          110  +  
          111  +  run_ota test.db ota.db
          112  +  
          113  +  do_execsql_test 2.$tn.3 {
          114  +    SELECT rowid, a, b, c FROM t1 ORDER BY rowid;
          115  +  } {
          116  +    -2 d e fff
          117  +    -1 a b c
          118  +     2 4 5 6
          119  +     3 x y z
          120  +     4 X Y Z
          121  +  }
          122  +  
          123  +  integrity_check 2.$tn.4
          124  +}
          125  +
          126  +
          127  +finish_test
          128  +

Added ext/ota/otaA.test.

            1  +# 2014 August 30
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This file contains tests for the OTA module. More specifically, it
           13  +# contains tests to ensure that it is an error to attempt to update
           14  +# a wal mode database via OTA.
           15  +#
           16  +
           17  +if {![info exists testdir]} {
           18  +  set testdir [file join [file dirname [info script]] .. .. test]
           19  +}
           20  +source $testdir/tester.tcl
           21  +set ::testprefix otaA
           22  +
           23  +set db_sql {
           24  +  CREATE TABLE t1(a PRIMARY KEY, b, c);
           25  +}
           26  +set ota_sql {
           27  +  CREATE TABLE data_t1(a, b, c, ota_control);
           28  +  INSERT INTO data_t1 VALUES(1, 2, 3, 0);
           29  +  INSERT INTO data_t1 VALUES(4, 5, 6, 0);
           30  +  INSERT INTO data_t1 VALUES(7, 8, 9, 0);
           31  +}
           32  +
           33  +do_test 1.0 {
           34  +  db close
           35  +  forcedelete test.db ota.db
           36  +
           37  +  sqlite3 db test.db
           38  +  db eval $db_sql
           39  +  db eval { PRAGMA journal_mode = wal }
           40  +  db close
           41  +
           42  +  sqlite3 db ota.db
           43  +  db eval $ota_sql
           44  +  db close
           45  +
           46  +  sqlite3ota ota test.db ota.db
           47  +  ota step
           48  +} {SQLITE_ERROR}
           49  +do_test 1.1 {
           50  +  list [catch { ota close } msg] $msg
           51  +} {1 {SQLITE_ERROR - cannot update wal mode database}}
           52  +
           53  +do_test 2.0 {
           54  +  forcedelete test.db ota.db
           55  +
           56  +  sqlite3 db test.db
           57  +  db eval $db_sql
           58  +  db close
           59  +
           60  +  sqlite3 db ota.db
           61  +  db eval $ota_sql
           62  +  db close
           63  +
           64  +  sqlite3ota ota test.db ota.db
           65  +  ota step
           66  +  ota close
           67  +} {SQLITE_OK}
           68  +
           69  +do_test 2.1 {
           70  +  sqlite3 db test.db
           71  +  db eval {PRAGMA journal_mode = wal}
           72  +  db close
           73  +  breakpoint
           74  +  sqlite3ota ota test.db ota.db
           75  +  ota step
           76  +} {SQLITE_ERROR}
           77  +
           78  +do_test 2.2 {
           79  +  list [catch { ota close } msg] $msg
           80  +} {1 {SQLITE_ERROR - cannot update wal mode database}}
           81  +
           82  +
           83  +finish_test
           84  +

Added ext/ota/otacrash.test.

            1  +# 2014 October 22
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +if {![info exists testdir]} {
           14  +  set testdir [file join [file dirname [info script]] .. .. test]
           15  +}
           16  +source $testdir/tester.tcl
           17  +set ::testprefix otacrash
           18  +
           19  +db close
           20  +forcedelete test.db-oal ota.db
           21  +sqlite3_shutdown
           22  +sqlite3_config_uri 1
           23  +reset_db
           24  +
           25  +# Set up a target database and an ota update database. The target
           26  +# db is the usual "test.db", the ota db is "test.db2".
           27  +#
           28  +forcedelete test.db2
           29  +do_execsql_test 1.0 {
           30  +  CREATE TABLE t1(a, b, c, PRIMARY KEY(a), UNIQUE(b));
           31  +  INSERT INTO t1 VALUES(1, 2, 3);
           32  +  INSERT INTO t1 VALUES(4, 5, 6);
           33  +  INSERT INTO t1 VALUES(7, 8, 9);
           34  +
           35  +  ATTACH 'test.db2' AS ota;
           36  +  CREATE TABLE ota.data_t1(a, b, c, ota_control);
           37  +  INSERT INTO data_t1 VALUES(10, 11, 12, 0);
           38  +  INSERT INTO data_t1 VALUES(13, 14, 15, 0);
           39  +  INSERT INTO data_t1 VALUES(4, NULL, NULL, 1);
           40  +  INSERT INTO data_t1 VALUES(1, NULL, 100, '..x');
           41  +}
           42  +db_save_and_close
           43  +
           44  +
           45  +# Determine the number of steps in applying the ota update to the test
           46  +# target database created above. Set $::ota_num_steps accordingly
           47  +#
           48  +# Check that the same number of steps are required to apply the ota
           49  +# update using many calls to sqlite3ota_step() on a single ota handle
           50  +# as required to apply it using a series of ota handles, on each of 
           51  +# which sqlite3ota_step() is called once.
           52  +#
           53  +do_test 1.1 {
           54  +  db_restore
           55  +  sqlite3ota ota test.db test.db2
           56  +  breakpoint
           57  +  set nStep 0
           58  +  while {[ota step]=="SQLITE_OK"} { incr nStep }
           59  +  ota close
           60  +} {SQLITE_DONE}
           61  +set ota_num_steps $nStep
           62  +do_test 1.2 {
           63  +  db_restore
           64  +  set nStep 0
           65  +  while {1} {
           66  +    sqlite3ota ota test.db test.db2
           67  +    ota step
           68  +    if {[ota close]=="SQLITE_DONE"} break
           69  +    incr nStep
           70  +  }
           71  +  set nStep
           72  +} $ota_num_steps
           73  +
           74  +
           75  +# Run one or more tests using the target (test.db) and ota (test.db2)
           76  +# databases created above. As follows:
           77  +#
           78  +#   1. This process starts the ota update and calls sqlite3ota_step()
           79  +#      $nPre times. Then closes the ota update handle.
           80  +#
           81  +#   2. A second process resumes the ota update and attempts to call 
           82  +#      sqlite3ota_step() $nStep times before closing the handle. A
           83  +#      crash is simulated during each xSync() of file test.db2.
           84  +#
           85  +#   3. This process attempts to resume the ota update from whatever
           86  +#      state it was left in by step (2). Test that it is successful
           87  +#      in doing so and that the final target database is as expected.
           88  +#
           89  +# In total (nSync+1) tests are run, where nSync is the number of times
           90  +# xSync() is called on test.db2.
           91  +#
           92  +proc do_ota_crash_test {tn nPre nStep} {
           93  +
           94  +  set script [subst -nocommands {
           95  +    sqlite3ota ota test.db file:test.db2?vfs=crash
           96  +    set i 0
           97  +    while {[set i] < $nStep} {
           98  +      if {[ota step]!="SQLITE_OK"} break
           99  +      incr i
          100  +    }
          101  +    ota close
          102  +  }]
          103  +
          104  +  set bDone 0
          105  +  for {set iDelay 1} {$bDone==0} {incr iDelay} {
          106  +    forcedelete test.db2 test.db2-journal test.db test.db-oal test.db-wal
          107  +    db_restore
          108  +
          109  +    if {$nPre>0} {
          110  +      sqlite3ota ota test.db file:test.db2
          111  +      set i 0
          112  +      for {set i 0} {$i < $nPre} {incr i} { 
          113  +        if {[ota step]!="SQLITE_OK"} break
          114  +      }
          115  +      ota close
          116  +    }
          117  +
          118  +    set res [
          119  +      crashsql -file test.db2 -delay $iDelay -tclbody $script -opendb {} {}
          120  +    ]
          121  +
          122  +    set bDone 1
          123  +    if {$res == "1 {child process exited abnormally}"} {
          124  +      set bDone 0
          125  +    } elseif {$res != "0 {}"} {
          126  +      error "unexected catchsql result: $res"
          127  +    }
          128  +
          129  +    sqlite3ota ota test.db test.db2
          130  +    while {[ota step]=="SQLITE_OK"} {}
          131  +    ota close
          132  +
          133  +    sqlite3 db test.db
          134  +    do_execsql_test $tn.delay=$iDelay {
          135  +      SELECT * FROM t1;
          136  +      PRAGMA integrity_check;
          137  +    } {1 2 100  7 8 9  10 11 12  13 14 15  ok}
          138  +    db close
          139  +  }
          140  +}
          141  +
          142  +for {set nPre 0} {$nPre < $ota_num_steps} {incr nPre} {
          143  +  for {set is 1} {$is <= ($ota_num_steps - $nPre)} {incr is} {
          144  +    do_ota_crash_test 2.pre=$nPre.step=$is $nPre $is
          145  +  }
          146  +}
          147  +
          148  +finish_test
          149  +

Added ext/ota/otafault.test.

            1  +# 2014 October 22
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +if {![info exists testdir]} {
           14  +  set testdir [file join [file dirname [info script]] .. .. test]
           15  +}
           16  +source $testdir/tester.tcl
           17  +source $testdir/malloc_common.tcl
           18  +set ::testprefix otafault
           19  +
           20  +proc copy_if_exists {src target} {
           21  +  if {[file exists $src]} {
           22  +    forcecopy $src $target
           23  +  } else {
           24  +    forcedelete $target
           25  +  }
           26  +}
           27  +
           28  +foreach {tn2 setup sql expect} {
           29  +  1 {
           30  +    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
           31  +    CREATE INDEX t1cb ON t1(c, b);
           32  +    INSERT INTO t1 VALUES(1, 1, 1);
           33  +    INSERT INTO t1 VALUES(2, 2, 2);
           34  +    INSERT INTO t1 VALUES(3, 3, 3);
           35  +
           36  +    CREATE TABLE ota.data_t1(a, b, c, ota_control);
           37  +    INSERT INTO data_t1 VALUES(2, NULL, NULL, 1);
           38  +    INSERT INTO data_t1 VALUES(3, 'three', NULL, '.x.');
           39  +    INSERT INTO data_t1 VALUES(4, 4, 4, 0);
           40  +  } {
           41  +    SELECT * FROM t1
           42  +  } {1 1 1   3 three 3   4 4 4}
           43  +
           44  +  2 {
           45  +    CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID;
           46  +    CREATE INDEX t2cb ON t2(c, b);
           47  +    INSERT INTO t2 VALUES('a', 'a', 'a');
           48  +    INSERT INTO t2 VALUES('b', 'b', 'b');
           49  +    INSERT INTO t2 VALUES('c', 'c', 'c');
           50  +
           51  +    CREATE TABLE ota.data_t2(a, b, c, ota_control);
           52  +    INSERT INTO data_t2 VALUES('b', NULL, NULL, 1);
           53  +    INSERT INTO data_t2 VALUES('c', 'see', NULL, '.x.');
           54  +    INSERT INTO data_t2 VALUES('d', 'd', 'd', 0);
           55  +  } {
           56  +    SELECT * FROM t2
           57  +  } {a a a   c see c     d d d}
           58  +
           59  +  3 {
           60  +    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
           61  +    CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID;
           62  +    CREATE INDEX t1cb ON t1(c, b);
           63  +    CREATE INDEX t2cb ON t2(c, b);
           64  +
           65  +    CREATE TABLE ota.data_t1(a, b, c, ota_control);
           66  +    CREATE TABLE ota.data_t2(a, b, c, ota_control);
           67  +    INSERT INTO data_t1 VALUES(1, 2, 3, 0);
           68  +    INSERT INTO data_t2 VALUES(4, 5, 6, 0);
           69  +  } {
           70  +    SELECT * FROM t1 UNION ALL SELECT * FROM t2
           71  +  } {1 2 3 4 5 6}
           72  +
           73  +  4 {
           74  +    CREATE TABLE t1(a PRIMARY KEY, b, c);
           75  +    CREATE INDEX t1c ON t1(c);
           76  +    INSERT INTO t1 VALUES('A', 'B', 'C');
           77  +    INSERT INTO t1 VALUES('D', 'E', 'F');
           78  +
           79  +    CREATE TABLE ota.data_t1(a, b, c, ota_control);
           80  +    INSERT INTO data_t1 VALUES('D', NULL, NULL, 1);
           81  +    INSERT INTO data_t1 VALUES('A', 'Z', NULL, '.x.');
           82  +    INSERT INTO data_t1 VALUES('G', 'H', 'I', 0);
           83  +  } {
           84  +    SELECT * FROM t1 ORDER BY a;
           85  +  } {A Z C G H I}
           86  +
           87  +  5 {
           88  +    CREATE TABLE t1(a, b, c);
           89  +    CREATE INDEX t1c ON t1(c, b);
           90  +
           91  +    CREATE TABLE ota.data_t1(a, b, c, ota_rowid, ota_control);
           92  +    INSERT INTO data_t1 VALUES('a', 'b', 'c', 1, 0);
           93  +    INSERT INTO data_t1 VALUES('d', 'e', 'f', '2', 0);
           94  +  } {
           95  +    SELECT * FROM t1 ORDER BY a;
           96  +  } {a b c d e f}
           97  +
           98  +} {
           99  +  catch {db close}
          100  +  forcedelete ota.db test.db
          101  +  sqlite3 db test.db
          102  +  execsql {
          103  +    PRAGMA encoding = utf16;
          104  +    ATTACH 'ota.db' AS ota;
          105  +  }
          106  +  execsql $setup
          107  +  db close
          108  +
          109  +  forcecopy test.db test.db.bak
          110  +  forcecopy ota.db ota.db.bak
          111  +
          112  +  foreach {tn f reslist} {
          113  +    1 oom-tra*  {
          114  +      {0 SQLITE_DONE} 
          115  +      {1 {SQLITE_NOMEM - out of memory}} 
          116  +      {1 SQLITE_NOMEM} 
          117  +      {1 SQLITE_IOERR_NOMEM} 
          118  +      {1 {SQLITE_NOMEM - unable to open a temporary database file for storing temporary tables}}
          119  +    }
          120  +  
          121  +    2 ioerr-*  {
          122  +      {0 SQLITE_DONE} 
          123  +      {1 {SQLITE_IOERR - disk I/O error}}
          124  +      {1 SQLITE_IOERR}
          125  +      {1 SQLITE_IOERR_WRITE}
          126  +      {1 SQLITE_IOERR_READ}
          127  +      {1 SQLITE_IOERR_FSYNC}
          128  +      {1 {SQLITE_ERROR - SQL logic error or missing database}}
          129  +      {1 {SQLITE_ERROR - unable to open database: ota.db}}
          130  +      {1 {SQLITE_IOERR - unable to open database: ota.db}}
          131  +    }
          132  +
          133  +    3 shmerr-*  {
          134  +      {0 SQLITE_DONE} 
          135  +      {1 {SQLITE_IOERR - disk I/O error}}
          136  +      {1 SQLITE_IOERR}
          137  +    }
          138  +  } {
          139  +
          140  +    catch {db close}
          141  +    sqlite3_shutdown
          142  +    set lookaside_config [sqlite3_config_lookaside 0 0]
          143  +    sqlite3_initialize
          144  +    autoinstall_test_functions
          145  +
          146  +    do_faultsim_test 2.$tn2 -faults $::f -prep {
          147  +      catch { db close }
          148  +      forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal
          149  +      forcecopy test.db.bak test.db
          150  +      forcecopy ota.db.bak  ota.db
          151  +    } -body {
          152  +      sqlite3ota ota test.db ota.db
          153  +      while {[ota step]=="SQLITE_OK"} {}
          154  +      ota close
          155  +    } -test {
          156  +      faultsim_test_result {*}$::reslist
          157  +      if {$testrc==0} {
          158  +        sqlite3 db test.db
          159  +        faultsim_integrity_check
          160  +        set res [db eval $::sql]
          161  +        if {$res != [list {*}$::expect]} {
          162  +          puts ""
          163  +          puts "res: $res"
          164  +          puts "exp: $expect"
          165  +          error "data not as expected!"
          166  +        }
          167  +      }
          168  +    }
          169  +
          170  +    catch {db close}
          171  +    sqlite3_shutdown
          172  +    sqlite3_config_lookaside {*}$lookaside_config
          173  +    sqlite3_initialize
          174  +    autoinstall_test_functions
          175  +
          176  +
          177  +    for {set iStep 0} {$iStep<=21} {incr iStep} {
          178  +    
          179  +      forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal
          180  +    
          181  +      copy_if_exists test.db.bak test.db
          182  +      copy_if_exists ota.db.bak ota.db
          183  +    
          184  +      sqlite3ota ota test.db ota.db
          185  +      for {set x 0} {$x < $::iStep} {incr x} { ota step }
          186  +      ota close
          187  +  
          188  +# sqlite3 x ota.db ; puts "XYZ [x eval { SELECT * FROM ota_state } ]" ; x close
          189  +    
          190  +      copy_if_exists test.db     test.db.bak.2
          191  +      copy_if_exists test.db-wal test.db.bak.2-wal
          192  +      copy_if_exists test.db-oal test.db.bak.2-oal
          193  +      copy_if_exists ota.db      ota.db.bak.2
          194  +    
          195  +      do_faultsim_test 3.$tn.$iStep -faults $::f -prep {
          196  +        catch { db close }
          197  +        forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal
          198  +        copy_if_exists test.db.bak.2 test.db
          199  +        copy_if_exists test.db.bak.2-wal test.db-wal
          200  +        copy_if_exists test.db.bak.2-oal test.db-oal
          201  +        copy_if_exists ota.db.bak.2  ota.db
          202  +      } -body {
          203  +        sqlite3ota ota test.db ota.db
          204  +        ota step
          205  +        ota close
          206  +      } -test {
          207  +
          208  +        if {$testresult=="SQLITE_OK"} {set testresult "SQLITE_DONE"}
          209  +        faultsim_test_result {*}$::reslist
          210  +      
          211  +        if {$testrc==0} {
          212  +          # No error occurred. If the OTA has not already been fully applied,
          213  +          # apply the rest of it now. Then ensure that the final state of the
          214  +          # target db is as expected. And that "PRAGMA integrity_check"
          215  +          # passes.
          216  +          sqlite3ota ota test.db ota.db
          217  +          while {[ota step] == "SQLITE_OK"} {}
          218  +          ota close
          219  +
          220  +          sqlite3 db test.db
          221  +          faultsim_integrity_check
          222  +
          223  +          set res [db eval $::sql]
          224  +          if {$res != [list {*}$::expect]} {
          225  +            puts ""
          226  +            puts "res: $res"
          227  +            puts "exp: $::expect"
          228  +            error "data not as expected!"
          229  +          }
          230  +        }
          231  +      }
          232  +    }
          233  +  }
          234  +}
          235  +
          236  +finish_test
          237  +

Added ext/ota/otafault2.test.

            1  +# 2014 October 22
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +if {![info exists testdir]} {
           14  +  set testdir [file join [file dirname [info script]] .. .. test]
           15  +}
           16  +source $testdir/tester.tcl
           17  +source $testdir/malloc_common.tcl
           18  +set ::testprefix otafault2
           19  +
           20  +forcedelete ota.db
           21  +do_execsql_test 1.0 {
           22  +  CREATE TABLE target(x UNIQUE, y, z, PRIMARY KEY(y));
           23  +  INSERT INTO target VALUES(1, 2, 3);
           24  +  INSERT INTO target VALUES(4, 5, 6);
           25  +
           26  +  ATTACH 'ota.db' AS ota;
           27  +  CREATE TABLE ota.data_target(x, y, z, ota_control);
           28  +  INSERT INTO data_target VALUES(7, 8, 9, 0);
           29  +  INSERT INTO data_target VALUES(1, 11, 12, 0);
           30  +  DETACH ota;
           31  +}
           32  +db close
           33  +
           34  +forcecopy test.db test.db-bak 
           35  +forcecopy ota.db ota.db-bak 
           36  +
           37  +do_faultsim_test 1 -faults oom* -prep {
           38  +  forcecopy test.db-bak test.db
           39  +  forcecopy ota.db-bak ota.db
           40  +  forcedelete test.db-oal test.db-wal ota.db-journal
           41  +  sqlite3ota ota test.db ota.db
           42  +} -body {
           43  +  while {[ota step]=="SQLITE_OK"} { }
           44  +  ota close
           45  +} -test {
           46  +  faultsim_test_result      \
           47  +      {1 {SQLITE_CONSTRAINT - UNIQUE constraint failed: target.x}} \
           48  +      {1 SQLITE_CONSTRAINT} \
           49  +      {1 SQLITE_NOMEM} \
           50  +      {1 {SQLITE_NOMEM - unable to open a temporary database file for storing temporary tables}} \
           51  +      {1 {SQLITE_NOMEM - out of memory}} 
           52  +}
           53  +
           54  +
           55  +
           56  +
           57  +finish_test
           58  +

Added ext/ota/sqlite3ota.c.

            1  +/*
            2  +** 2014 August 30
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +**
           14  +** OVERVIEW 
           15  +**
           16  +**  The OTA extension requires that the OTA update be packaged as an
           17  +**  SQLite database. The tables it expects to find are described in
           18  +**  sqlite3ota.h.  Essentially, for each table xyz in the target database
           19  +**  that the user wishes to write to, a corresponding data_xyz table is
           20  +**  created in the OTA database and populated with one row for each row to
           21  +**  update, insert or delete from the target table.
           22  +** 
           23  +**  The update proceeds in three stages:
           24  +** 
           25  +**  1) The database is updated. The modified database pages are written
           26  +**     to a *-oal file. A *-oal file is just like a *-wal file, except
           27  +**     that it is named "<database>-oal" instead of "<database>-wal".
           28  +**     Because regular SQLite clients do not look for file named
           29  +**     "<database>-oal", they go on using the original database in
           30  +**     rollback mode while the *-oal file is being generated.
           31  +** 
           32  +**     During this stage OTA does not update the database by writing
           33  +**     directly to the target tables. Instead it creates "imposter"
           34  +**     tables using the SQLITE_TESTCTRL_IMPOSTER interface that it uses
           35  +**     to update each b-tree individually. All updates required by each
           36  +**     b-tree are completed before moving on to the next, and all
           37  +**     updates are done in sorted key order.
           38  +** 
           39  +**  2) The "<database>-oal" file is moved to the equivalent "<database>-wal"
           40  +**     location using a call to rename(2). Before doing this the OTA
           41  +**     module takes an EXCLUSIVE lock on the database file, ensuring
           42  +**     that there are no other active readers.
           43  +** 
           44  +**     Once the EXCLUSIVE lock is released, any other database readers
           45  +**     detect the new *-wal file and read the database in wal mode. At
           46  +**     this point they see the new version of the database - including
           47  +**     the updates made as part of the OTA update.
           48  +** 
           49  +**  3) The new *-wal file is checkpointed. This proceeds in the same way 
           50  +**     as a regular database checkpoint, except that a single frame is
           51  +**     checkpointed each time sqlite3ota_step() is called. If the OTA
           52  +**     handle is closed before the entire *-wal file is checkpointed,
           53  +**     the checkpoint progress is saved in the OTA database and the
           54  +**     checkpoint can be resumed by another OTA client at some point in
           55  +**     the future.
           56  +**
           57  +** POTENTIAL PROBLEMS
           58  +** 
           59  +**  The rename() call might not be portable. And OTA is not currently
           60  +**  syncing the directory after renaming the file.
           61  +**
           62  +**  When state is saved, any commit to the *-oal file and the commit to
           63  +**  the OTA update database are not atomic. So if the power fails at the
           64  +**  wrong moment they might get out of sync. As the main database will be
           65  +**  committed before the OTA update database this will likely either just
           66  +**  pass unnoticed, or result in SQLITE_CONSTRAINT errors (due to UNIQUE
           67  +**  constraint violations).
           68  +**
           69  +**  If some client does modify the target database mid OTA update, or some
           70  +**  other error occurs, the OTA extension will keep throwing errors. It's
           71  +**  not really clear how to get out of this state. The system could just
           72  +**  by delete the OTA update database and *-oal file and have the device
           73  +**  download the update again and start over.
           74  +**
           75  +**  At present, for an UPDATE, both the new.* and old.* records are
           76  +**  collected in the ota_xyz table. And for both UPDATEs and DELETEs all
           77  +**  fields are collected.  This means we're probably writing a lot more
           78  +**  data to disk when saving the state of an ongoing update to the OTA
           79  +**  update database than is strictly necessary.
           80  +** 
           81  +*/
           82  +
           83  +#include <assert.h>
           84  +#include <string.h>
           85  +#include <stdio.h>
           86  +#include <unistd.h>
           87  +
           88  +#include "sqlite3.h"
           89  +
           90  +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_OTA)
           91  +#include "sqlite3ota.h"
           92  +
           93  +/* Maximum number of prepared UPDATE statements held by this module */
           94  +#define SQLITE_OTA_UPDATE_CACHESIZE 16
           95  +
           96  +/*
           97  +** Swap two objects of type TYPE.
           98  +*/
           99  +#if !defined(SQLITE_AMALGAMATION)
          100  +# define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
          101  +#endif
          102  +
          103  +/*
          104  +** The ota_state table is used to save the state of a partially applied
          105  +** update so that it can be resumed later. The table consists of integer
          106  +** keys mapped to values as follows:
          107  +**
          108  +** OTA_STATE_STAGE:
          109  +**   May be set to integer values 1, 2, 4 or 5. As follows:
          110  +**       1: the *-ota file is currently under construction.
          111  +**       2: the *-ota file has been constructed, but not yet moved 
          112  +**          to the *-wal path.
          113  +**       4: the checkpoint is underway.
          114  +**       5: the ota update has been checkpointed.
          115  +**
          116  +** OTA_STATE_TBL:
          117  +**   Only valid if STAGE==1. The target database name of the table 
          118  +**   currently being written.
          119  +**
          120  +** OTA_STATE_IDX:
          121  +**   Only valid if STAGE==1. The target database name of the index 
          122  +**   currently being written, or NULL if the main table is currently being
          123  +**   updated.
          124  +**
          125  +** OTA_STATE_ROW:
          126  +**   Only valid if STAGE==1. Number of rows already processed for the current
          127  +**   table/index.
          128  +**
          129  +** OTA_STATE_PROGRESS:
          130  +**   Total number of sqlite3ota_step() calls made so far as part of this
          131  +**   ota update.
          132  +**
          133  +** OTA_STATE_CKPT:
          134  +**   Valid if STAGE==4. The 64-bit checksum associated with the wal-index
          135  +**   header created by recovering the *-wal file. This is used to detect
          136  +**   cases when another client appends frames to the *-wal file in the
          137  +**   middle of an incremental checkpoint (an incremental checkpoint cannot
          138  +**   be continued if this happens).
          139  +**
          140  +** OTA_STATE_COOKIE:
          141  +**   Valid if STAGE==1. The current change-counter cookie value in the 
          142  +**   target db file.
          143  +**
          144  +** OTA_STATE_OALSZ:
          145  +**   Valid if STAGE==1. The size in bytes of the *-oal file.
          146  +*/
          147  +#define OTA_STATE_STAGE       1
          148  +#define OTA_STATE_TBL         2
          149  +#define OTA_STATE_IDX         3
          150  +#define OTA_STATE_ROW         4
          151  +#define OTA_STATE_PROGRESS    5
          152  +#define OTA_STATE_CKPT        6
          153  +#define OTA_STATE_COOKIE      7
          154  +#define OTA_STATE_OALSZ       8
          155  +
          156  +#define OTA_STAGE_OAL         1
          157  +#define OTA_STAGE_MOVE        2
          158  +#define OTA_STAGE_CAPTURE     3
          159  +#define OTA_STAGE_CKPT        4
          160  +#define OTA_STAGE_DONE        5
          161  +
          162  +
          163  +#define OTA_CREATE_STATE \
          164  +  "CREATE TABLE IF NOT EXISTS %s.ota_state(k INTEGER PRIMARY KEY, v)"
          165  +
          166  +typedef struct OtaFrame OtaFrame;
          167  +typedef struct OtaObjIter OtaObjIter;
          168  +typedef struct OtaState OtaState;
          169  +typedef struct ota_vfs ota_vfs;
          170  +typedef struct ota_file ota_file;
          171  +typedef struct OtaUpdateStmt OtaUpdateStmt;
          172  +
          173  +#if !defined(SQLITE_AMALGAMATION)
          174  +typedef unsigned int u32;
          175  +typedef unsigned char u8;
          176  +typedef sqlite3_int64 i64;
          177  +#endif
          178  +
          179  +/*
          180  +** These values must match the values defined in wal.c for the equivalent
          181  +** locks. These are not magic numbers as they are part of the SQLite file
          182  +** format.
          183  +*/
          184  +#define WAL_LOCK_WRITE  0
          185  +#define WAL_LOCK_CKPT   1
          186  +#define WAL_LOCK_READ0  3
          187  +
          188  +/*
          189  +** A structure to store values read from the ota_state table in memory.
          190  +*/
          191  +struct OtaState {
          192  +  int eStage;
          193  +  char *zTbl;
          194  +  char *zIdx;
          195  +  i64 iWalCksum;
          196  +  int nRow;
          197  +  i64 nProgress;
          198  +  u32 iCookie;
          199  +  i64 iOalSz;
          200  +};
          201  +
          202  +struct OtaUpdateStmt {
          203  +  char *zMask;                    /* Copy of update mask used with pUpdate */
          204  +  sqlite3_stmt *pUpdate;          /* Last update statement (or NULL) */
          205  +  OtaUpdateStmt *pNext;
          206  +};
          207  +
          208  +/*
          209  +** An iterator of this type is used to iterate through all objects in
          210  +** the target database that require updating. For each such table, the
          211  +** iterator visits, in order:
          212  +**
          213  +**     * the table itself, 
          214  +**     * each index of the table (zero or more points to visit), and
          215  +**     * a special "cleanup table" state.
          216  +**
          217  +** abIndexed:
          218  +**   If the table has no indexes on it, abIndexed is set to NULL. Otherwise,
          219  +**   it points to an array of flags nTblCol elements in size. The flag is
          220  +**   set for each column that is either a part of the PK or a part of an
          221  +**   index. Or clear otherwise.
          222  +**   
          223  +*/
          224  +struct OtaObjIter {
          225  +  sqlite3_stmt *pTblIter;         /* Iterate through tables */
          226  +  sqlite3_stmt *pIdxIter;         /* Index iterator */
          227  +  int nTblCol;                    /* Size of azTblCol[] array */
          228  +  char **azTblCol;                /* Array of unquoted target column names */
          229  +  char **azTblType;               /* Array of target column types */
          230  +  int *aiSrcOrder;                /* src table col -> target table col */
          231  +  u8 *abTblPk;                    /* Array of flags, set on target PK columns */
          232  +  u8 *abNotNull;                  /* Array of flags, set on NOT NULL columns */
          233  +  u8 *abIndexed;                  /* Array of flags, set on indexed & PK cols */
          234  +  int eType;                      /* Table type - an OTA_PK_XXX value */
          235  +
          236  +  /* Output variables. zTbl==0 implies EOF. */
          237  +  int bCleanup;                   /* True in "cleanup" state */
          238  +  const char *zTbl;               /* Name of target db table */
          239  +  const char *zIdx;               /* Name of target db index (or null) */
          240  +  int iTnum;                      /* Root page of current object */
          241  +  int iPkTnum;                    /* If eType==EXTERNAL, root of PK index */
          242  +  int bUnique;                    /* Current index is unique */
          243  +
          244  +  /* Statements created by otaObjIterPrepareAll() */
          245  +  int nCol;                       /* Number of columns in current object */
          246  +  sqlite3_stmt *pSelect;          /* Source data */
          247  +  sqlite3_stmt *pInsert;          /* Statement for INSERT operations */
          248  +  sqlite3_stmt *pDelete;          /* Statement for DELETE ops */
          249  +  sqlite3_stmt *pTmpInsert;       /* Insert into ota_tmp_$zTbl */
          250  +
          251  +  /* Last UPDATE used (for PK b-tree updates only), or NULL. */
          252  +  OtaUpdateStmt *pOtaUpdate;
          253  +};
          254  +
          255  +/*
          256  +** Values for OtaObjIter.eType
          257  +**
          258  +**     0: Table does not exist (error)
          259  +**     1: Table has an implicit rowid.
          260  +**     2: Table has an explicit IPK column.
          261  +**     3: Table has an external PK index.
          262  +**     4: Table is WITHOUT ROWID.
          263  +**     5: Table is a virtual table.
          264  +*/
          265  +#define OTA_PK_NOTABLE        0
          266  +#define OTA_PK_NONE           1
          267  +#define OTA_PK_IPK            2
          268  +#define OTA_PK_EXTERNAL       3
          269  +#define OTA_PK_WITHOUT_ROWID  4
          270  +#define OTA_PK_VTAB           5
          271  +
          272  +
          273  +/*
          274  +** Within the OTA_STAGE_OAL stage, each call to sqlite3ota_step() performs
          275  +** one of the following operations.
          276  +*/
          277  +#define OTA_INSERT     1          /* Insert on a main table b-tree */
          278  +#define OTA_DELETE     2          /* Delete a row from a main table b-tree */
          279  +#define OTA_IDX_DELETE 3          /* Delete a row from an aux. index b-tree */
          280  +#define OTA_IDX_INSERT 4          /* Insert on an aux. index b-tree */
          281  +#define OTA_UPDATE     5          /* Update a row in a main table b-tree */
          282  +
          283  +
          284  +/*
          285  +** A single step of an incremental checkpoint - frame iWalFrame of the wal
          286  +** file should be copied to page iDbPage of the database file.
          287  +*/
          288  +struct OtaFrame {
          289  +  u32 iDbPage;
          290  +  u32 iWalFrame;
          291  +};
          292  +
          293  +/*
          294  +** OTA handle.
          295  +*/
          296  +struct sqlite3ota {
          297  +  int eStage;                     /* Value of OTA_STATE_STAGE field */
          298  +  sqlite3 *dbMain;                /* target database handle */
          299  +  sqlite3 *dbOta;                 /* ota database handle */
          300  +  char *zTarget;                  /* Path to target db */
          301  +  char *zOta;                     /* Path to ota db */
          302  +  char *zState;                   /* Path to state db (or NULL if zOta) */
          303  +  char zStateDb[5];               /* Db name for state ("stat" or "main") */
          304  +  int rc;                         /* Value returned by last ota_step() call */
          305  +  char *zErrmsg;                  /* Error message if rc!=SQLITE_OK */
          306  +  int nStep;                      /* Rows processed for current object */
          307  +  int nProgress;                  /* Rows processed for all objects */
          308  +  OtaObjIter objiter;             /* Iterator for skipping through tbl/idx */
          309  +  const char *zVfsName;           /* Name of automatically created ota vfs */
          310  +  ota_file *pTargetFd;            /* File handle open on target db */
          311  +  i64 iOalSz;
          312  +
          313  +  /* The following state variables are used as part of the incremental
          314  +  ** checkpoint stage (eStage==OTA_STAGE_CKPT). See comments surrounding
          315  +  ** function otaSetupCheckpoint() for details.  */
          316  +  u32 iMaxFrame;                  /* Largest iWalFrame value in aFrame[] */
          317  +  u32 mLock;
          318  +  int nFrame;                     /* Entries in aFrame[] array */
          319  +  int nFrameAlloc;                /* Allocated size of aFrame[] array */
          320  +  OtaFrame *aFrame;
          321  +  int pgsz;
          322  +  u8 *aBuf;
          323  +  i64 iWalCksum;
          324  +};
          325  +
          326  +/*
          327  +** An ota VFS is implemented using an instance of this structure.
          328  +*/
          329  +struct ota_vfs {
          330  +  sqlite3_vfs base;               /* ota VFS shim methods */
          331  +  sqlite3_vfs *pRealVfs;          /* Underlying VFS */
          332  +  sqlite3_mutex *mutex;           /* Mutex to protect pMain */
          333  +  ota_file *pMain;                /* Linked list of main db files */
          334  +};
          335  +
          336  +/*
          337  +** Each file opened by an ota VFS is represented by an instance of
          338  +** the following structure.
          339  +*/
          340  +struct ota_file {
          341  +  sqlite3_file base;              /* sqlite3_file methods */
          342  +  sqlite3_file *pReal;            /* Underlying file handle */
          343  +  ota_vfs *pOtaVfs;               /* Pointer to the ota_vfs object */
          344  +  sqlite3ota *pOta;               /* Pointer to ota object (ota target only) */
          345  +
          346  +  int openFlags;                  /* Flags this file was opened with */
          347  +  u32 iCookie;                    /* Cookie value for main db files */
          348  +  u8 iWriteVer;                   /* "write-version" value for main db files */
          349  +
          350  +  int nShm;                       /* Number of entries in apShm[] array */
          351  +  char **apShm;                   /* Array of mmap'd *-shm regions */
          352  +  char *zDel;                     /* Delete this when closing file */
          353  +
          354  +  const char *zWal;               /* Wal filename for this main db file */
          355  +  ota_file *pWalFd;               /* Wal file descriptor for this main db */
          356  +  ota_file *pMainNext;            /* Next MAIN_DB file */
          357  +};
          358  +
          359  +
          360  +/*
          361  +** Prepare the SQL statement in buffer zSql against database handle db.
          362  +** If successful, set *ppStmt to point to the new statement and return
          363  +** SQLITE_OK. 
          364  +**
          365  +** Otherwise, if an error does occur, set *ppStmt to NULL and return
          366  +** an SQLite error code. Additionally, set output variable *pzErrmsg to
          367  +** point to a buffer containing an error message. It is the responsibility
          368  +** of the caller to (eventually) free this buffer using sqlite3_free().
          369  +*/
          370  +static int prepareAndCollectError(
          371  +  sqlite3 *db, 
          372  +  sqlite3_stmt **ppStmt,
          373  +  char **pzErrmsg,
          374  +  const char *zSql
          375  +){
          376  +  int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
          377  +  if( rc!=SQLITE_OK ){
          378  +    *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
          379  +    *ppStmt = 0;
          380  +  }
          381  +  return rc;
          382  +}
          383  +
          384  +/*
          385  +** Reset the SQL statement passed as the first argument. Return a copy
          386  +** of the value returned by sqlite3_reset().
          387  +**
          388  +** If an error has occurred, then set *pzErrmsg to point to a buffer
          389  +** containing an error message. It is the responsibility of the caller
          390  +** to eventually free this buffer using sqlite3_free().
          391  +*/
          392  +static int resetAndCollectError(sqlite3_stmt *pStmt, char **pzErrmsg){
          393  +  int rc = sqlite3_reset(pStmt);
          394  +  if( rc!=SQLITE_OK ){
          395  +    *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt)));
          396  +  }
          397  +  return rc;
          398  +}
          399  +
          400  +/*
          401  +** Unless it is NULL, argument zSql points to a buffer allocated using
          402  +** sqlite3_malloc containing an SQL statement. This function prepares the SQL
          403  +** statement against database db and frees the buffer. If statement 
          404  +** compilation is successful, *ppStmt is set to point to the new statement 
          405  +** handle and SQLITE_OK is returned. 
          406  +**
          407  +** Otherwise, if an error occurs, *ppStmt is set to NULL and an error code
          408  +** returned. In this case, *pzErrmsg may also be set to point to an error
          409  +** message. It is the responsibility of the caller to free this error message
          410  +** buffer using sqlite3_free().
          411  +**
          412  +** If argument zSql is NULL, this function assumes that an OOM has occurred.
          413  +** In this case SQLITE_NOMEM is returned and *ppStmt set to NULL.
          414  +*/
          415  +static int prepareFreeAndCollectError(
          416  +  sqlite3 *db, 
          417  +  sqlite3_stmt **ppStmt,
          418  +  char **pzErrmsg,
          419  +  char *zSql
          420  +){
          421  +  int rc;
          422  +  assert( *pzErrmsg==0 );
          423  +  if( zSql==0 ){
          424  +    rc = SQLITE_NOMEM;
          425  +    *ppStmt = 0;
          426  +  }else{
          427  +    rc = prepareAndCollectError(db, ppStmt, pzErrmsg, zSql);
          428  +    sqlite3_free(zSql);
          429  +  }
          430  +  return rc;
          431  +}
          432  +
          433  +/*
          434  +** Free the OtaObjIter.azTblCol[] and OtaObjIter.abTblPk[] arrays allocated
          435  +** by an earlier call to otaObjIterCacheTableInfo().
          436  +*/
          437  +static void otaObjIterFreeCols(OtaObjIter *pIter){
          438  +  int i;
          439  +  for(i=0; i<pIter->nTblCol; i++){
          440  +    sqlite3_free(pIter->azTblCol[i]);
          441  +    sqlite3_free(pIter->azTblType[i]);
          442  +  }
          443  +  sqlite3_free(pIter->azTblCol);
          444  +  pIter->azTblCol = 0;
          445  +  pIter->azTblType = 0;
          446  +  pIter->aiSrcOrder = 0;
          447  +  pIter->abTblPk = 0;
          448  +  pIter->abNotNull = 0;
          449  +  pIter->nTblCol = 0;
          450  +  pIter->eType = 0;               /* Invalid value */
          451  +}
          452  +
          453  +/*
          454  +** Finalize all statements and free all allocations that are specific to
          455  +** the current object (table/index pair).
          456  +*/
          457  +static void otaObjIterClearStatements(OtaObjIter *pIter){
          458  +  OtaUpdateStmt *pUp;
          459  +
          460  +  sqlite3_finalize(pIter->pSelect);
          461  +  sqlite3_finalize(pIter->pInsert);
          462  +  sqlite3_finalize(pIter->pDelete);
          463  +  sqlite3_finalize(pIter->pTmpInsert);
          464  +  pUp = pIter->pOtaUpdate;
          465  +  while( pUp ){
          466  +    OtaUpdateStmt *pTmp = pUp->pNext;
          467  +    sqlite3_finalize(pUp->pUpdate);
          468  +    sqlite3_free(pUp);
          469  +    pUp = pTmp;
          470  +  }
          471  +  
          472  +  pIter->pSelect = 0;
          473  +  pIter->pInsert = 0;
          474  +  pIter->pDelete = 0;
          475  +  pIter->pOtaUpdate = 0;
          476  +  pIter->pTmpInsert = 0;
          477  +  pIter->nCol = 0;
          478  +}
          479  +
          480  +/*
          481  +** Clean up any resources allocated as part of the iterator object passed
          482  +** as the only argument.
          483  +*/
          484  +static void otaObjIterFinalize(OtaObjIter *pIter){
          485  +  otaObjIterClearStatements(pIter);
          486  +  sqlite3_finalize(pIter->pTblIter);
          487  +  sqlite3_finalize(pIter->pIdxIter);
          488  +  otaObjIterFreeCols(pIter);
          489  +  memset(pIter, 0, sizeof(OtaObjIter));
          490  +}
          491  +
          492  +/*
          493  +** Advance the iterator to the next position.
          494  +**
          495  +** If no error occurs, SQLITE_OK is returned and the iterator is left 
          496  +** pointing to the next entry. Otherwise, an error code and message is 
          497  +** left in the OTA handle passed as the first argument. A copy of the 
          498  +** error code is returned.
          499  +*/
          500  +static int otaObjIterNext(sqlite3ota *p, OtaObjIter *pIter){
          501  +  int rc = p->rc;
          502  +  if( rc==SQLITE_OK ){
          503  +
          504  +    /* Free any SQLite statements used while processing the previous object */ 
          505  +    otaObjIterClearStatements(pIter);
          506  +    if( pIter->zIdx==0 ){
          507  +      rc = sqlite3_exec(p->dbMain,
          508  +          "DROP TRIGGER IF EXISTS temp.ota_insert_tr;"
          509  +          "DROP TRIGGER IF EXISTS temp.ota_update1_tr;"
          510  +          "DROP TRIGGER IF EXISTS temp.ota_update2_tr;"
          511  +          "DROP TRIGGER IF EXISTS temp.ota_delete_tr;"
          512  +          , 0, 0, &p->zErrmsg
          513  +      );
          514  +    }
          515  +
          516  +    if( rc==SQLITE_OK ){
          517  +      if( pIter->bCleanup ){
          518  +        otaObjIterFreeCols(pIter);
          519  +        pIter->bCleanup = 0;
          520  +        rc = sqlite3_step(pIter->pTblIter);
          521  +        if( rc!=SQLITE_ROW ){
          522  +          rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg);
          523  +          pIter->zTbl = 0;
          524  +        }else{
          525  +          pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0);
          526  +          rc = pIter->zTbl ? SQLITE_OK : SQLITE_NOMEM;
          527  +        }
          528  +      }else{
          529  +        if( pIter->zIdx==0 ){
          530  +          sqlite3_stmt *pIdx = pIter->pIdxIter;
          531  +          rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC);
          532  +        }
          533  +        if( rc==SQLITE_OK ){
          534  +          rc = sqlite3_step(pIter->pIdxIter);
          535  +          if( rc!=SQLITE_ROW ){
          536  +            rc = resetAndCollectError(pIter->pIdxIter, &p->zErrmsg);
          537  +            pIter->bCleanup = 1;
          538  +            pIter->zIdx = 0;
          539  +          }else{
          540  +            pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0);
          541  +            pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1);
          542  +            pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2);
          543  +            rc = pIter->zIdx ? SQLITE_OK : SQLITE_NOMEM;
          544  +          }
          545  +        }
          546  +      }
          547  +    }
          548  +  }
          549  +
          550  +  if( rc!=SQLITE_OK ){
          551  +    otaObjIterFinalize(pIter);
          552  +    p->rc = rc;
          553  +  }
          554  +  return rc;
          555  +}
          556  +
          557  +/*
          558  +** Initialize the iterator structure passed as the second argument.
          559  +**
          560  +** If no error occurs, SQLITE_OK is returned and the iterator is left 
          561  +** pointing to the first entry. Otherwise, an error code and message is 
          562  +** left in the OTA handle passed as the first argument. A copy of the 
          563  +** error code is returned.
          564  +*/
          565  +static int otaObjIterFirst(sqlite3ota *p, OtaObjIter *pIter){
          566  +  int rc;
          567  +  memset(pIter, 0, sizeof(OtaObjIter));
          568  +
          569  +  rc = prepareAndCollectError(p->dbOta, &pIter->pTblIter, &p->zErrmsg, 
          570  +      "SELECT substr(name, 6) FROM sqlite_master "
          571  +      "WHERE type='table' AND name LIKE 'data_%'"
          572  +  );
          573  +
          574  +  if( rc==SQLITE_OK ){
          575  +    rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg,
          576  +        "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' "
          577  +        "  FROM main.sqlite_master "
          578  +        "  WHERE type='index' AND tbl_name = ?"
          579  +    );
          580  +  }
          581  +
          582  +  pIter->bCleanup = 1;
          583  +  p->rc = rc;
          584  +  return otaObjIterNext(p, pIter);
          585  +}
          586  +
          587  +/*
          588  +** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs,
          589  +** an error code is stored in the OTA handle passed as the first argument.
          590  +**
          591  +** If an error has already occurred (p->rc is already set to something other
          592  +** than SQLITE_OK), then this function returns NULL without modifying the
          593  +** stored error code. In this case it still calls sqlite3_free() on any 
          594  +** printf() parameters associated with %z conversions.
          595  +*/
          596  +static char *otaMPrintf(sqlite3ota *p, const char *zFmt, ...){
          597  +  char *zSql = 0;
          598  +  va_list ap;
          599  +  va_start(ap, zFmt);
          600  +  zSql = sqlite3_vmprintf(zFmt, ap);
          601  +  if( p->rc==SQLITE_OK ){
          602  +    if( zSql==0 ) p->rc = SQLITE_NOMEM;
          603  +  }else{
          604  +    sqlite3_free(zSql);
          605  +    zSql = 0;
          606  +  }
          607  +  va_end(ap);
          608  +  return zSql;
          609  +}
          610  +
          611  +/*
          612  +** Argument zFmt is a sqlite3_mprintf() style format string. The trailing
          613  +** arguments are the usual subsitution values. This function performs
          614  +** the printf() style substitutions and executes the result as an SQL
          615  +** statement on the OTA handles database.
          616  +**
          617  +** If an error occurs, an error code and error message is stored in the
          618  +** OTA handle. If an error has already occurred when this function is
          619  +** called, it is a no-op.
          620  +*/
          621  +static int otaMPrintfExec(sqlite3ota *p, sqlite3 *db, const char *zFmt, ...){
          622  +  va_list ap;
          623  +  va_start(ap, zFmt);
          624  +  char *zSql = sqlite3_vmprintf(zFmt, ap);
          625  +  if( p->rc==SQLITE_OK ){
          626  +    if( zSql==0 ){
          627  +      p->rc = SQLITE_NOMEM;
          628  +    }else{
          629  +      p->rc = sqlite3_exec(db, zSql, 0, 0, &p->zErrmsg);
          630  +    }
          631  +  }
          632  +  sqlite3_free(zSql);
          633  +  va_end(ap);
          634  +  return p->rc;
          635  +}
          636  +
          637  +/*
          638  +** Attempt to allocate and return a pointer to a zeroed block of nByte 
          639  +** bytes. 
          640  +**
          641  +** If an error (i.e. an OOM condition) occurs, return NULL and leave an 
          642  +** error code in the ota handle passed as the first argument. Or, if an 
          643  +** error has already occurred when this function is called, return NULL 
          644  +** immediately without attempting the allocation or modifying the stored
          645  +** error code.
          646  +*/
          647  +static void *otaMalloc(sqlite3ota *p, int nByte){
          648  +  void *pRet = 0;
          649  +  if( p->rc==SQLITE_OK ){
          650  +    assert( nByte>0 );
          651  +    pRet = sqlite3_malloc(nByte);
          652  +    if( pRet==0 ){
          653  +      p->rc = SQLITE_NOMEM;
          654  +    }else{
          655  +      memset(pRet, 0, nByte);
          656  +    }
          657  +  }
          658  +  return pRet;
          659  +}
          660  +
          661  +
          662  +/*
          663  +** Allocate and zero the pIter->azTblCol[] and abTblPk[] arrays so that
          664  +** there is room for at least nCol elements. If an OOM occurs, store an
          665  +** error code in the OTA handle passed as the first argument.
          666  +*/
          667  +static void otaAllocateIterArrays(sqlite3ota *p, OtaObjIter *pIter, int nCol){
          668  +  int nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol;
          669  +  char **azNew;
          670  +
          671  +  azNew = (char**)otaMalloc(p, nByte);
          672  +  if( azNew ){
          673  +    pIter->azTblCol = azNew;
          674  +    pIter->azTblType = &azNew[nCol];
          675  +    pIter->aiSrcOrder = (int*)&pIter->azTblType[nCol];
          676  +    pIter->abTblPk = (u8*)&pIter->aiSrcOrder[nCol];
          677  +    pIter->abNotNull = (u8*)&pIter->abTblPk[nCol];
          678  +    pIter->abIndexed = (u8*)&pIter->abNotNull[nCol];
          679  +  }
          680  +}
          681  +
          682  +/*
          683  +** The first argument must be a nul-terminated string. This function
          684  +** returns a copy of the string in memory obtained from sqlite3_malloc().
          685  +** It is the responsibility of the caller to eventually free this memory
          686  +** using sqlite3_free().
          687  +**
          688  +** If an OOM condition is encountered when attempting to allocate memory,
          689  +** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise,
          690  +** if the allocation succeeds, (*pRc) is left unchanged.
          691  +*/
          692  +static char *otaStrndup(const char *zStr, int *pRc){
          693  +  char *zRet = 0;
          694  +
          695  +  assert( *pRc==SQLITE_OK );
          696  +  if( zStr ){
          697  +    int nCopy = strlen(zStr) + 1;
          698  +    zRet = (char*)sqlite3_malloc(nCopy);
          699  +    if( zRet ){
          700  +      memcpy(zRet, zStr, nCopy);
          701  +    }else{
          702  +      *pRc = SQLITE_NOMEM;
          703  +    }
          704  +  }
          705  +
          706  +  return zRet;
          707  +}
          708  +
          709  +/*
          710  +** Finalize the statement passed as the second argument.
          711  +**
          712  +** If the sqlite3_finalize() call indicates that an error occurs, and the
          713  +** ota handle error code is not already set, set the error code and error
          714  +** message accordingly.
          715  +*/
          716  +static void otaFinalize(sqlite3ota *p, sqlite3_stmt *pStmt){
          717  +  sqlite3 *db = sqlite3_db_handle(pStmt);
          718  +  int rc = sqlite3_finalize(pStmt);
          719  +  if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){
          720  +    p->rc = rc;
          721  +    p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
          722  +  }
          723  +}
          724  +
          725  +/* Determine the type of a table.
          726  +**
          727  +**   peType is of type (int*), a pointer to an output parameter of type
          728  +**   (int). This call sets the output parameter as follows, depending
          729  +**   on the type of the table specified by parameters dbName and zTbl.
          730  +**
          731  +**     OTA_PK_NOTABLE:       No such table.
          732  +**     OTA_PK_NONE:          Table has an implicit rowid.
          733  +**     OTA_PK_IPK:           Table has an explicit IPK column.
          734  +**     OTA_PK_EXTERNAL:      Table has an external PK index.
          735  +**     OTA_PK_WITHOUT_ROWID: Table is WITHOUT ROWID.
          736  +**     OTA_PK_VTAB:          Table is a virtual table.
          737  +**
          738  +**   Argument *piPk is also of type (int*), and also points to an output
          739  +**   parameter. Unless the table has an external primary key index 
          740  +**   (i.e. unless *peType is set to 3), then *piPk is set to zero. Or,
          741  +**   if the table does have an external primary key index, then *piPk
          742  +**   is set to the root page number of the primary key index before
          743  +**   returning.
          744  +**
          745  +** ALGORITHM:
          746  +**
          747  +**   if( no entry exists in sqlite_master ){
          748  +**     return OTA_PK_NOTABLE
          749  +**   }else if( sql for the entry starts with "CREATE VIRTUAL" ){
          750  +**     return OTA_PK_VTAB
          751  +**   }else if( "PRAGMA index_list()" for the table contains a "pk" index ){
          752  +**     if( the index that is the pk exists in sqlite_master ){
          753  +**       *piPK = rootpage of that index.
          754  +**       return OTA_PK_EXTERNAL
          755  +**     }else{
          756  +**       return OTA_PK_WITHOUT_ROWID
          757  +**     }
          758  +**   }else if( "PRAGMA table_info()" lists one or more "pk" columns ){
          759  +**     return OTA_PK_IPK
          760  +**   }else{
          761  +**     return OTA_PK_NONE
          762  +**   }
          763  +*/
          764  +static void otaTableType(
          765  +  sqlite3ota *p,
          766  +  const char *zTab,
          767  +  int *peType,
          768  +  int *piTnum,
          769  +  int *piPk
          770  +){
          771  +  /*
          772  +  ** 0) SELECT count(*) FROM sqlite_master where name=%Q AND IsVirtual(%Q)
          773  +  ** 1) PRAGMA index_list = ?
          774  +  ** 2) SELECT count(*) FROM sqlite_master where name=%Q 
          775  +  ** 3) PRAGMA table_info = ?
          776  +  */
          777  +  sqlite3_stmt *aStmt[4] = {0, 0, 0, 0};
          778  +
          779  +  *peType = OTA_PK_NOTABLE;
          780  +  *piPk = 0;
          781  +
          782  +  assert( p->rc==SQLITE_OK );
          783  +  p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg, 
          784  +    sqlite3_mprintf(
          785  +          "SELECT (sql LIKE 'create virtual%%'), rootpage"
          786  +          "  FROM sqlite_master"
          787  +          " WHERE name=%Q", zTab
          788  +  ));
          789  +  if( p->rc!=SQLITE_OK || sqlite3_step(aStmt[0])!=SQLITE_ROW ){
          790  +    /* Either an error, or no such table. */
          791  +    goto otaTableType_end;
          792  +  }
          793  +  if( sqlite3_column_int(aStmt[0], 0) ){
          794  +    *peType = OTA_PK_VTAB;                     /* virtual table */
          795  +    goto otaTableType_end;
          796  +  }
          797  +  *piTnum = sqlite3_column_int(aStmt[0], 1);
          798  +
          799  +  p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[1], &p->zErrmsg, 
          800  +    sqlite3_mprintf("PRAGMA index_list=%Q",zTab)
          801  +  );
          802  +  if( p->rc ) goto otaTableType_end;
          803  +  while( sqlite3_step(aStmt[1])==SQLITE_ROW ){
          804  +    const u8 *zOrig = sqlite3_column_text(aStmt[1], 3);
          805  +    const u8 *zIdx = sqlite3_column_text(aStmt[1], 1);
          806  +    if( zOrig && zIdx && zOrig[0]=='p' ){
          807  +      p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[2], &p->zErrmsg, 
          808  +          sqlite3_mprintf(
          809  +            "SELECT rootpage FROM sqlite_master WHERE name = %Q", zIdx
          810  +      ));
          811  +      if( p->rc==SQLITE_OK ){
          812  +        if( sqlite3_step(aStmt[2])==SQLITE_ROW ){
          813  +          *piPk = sqlite3_column_int(aStmt[2], 0);
          814  +          *peType = OTA_PK_EXTERNAL;
          815  +        }else{
          816  +          *peType = OTA_PK_WITHOUT_ROWID;
          817  +        }
          818  +      }
          819  +      goto otaTableType_end;
          820  +    }
          821  +  }
          822  +
          823  +  p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[3], &p->zErrmsg, 
          824  +    sqlite3_mprintf("PRAGMA table_info=%Q",zTab)
          825  +  );
          826  +  if( p->rc==SQLITE_OK ){
          827  +    while( sqlite3_step(aStmt[3])==SQLITE_ROW ){
          828  +      if( sqlite3_column_int(aStmt[3],5)>0 ){
          829  +        *peType = OTA_PK_IPK;                /* explicit IPK column */
          830  +        goto otaTableType_end;
          831  +      }
          832  +    }
          833  +    *peType = OTA_PK_NONE;
          834  +  }
          835  +
          836  +otaTableType_end: {
          837  +    int i;
          838  +    for(i=0; i<sizeof(aStmt)/sizeof(aStmt[0]); i++){
          839  +      otaFinalize(p, aStmt[i]);
          840  +    }
          841  +  }
          842  +}
          843  +
          844  +/*
          845  +** This is a helper function for otaObjIterCacheTableInfo(). It populates
          846  +** the pIter->abIndexed[] array.
          847  +*/
          848  +static void otaObjIterCacheIndexedCols(sqlite3ota *p, OtaObjIter *pIter){
          849  +  sqlite3_stmt *pList = 0;
          850  +  int bIndex = 0;
          851  +
          852  +  if( p->rc==SQLITE_OK ){
          853  +    memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol);
          854  +    p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg,
          855  +        sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
          856  +    );
          857  +  }
          858  +
          859  +  while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
          860  +    const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
          861  +    sqlite3_stmt *pXInfo = 0;
          862  +    if( zIdx==0 ) break;
          863  +    p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
          864  +        sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
          865  +    );
          866  +    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
          867  +      int iCid = sqlite3_column_int(pXInfo, 1);
          868  +      if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
          869  +    }
          870  +    otaFinalize(p, pXInfo);
          871  +    bIndex = 1;
          872  +  }
          873  +
          874  +  otaFinalize(p, pList);
          875  +  if( bIndex==0 ) pIter->abIndexed = 0;
          876  +}
          877  +
          878  +
          879  +/*
          880  +** If they are not already populated, populate the pIter->azTblCol[],
          881  +** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to
          882  +** the table (not index) that the iterator currently points to.
          883  +**
          884  +** Return SQLITE_OK if successful, or an SQLite error code otherwise. If
          885  +** an error does occur, an error code and error message are also left in 
          886  +** the OTA handle.
          887  +*/
          888  +static int otaObjIterCacheTableInfo(sqlite3ota *p, OtaObjIter *pIter){
          889  +  if( pIter->azTblCol==0 ){
          890  +    sqlite3_stmt *pStmt = 0;
          891  +    int nCol = 0;
          892  +    int i;                        /* for() loop iterator variable */
          893  +    int bOtaRowid = 0;            /* If input table has column "ota_rowid" */
          894  +    int iOrder = 0;
          895  +    int iTnum = 0;
          896  +
          897  +    /* Figure out the type of table this step will deal with. */
          898  +    assert( pIter->eType==0 );
          899  +    otaTableType(p, pIter->zTbl, &pIter->eType, &iTnum, &pIter->iPkTnum);
          900  +    if( p->rc==SQLITE_OK && pIter->eType==OTA_PK_NOTABLE ){
          901  +      p->rc = SQLITE_ERROR;
          902  +      p->zErrmsg = sqlite3_mprintf("no such table: %s", pIter->zTbl);
          903  +    }
          904  +    if( p->rc ) return p->rc;
          905  +    if( pIter->zIdx==0 ) pIter->iTnum = iTnum;
          906  +
          907  +    assert( pIter->eType==OTA_PK_NONE || pIter->eType==OTA_PK_IPK 
          908  +         || pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_WITHOUT_ROWID
          909  +         || pIter->eType==OTA_PK_VTAB
          910  +    );
          911  +
          912  +    /* Populate the azTblCol[] and nTblCol variables based on the columns
          913  +    ** of the input table. Ignore any input table columns that begin with
          914  +    ** "ota_".  */
          915  +    p->rc = prepareFreeAndCollectError(p->dbOta, &pStmt, &p->zErrmsg, 
          916  +        sqlite3_mprintf("SELECT * FROM 'data_%q'", pIter->zTbl)
          917  +    );
          918  +    if( p->rc==SQLITE_OK ){
          919  +      nCol = sqlite3_column_count(pStmt);
          920  +      otaAllocateIterArrays(p, pIter, nCol);
          921  +    }
          922  +    for(i=0; p->rc==SQLITE_OK && i<nCol; i++){
          923  +      const char *zName = (const char*)sqlite3_column_name(pStmt, i);
          924  +      if( sqlite3_strnicmp("ota_", zName, 4) ){
          925  +        char *zCopy = otaStrndup(zName, &p->rc);
          926  +        pIter->aiSrcOrder[pIter->nTblCol] = pIter->nTblCol;
          927  +        pIter->azTblCol[pIter->nTblCol++] = zCopy;
          928  +      }
          929  +      else if( 0==sqlite3_stricmp("ota_rowid", zName) ){
          930  +        bOtaRowid = 1;
          931  +      }
          932  +    }
          933  +    sqlite3_finalize(pStmt);
          934  +    pStmt = 0;
          935  +
          936  +    if( p->rc==SQLITE_OK
          937  +     && bOtaRowid!=(pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE)
          938  +    ){
          939  +      p->rc = SQLITE_ERROR;
          940  +      p->zErrmsg = sqlite3_mprintf(
          941  +          "table data_%q %s ota_rowid column", pIter->zTbl,
          942  +          (bOtaRowid ? "may not have" : "requires")
          943  +      );
          944  +    }
          945  +
          946  +    /* Check that all non-HIDDEN columns in the destination table are also
          947  +    ** present in the input table. Populate the abTblPk[], azTblType[] and
          948  +    ** aiTblOrder[] arrays at the same time.  */
          949  +    if( p->rc==SQLITE_OK ){
          950  +      p->rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, 
          951  +          sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl)
          952  +      );
          953  +    }
          954  +    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
          955  +      const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
          956  +      if( zName==0 ) break;  /* An OOM - finalize() below returns S_NOMEM */
          957  +      for(i=iOrder; i<pIter->nTblCol; i++){
          958  +        if( 0==strcmp(zName, pIter->azTblCol[i]) ) break;
          959  +      }
          960  +      if( i==pIter->nTblCol ){
          961  +        p->rc = SQLITE_ERROR;
          962  +        p->zErrmsg = sqlite3_mprintf("column missing from data_%q: %s",
          963  +            pIter->zTbl, zName
          964  +        );
          965  +      }else{
          966  +        int iPk = sqlite3_column_int(pStmt, 5);
          967  +        int bNotNull = sqlite3_column_int(pStmt, 3);
          968  +        const char *zType = (const char*)sqlite3_column_text(pStmt, 2);
          969  +
          970  +        if( i!=iOrder ){
          971  +          SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]);
          972  +          SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]);
          973  +        }
          974  +
          975  +        pIter->azTblType[iOrder] = otaStrndup(zType, &p->rc);
          976  +        pIter->abTblPk[iOrder] = (iPk!=0);
          977  +        pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
          978  +        iOrder++;
          979  +      }
          980  +    }
          981  +
          982  +    otaFinalize(p, pStmt);
          983  +    otaObjIterCacheIndexedCols(p, pIter);
          984  +    assert( pIter->eType!=OTA_PK_VTAB || pIter->abIndexed==0 );
          985  +  }
          986  +
          987  +  return p->rc;
          988  +}
          989  +
          990  +/*
          991  +** This function constructs and returns a pointer to a nul-terminated 
          992  +** string containing some SQL clause or list based on one or more of the 
          993  +** column names currently stored in the pIter->azTblCol[] array.
          994  +*/
          995  +static char *otaObjIterGetCollist(
          996  +  sqlite3ota *p,                  /* OTA object */
          997  +  OtaObjIter *pIter               /* Object iterator for column names */
          998  +){
          999  +  char *zList = 0;
         1000  +  const char *zSep = "";
         1001  +  int i;
         1002  +  for(i=0; i<pIter->nTblCol; i++){
         1003  +    const char *z = pIter->azTblCol[i];
         1004  +    zList = otaMPrintf(p, "%z%s\"%w\"", zList, zSep, z);
         1005  +    zSep = ", ";
         1006  +  }
         1007  +  return zList;
         1008  +}
         1009  +
         1010  +/*
         1011  +** This function is used to create a SELECT list (the list of SQL 
         1012  +** expressions that follows a SELECT keyword) for a SELECT statement 
         1013  +** used to read from an data_xxx or ota_tmp_xxx table while updating the 
         1014  +** index object currently indicated by the iterator object passed as the 
         1015  +** second argument. A "PRAGMA index_xinfo = <idxname>" statement is used 
         1016  +** to obtain the required information.
         1017  +**
         1018  +** If the index is of the following form:
         1019  +**
         1020  +**   CREATE INDEX i1 ON t1(c, b COLLATE nocase);
         1021  +**
         1022  +** and "t1" is a table with an explicit INTEGER PRIMARY KEY column 
         1023  +** "ipk", the returned string is:
         1024  +**
         1025  +**   "`c` COLLATE 'BINARY', `b` COLLATE 'NOCASE', `ipk` COLLATE 'BINARY'"
         1026  +**
         1027  +** As well as the returned string, three other malloc'd strings are 
         1028  +** returned via output parameters. As follows:
         1029  +**
         1030  +**   pzImposterCols: ...
         1031  +**   pzImposterPk: ...
         1032  +**   pzWhere: ...
         1033  +*/
         1034  +static char *otaObjIterGetIndexCols(
         1035  +  sqlite3ota *p,                  /* OTA object */
         1036  +  OtaObjIter *pIter,              /* Object iterator for column names */
         1037  +  char **pzImposterCols,          /* OUT: Columns for imposter table */
         1038  +  char **pzImposterPk,            /* OUT: Imposter PK clause */
         1039  +  char **pzWhere,                 /* OUT: WHERE clause */
         1040  +  int *pnBind                     /* OUT: Total number of columns */
         1041  +){
         1042  +  int rc = p->rc;                 /* Error code */
         1043  +  int rc2;                        /* sqlite3_finalize() return code */
         1044  +  char *zRet = 0;                 /* String to return */
         1045  +  char *zImpCols = 0;             /* String to return via *pzImposterCols */
         1046  +  char *zImpPK = 0;               /* String to return via *pzImposterPK */
         1047  +  char *zWhere = 0;               /* String to return via *pzWhere */
         1048  +  int nBind = 0;                  /* Value to return via *pnBind */
         1049  +  const char *zCom = "";          /* Set to ", " later on */
         1050  +  const char *zAnd = "";          /* Set to " AND " later on */
         1051  +  sqlite3_stmt *pXInfo = 0;       /* PRAGMA index_xinfo = ? */
         1052  +
         1053  +  if( rc==SQLITE_OK ){
         1054  +    assert( p->zErrmsg==0 );
         1055  +    rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
         1056  +        sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
         1057  +    );
         1058  +  }
         1059  +
         1060  +  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
         1061  +    int iCid = sqlite3_column_int(pXInfo, 1);
         1062  +    int bDesc = sqlite3_column_int(pXInfo, 3);
         1063  +    const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
         1064  +    const char *zCol;
         1065  +    const char *zType;
         1066  +
         1067  +    if( iCid<0 ){
         1068  +      /* An integer primary key. If the table has an explicit IPK, use
         1069  +      ** its name. Otherwise, use "ota_rowid".  */
         1070  +      if( pIter->eType==OTA_PK_IPK ){
         1071  +        int i;
         1072  +        for(i=0; pIter->abTblPk[i]==0; i++);
         1073  +        assert( i<pIter->nTblCol );
         1074  +        zCol = pIter->azTblCol[i];
         1075  +      }else{
         1076  +        zCol = "ota_rowid";
         1077  +      }
         1078  +      zType = "INTEGER";
         1079  +    }else{
         1080  +      zCol = pIter->azTblCol[iCid];
         1081  +      zType = pIter->azTblType[iCid];
         1082  +    }
         1083  +
         1084  +    zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate);
         1085  +    if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){
         1086  +      const char *zOrder = (bDesc ? " DESC" : "");
         1087  +      zImpPK = sqlite3_mprintf("%z%s\"ota_imp_%d%w\"%s", 
         1088  +          zImpPK, zCom, nBind, zCol, zOrder
         1089  +      );
         1090  +    }
         1091  +    zImpCols = sqlite3_mprintf("%z%s\"ota_imp_%d%w\" %s COLLATE %Q", 
         1092  +        zImpCols, zCom, nBind, zCol, zType, zCollate
         1093  +    );
         1094  +    zWhere = sqlite3_mprintf(
         1095  +        "%z%s\"ota_imp_%d%w\" IS ?", zWhere, zAnd, nBind, zCol
         1096  +    );
         1097  +    if( zRet==0 || zImpPK==0 || zImpCols==0 || zWhere==0 ) rc = SQLITE_NOMEM;
         1098  +    zCom = ", ";
         1099  +    zAnd = " AND ";
         1100  +    nBind++;
         1101  +  }
         1102  +
         1103  +  rc2 = sqlite3_finalize(pXInfo);
         1104  +  if( rc==SQLITE_OK ) rc = rc2;
         1105  +
         1106  +  if( rc!=SQLITE_OK ){
         1107  +    sqlite3_free(zRet);
         1108  +    sqlite3_free(zImpCols);
         1109  +    sqlite3_free(zImpPK);
         1110  +    sqlite3_free(zWhere);
         1111  +    zRet = 0;
         1112  +    zImpCols = 0;
         1113  +    zImpPK = 0;
         1114  +    zWhere = 0;
         1115  +    p->rc = rc;
         1116  +  }
         1117  +
         1118  +  *pzImposterCols = zImpCols;
         1119  +  *pzImposterPk = zImpPK;
         1120  +  *pzWhere = zWhere;
         1121  +  *pnBind = nBind;
         1122  +  return zRet;
         1123  +}
         1124  +
         1125  +/*
         1126  +** Assuming the current table columns are "a", "b" and "c", and the zObj
         1127  +** paramter is passed "old", return a string of the form:
         1128  +**
         1129  +**     "old.a, old.b, old.b"
         1130  +**
         1131  +** With the column names escaped.
         1132  +**
         1133  +** For tables with implicit rowids - OTA_PK_EXTERNAL and OTA_PK_NONE, append
         1134  +** the text ", old._rowid_" to the returned value.
         1135  +*/
         1136  +static char *otaObjIterGetOldlist(
         1137  +  sqlite3ota *p, 
         1138  +  OtaObjIter *pIter,
         1139  +  const char *zObj
         1140  +){
         1141  +  char *zList = 0;
         1142  +  if( p->rc==SQLITE_OK && pIter->abIndexed ){
         1143  +    const char *zS = "";
         1144  +    int i;
         1145  +    for(i=0; i<pIter->nTblCol; i++){
         1146  +      if( pIter->abIndexed[i] ){
         1147  +        const char *zCol = pIter->azTblCol[i];
         1148  +        zList = sqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol);
         1149  +      }else{
         1150  +        zList = sqlite3_mprintf("%z%sNULL", zList, zS);
         1151  +      }
         1152  +      zS = ", ";
         1153  +      if( zList==0 ){
         1154  +        p->rc = SQLITE_NOMEM;
         1155  +        break;
         1156  +      }
         1157  +    }
         1158  +
         1159  +    /* For a table with implicit rowids, append "old._rowid_" to the list. */
         1160  +    if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
         1161  +      zList = otaMPrintf(p, "%z, %s._rowid_", zList, zObj);
         1162  +    }
         1163  +  }
         1164  +  return zList;
         1165  +}
         1166  +
         1167  +/*
         1168  +** Return an expression that can be used in a WHERE clause to match the
         1169  +** primary key of the current table. For example, if the table is:
         1170  +**
         1171  +**   CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c));
         1172  +**
         1173  +** Return the string:
         1174  +**
         1175  +**   "b = ?1 AND c = ?2"
         1176  +*/
         1177  +static char *otaObjIterGetWhere(
         1178  +  sqlite3ota *p, 
         1179  +  OtaObjIter *pIter
         1180  +){
         1181  +  char *zList = 0;
         1182  +  if( pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE ){
         1183  +    zList = otaMPrintf(p, "_rowid_ = ?%d", pIter->nTblCol+1);
         1184  +  }else if( pIter->eType==OTA_PK_EXTERNAL ){
         1185  +    const char *zSep = "";
         1186  +    int i;
         1187  +    for(i=0; i<pIter->nTblCol; i++){
         1188  +      if( pIter->abTblPk[i] ){
         1189  +        zList = otaMPrintf(p, "%z%sc%d=?%d", zList, zSep, i, i+1);
         1190  +        zSep = " AND ";
         1191  +      }
         1192  +    }
         1193  +    zList = otaMPrintf(p, 
         1194  +        "_rowid_ = (SELECT id FROM ota_imposter2 WHERE %z)", zList
         1195  +    );
         1196  +
         1197  +  }else{
         1198  +    const char *zSep = "";
         1199  +    int i;
         1200  +    for(i=0; i<pIter->nTblCol; i++){
         1201  +      if( pIter->abTblPk[i] ){
         1202  +        const char *zCol = pIter->azTblCol[i];
         1203  +        zList = otaMPrintf(p, "%z%s\"%w\"=?%d", zList, zSep, zCol, i+1);
         1204  +        zSep = " AND ";
         1205  +      }
         1206  +    }
         1207  +  }
         1208  +  return zList;
         1209  +}
         1210  +
         1211  +/*
         1212  +** The SELECT statement iterating through the keys for the current object
         1213  +** (p->objiter.pSelect) currently points to a valid row. However, there
         1214  +** is something wrong with the ota_control value in the ota_control value
         1215  +** stored in the (p->nCol+1)'th column. Set the error code and error message
         1216  +** of the OTA handle to something reflecting this.
         1217  +*/
         1218  +static void otaBadControlError(sqlite3ota *p){
         1219  +  p->rc = SQLITE_ERROR;
         1220  +  p->zErrmsg = sqlite3_mprintf("invalid ota_control value");
         1221  +}
         1222  +
         1223  +
         1224  +/*
         1225  +** Return a nul-terminated string containing the comma separated list of
         1226  +** assignments that should be included following the "SET" keyword of
         1227  +** an UPDATE statement used to update the table object that the iterator
         1228  +** passed as the second argument currently points to if the ota_control
         1229  +** column of the data_xxx table entry is set to zMask.
         1230  +**
         1231  +** The memory for the returned string is obtained from sqlite3_malloc().
         1232  +** It is the responsibility of the caller to eventually free it using
         1233  +** sqlite3_free(). 
         1234  +**
         1235  +** If an OOM error is encountered when allocating space for the new
         1236  +** string, an error code is left in the ota handle passed as the first
         1237  +** argument and NULL is returned. Or, if an error has already occurred
         1238  +** when this function is called, NULL is returned immediately, without
         1239  +** attempting the allocation or modifying the stored error code.
         1240  +*/
         1241  +static char *otaObjIterGetSetlist(
         1242  +  sqlite3ota *p,
         1243  +  OtaObjIter *pIter,
         1244  +  const char *zMask
         1245  +){
         1246  +  char *zList = 0;
         1247  +  if( p->rc==SQLITE_OK ){
         1248  +    int i;
         1249  +
         1250  +    if( strlen(zMask)!=pIter->nTblCol ){
         1251  +      otaBadControlError(p);
         1252  +    }else{
         1253  +      const char *zSep = "";
         1254  +      for(i=0; i<pIter->nTblCol; i++){
         1255  +        char c = zMask[pIter->aiSrcOrder[i]];
         1256  +        if( c=='x' ){
         1257  +          zList = otaMPrintf(p, "%z%s\"%w\"=?%d", 
         1258  +              zList, zSep, pIter->azTblCol[i], i+1
         1259  +          );
         1260  +          zSep = ", ";
         1261  +        }
         1262  +        if( c=='d' ){
         1263  +          zList = otaMPrintf(p, "%z%s\"%w\"=ota_delta(\"%w\", ?%d)", 
         1264  +              zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
         1265  +          );
         1266  +          zSep = ", ";
         1267  +        }
         1268  +      }
         1269  +    }
         1270  +  }
         1271  +  return zList;
         1272  +}
         1273  +
         1274  +/*
         1275  +** Return a nul-terminated string consisting of nByte comma separated
         1276  +** "?" expressions. For example, if nByte is 3, return a pointer to
         1277  +** a buffer containing the string "?,?,?".
         1278  +**
         1279  +** The memory for the returned string is obtained from sqlite3_malloc().
         1280  +** It is the responsibility of the caller to eventually free it using
         1281  +** sqlite3_free(). 
         1282  +**
         1283  +** If an OOM error is encountered when allocating space for the new
         1284  +** string, an error code is left in the ota handle passed as the first
         1285  +** argument and NULL is returned. Or, if an error has already occurred
         1286  +** when this function is called, NULL is returned immediately, without
         1287  +** attempting the allocation or modifying the stored error code.
         1288  +*/
         1289  +static char *otaObjIterGetBindlist(sqlite3ota *p, int nBind){
         1290  +  char *zRet = 0;
         1291  +  int nByte = nBind*2 + 1;
         1292  +
         1293  +  zRet = (char*)otaMalloc(p, nByte);
         1294  +  if( zRet ){
         1295  +    int i;
         1296  +    for(i=0; i<nBind; i++){
         1297  +      zRet[i*2] = '?';
         1298  +      zRet[i*2+1] = (i+1==nBind) ? '\0' : ',';
         1299  +    }
         1300  +  }
         1301  +  return zRet;
         1302  +}
         1303  +
         1304  +/*
         1305  +** The iterator currently points to a table (not index) of type 
         1306  +** OTA_PK_WITHOUT_ROWID. This function creates the PRIMARY KEY 
         1307  +** declaration for the corresponding imposter table. For example,
         1308  +** if the iterator points to a table created as:
         1309  +**
         1310  +**   CREATE TABLE t1(a, b, c, PRIMARY KEY(b, a DESC)) WITHOUT ROWID
         1311  +**
         1312  +** this function returns:
         1313  +**
         1314  +**   PRIMARY KEY("b", "a" DESC)
         1315  +*/
         1316  +static char *otaWithoutRowidPK(sqlite3ota *p, OtaObjIter *pIter){
         1317  +  char *z = 0;
         1318  +  assert( pIter->zIdx==0 );
         1319  +  if( p->rc==SQLITE_OK ){
         1320  +    const char *zSep = "PRIMARY KEY(";
         1321  +    sqlite3_stmt *pXList = 0;     /* PRAGMA index_list = (pIter->zTbl) */
         1322  +    sqlite3_stmt *pXInfo = 0;     /* PRAGMA index_xinfo = <pk-index> */
         1323  +   
         1324  +    p->rc = prepareFreeAndCollectError(p->dbMain, &pXList, &p->zErrmsg,
         1325  +        sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
         1326  +    );
         1327  +    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){
         1328  +      const char *zOrig = (const char*)sqlite3_column_text(pXList,3);
         1329  +      if( zOrig && strcmp(zOrig, "pk")==0 ){
         1330  +        const char *zIdx = (const char*)sqlite3_column_text(pXList,1);
         1331  +        if( zIdx ){
         1332  +          p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
         1333  +              sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
         1334  +          );
         1335  +        }
         1336  +        break;
         1337  +      }
         1338  +    }
         1339  +    otaFinalize(p, pXList);
         1340  +
         1341  +    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
         1342  +      if( sqlite3_column_int(pXInfo, 5) ){
         1343  +        /* int iCid = sqlite3_column_int(pXInfo, 0); */
         1344  +        const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2);
         1345  +        const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : "";
         1346  +        z = otaMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc);
         1347  +        zSep = ", ";
         1348  +      }
         1349  +    }
         1350  +    z = otaMPrintf(p, "%z)", z);
         1351  +    otaFinalize(p, pXInfo);
         1352  +  }
         1353  +  return z;
         1354  +}
         1355  +
         1356  +/*
         1357  +** This function creates the second imposter table used when writing to
         1358  +** a table b-tree where the table has an external primary key. If the
         1359  +** iterator passed as the second argument does not currently point to
         1360  +** a table (not index) with an external primary key, this function is a
         1361  +** no-op. 
         1362  +**
         1363  +** Assuming the iterator does point to a table with an external PK, this
         1364  +** function creates a WITHOUT ROWID imposter table named "ota_imposter2"
         1365  +** used to access that PK index. For example, if the target table is
         1366  +** declared as follows:
         1367  +**
         1368  +**   CREATE TABLE t1(a, b TEXT, c REAL, PRIMARY KEY(b, c));
         1369  +**
         1370  +** then the imposter table schema is:
         1371  +**
         1372  +**   CREATE TABLE ota_imposter2(c1 TEXT, c2 REAL, id INTEGER) WITHOUT ROWID;
         1373  +**
         1374  +*/
         1375  +static void otaCreateImposterTable2(sqlite3ota *p, OtaObjIter *pIter){
         1376  +  if( p->rc==SQLITE_OK && pIter->eType==OTA_PK_EXTERNAL ){
         1377  +    int tnum = pIter->iPkTnum;    /* Root page of PK index */
         1378  +    sqlite3_stmt *pQuery = 0;     /* SELECT name ... WHERE rootpage = $tnum */
         1379  +    const char *zIdx = 0;         /* Name of PK index */
         1380  +    sqlite3_stmt *pXInfo = 0;     /* PRAGMA main.index_xinfo = $zIdx */
         1381  +    const char *zComma = "";
         1382  +    char *zCols = 0;              /* Used to build up list of table cols */
         1383  +    char *zPk = 0;                /* Used to build up table PK declaration */
         1384  +
         1385  +    /* Figure out the name of the primary key index for the current table.
         1386  +    ** This is needed for the argument to "PRAGMA index_xinfo". Set
         1387  +    ** zIdx to point to a nul-terminated string containing this name. */
         1388  +    p->rc = prepareAndCollectError(p->dbMain, &pQuery, &p->zErrmsg, 
         1389  +        "SELECT name FROM sqlite_master WHERE rootpage = ?"
         1390  +    );
         1391  +    if( p->rc==SQLITE_OK ){
         1392  +      sqlite3_bind_int(pQuery, 1, tnum);
         1393  +      if( SQLITE_ROW==sqlite3_step(pQuery) ){
         1394  +        zIdx = (const char*)sqlite3_column_text(pQuery, 0);
         1395  +      }
         1396  +    }
         1397  +    if( zIdx ){
         1398  +      p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
         1399  +          sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
         1400  +      );
         1401  +    }
         1402  +    otaFinalize(p, pQuery);
         1403  +
         1404  +    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
         1405  +      int bKey = sqlite3_column_int(pXInfo, 5);
         1406  +      if( bKey ){
         1407  +        int iCid = sqlite3_column_int(pXInfo, 1);
         1408  +        int bDesc = sqlite3_column_int(pXInfo, 3);
         1409  +        const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
         1410  +        zCols = otaMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma, 
         1411  +            iCid, pIter->azTblType[iCid], zCollate
         1412  +        );
         1413  +        zPk = otaMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":"");
         1414  +        zComma = ", ";
         1415  +      }
         1416  +    }
         1417  +    zCols = otaMPrintf(p, "%z, id INTEGER", zCols);
         1418  +    otaFinalize(p, pXInfo);
         1419  +
         1420  +    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum);
         1421  +    otaMPrintfExec(p, p->dbMain,
         1422  +        "CREATE TABLE ota_imposter2(%z, PRIMARY KEY(%z)) WITHOUT ROWID", 
         1423  +        zCols, zPk
         1424  +    );
         1425  +    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
         1426  +  }
         1427  +}
         1428  +
         1429  +/*
         1430  +** If an error has already occurred when this function is called, it 
         1431  +** immediately returns zero (without doing any work). Or, if an error
         1432  +** occurs during the execution of this function, it sets the error code
         1433  +** in the sqlite3ota object indicated by the first argument and returns
         1434  +** zero.
         1435  +**
         1436  +** The iterator passed as the second argument is guaranteed to point to
         1437  +** a table (not an index) when this function is called. This function
         1438  +** attempts to create any imposter table required to write to the main
         1439  +** table b-tree of the table before returning. Non-zero is returned if
         1440  +** an imposter table are created, or zero otherwise.
         1441  +**
         1442  +** An imposter table is required in all cases except OTA_PK_VTAB. Only
         1443  +** virtual tables are written to directly. The imposter table has the 
         1444  +** same schema as the actual target table (less any UNIQUE constraints). 
         1445  +** More precisely, the "same schema" means the same columns, types, 
         1446  +** collation sequences. For tables that do not have an external PRIMARY
         1447  +** KEY, it also means the same PRIMARY KEY declaration.
         1448  +*/
         1449  +static void otaCreateImposterTable(sqlite3ota *p, OtaObjIter *pIter){
         1450  +  if( p->rc==SQLITE_OK && pIter->eType!=OTA_PK_VTAB ){
         1451  +    int tnum = pIter->iTnum;
         1452  +    const char *zComma = "";
         1453  +    char *zSql = 0;
         1454  +    int iCol;
         1455  +    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
         1456  +
         1457  +    for(iCol=0; p->rc==SQLITE_OK && iCol<pIter->nTblCol; iCol++){
         1458  +      const char *zPk = "";
         1459  +      const char *zCol = pIter->azTblCol[iCol];
         1460  +      const char *zColl = 0;
         1461  +
         1462  +      p->rc = sqlite3_table_column_metadata(
         1463  +          p->dbMain, "main", pIter->zTbl, zCol, 0, &zColl, 0, 0, 0
         1464  +      );
         1465  +
         1466  +      if( pIter->eType==OTA_PK_IPK && pIter->abTblPk[iCol] ){
         1467  +        /* If the target table column is an "INTEGER PRIMARY KEY", add
         1468  +        ** "PRIMARY KEY" to the imposter table column declaration. */
         1469  +        zPk = "PRIMARY KEY ";
         1470  +      }
         1471  +      zSql = otaMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s", 
         1472  +          zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl,
         1473  +          (pIter->abNotNull[iCol] ? " NOT NULL" : "")
         1474  +      );
         1475  +      zComma = ", ";
         1476  +    }
         1477  +
         1478  +    if( pIter->eType==OTA_PK_WITHOUT_ROWID ){
         1479  +      char *zPk = otaWithoutRowidPK(p, pIter);
         1480  +      if( zPk ){
         1481  +        zSql = otaMPrintf(p, "%z, %z", zSql, zPk);
         1482  +      }
         1483  +    }
         1484  +
         1485  +    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum);
         1486  +    otaMPrintfExec(p, p->dbMain, "CREATE TABLE \"ota_imp_%w\"(%z)%s", 
         1487  +        pIter->zTbl, zSql, 
         1488  +        (pIter->eType==OTA_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "")
         1489  +    );
         1490  +    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
         1491  +  }
         1492  +}
         1493  +
         1494  +/*
         1495  +** Prepare a statement used to insert rows into the "ota_tmp_xxx" table.
         1496  +** Specifically a statement of the form:
         1497  +**
         1498  +**     INSERT INTO ota_tmp_xxx VALUES(?, ?, ? ...);
         1499  +**
         1500  +** The number of bound variables is equal to the number of columns in
         1501  +** the target table, plus one (for the ota_control column), plus one more 
         1502  +** (for the ota_rowid column) if the target table is an implicit IPK or 
         1503  +** virtual table.
         1504  +*/
         1505  +static void otaObjIterPrepareTmpInsert(
         1506  +  sqlite3ota *p, 
         1507  +  OtaObjIter *pIter,
         1508  +  const char *zCollist,
         1509  +  const char *zOtaRowid
         1510  +){
         1511  +  int bOtaRowid = (pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE);
         1512  +  char *zBind = otaObjIterGetBindlist(p, pIter->nTblCol + 1 + bOtaRowid);
         1513  +  if( zBind ){
         1514  +    assert( pIter->pTmpInsert==0 );
         1515  +    p->rc = prepareFreeAndCollectError(
         1516  +        p->dbOta, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf(
         1517  +          "INSERT INTO %s.'ota_tmp_%q'(ota_control,%s%s) VALUES(%z)", 
         1518  +          p->zStateDb, pIter->zTbl, zCollist, zOtaRowid, zBind
         1519  +    ));
         1520  +  }
         1521  +}
         1522  +
         1523  +static void otaTmpInsertFunc(
         1524  +  sqlite3_context *pCtx, 
         1525  +  int nVal,
         1526  +  sqlite3_value **apVal
         1527  +){
         1528  +  sqlite3ota *p = sqlite3_user_data(pCtx);
         1529  +  int rc = SQLITE_OK;
         1530  +  int i;
         1531  +
         1532  +  for(i=0; rc==SQLITE_OK && i<nVal; i++){
         1533  +    rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]);
         1534  +  }
         1535  +  if( rc==SQLITE_OK ){
         1536  +    sqlite3_step(p->objiter.pTmpInsert);
         1537  +    rc = sqlite3_reset(p->objiter.pTmpInsert);
         1538  +  }
         1539  +
         1540  +  if( rc!=SQLITE_OK ){
         1541  +    sqlite3_result_error_code(pCtx, rc);
         1542  +  }
         1543  +}
         1544  +
         1545  +/*
         1546  +** Ensure that the SQLite statement handles required to update the 
         1547  +** target database object currently indicated by the iterator passed 
         1548  +** as the second argument are available.
         1549  +*/
         1550  +static int otaObjIterPrepareAll(
         1551  +  sqlite3ota *p, 
         1552  +  OtaObjIter *pIter,
         1553  +  int nOffset                     /* Add "LIMIT -1 OFFSET $nOffset" to SELECT */
         1554  +){
         1555  +  assert( pIter->bCleanup==0 );
         1556  +  if( pIter->pSelect==0 && otaObjIterCacheTableInfo(p, pIter)==SQLITE_OK ){
         1557  +    const int tnum = pIter->iTnum;
         1558  +    char *zCollist = 0;           /* List of indexed columns */
         1559  +    char **pz = &p->zErrmsg;
         1560  +    const char *zIdx = pIter->zIdx;
         1561  +    char *zLimit = 0;
         1562  +
         1563  +    if( nOffset ){
         1564  +      zLimit = sqlite3_mprintf(" LIMIT -1 OFFSET %d", nOffset);
         1565  +      if( !zLimit ) p->rc = SQLITE_NOMEM;
         1566  +    }
         1567  +
         1568  +    if( zIdx ){
         1569  +      const char *zTbl = pIter->zTbl;
         1570  +      char *zImposterCols = 0;    /* Columns for imposter table */
         1571  +      char *zImposterPK = 0;      /* Primary key declaration for imposter */
         1572  +      char *zWhere = 0;           /* WHERE clause on PK columns */
         1573  +      char *zBind = 0;
         1574  +      int nBind = 0;
         1575  +
         1576  +      assert( pIter->eType!=OTA_PK_VTAB );
         1577  +      zCollist = otaObjIterGetIndexCols(
         1578  +          p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind
         1579  +      );
         1580  +      zBind = otaObjIterGetBindlist(p, nBind);
         1581  +
         1582  +      /* Create the imposter table used to write to this index. */
         1583  +      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
         1584  +      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum);
         1585  +      otaMPrintfExec(p, p->dbMain,
         1586  +          "CREATE TABLE \"ota_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID",
         1587  +          zTbl, zImposterCols, zImposterPK
         1588  +      );
         1589  +      sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
         1590  +
         1591  +      /* Create the statement to insert index entries */
         1592  +      pIter->nCol = nBind;
         1593  +      if( p->rc==SQLITE_OK ){
         1594  +        p->rc = prepareFreeAndCollectError(
         1595  +            p->dbMain, &pIter->pInsert, &p->zErrmsg,
         1596  +          sqlite3_mprintf("INSERT INTO \"ota_imp_%w\" VALUES(%s)", zTbl, zBind)
         1597  +        );
         1598  +      }
         1599  +
         1600  +      /* And to delete index entries */
         1601  +      if( p->rc==SQLITE_OK ){
         1602  +        p->rc = prepareFreeAndCollectError(
         1603  +            p->dbMain, &pIter->pDelete, &p->zErrmsg,
         1604  +          sqlite3_mprintf("DELETE FROM \"ota_imp_%w\" WHERE %s", zTbl, zWhere)
         1605  +        );
         1606  +      }
         1607  +
         1608  +      /* Create the SELECT statement to read keys in sorted order */
         1609  +      if( p->rc==SQLITE_OK ){
         1610  +        char *zSql;
         1611  +        if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
         1612  +          zSql = sqlite3_mprintf(
         1613  +              "SELECT %s, ota_control FROM %s.'ota_tmp_%q' ORDER BY %s%s",
         1614  +              zCollist, p->zStateDb, pIter->zTbl,
         1615  +              zCollist, zLimit
         1616  +          );
         1617  +        }else{
         1618  +          zSql = sqlite3_mprintf(
         1619  +              "SELECT %s, ota_control FROM 'data_%q' "
         1620  +              "WHERE typeof(ota_control)='integer' AND ota_control!=1 "
         1621  +              "UNION ALL "
         1622  +              "SELECT %s, ota_control FROM %s.'ota_tmp_%q' "
         1623  +              "ORDER BY %s%s",
         1624  +              zCollist, pIter->zTbl, 
         1625  +              zCollist, p->zStateDb, pIter->zTbl, 
         1626  +              zCollist, zLimit
         1627  +          );
         1628  +        }
         1629  +        p->rc = prepareFreeAndCollectError(p->dbOta, &pIter->pSelect, pz, zSql);
         1630  +      }
         1631  +
         1632  +      sqlite3_free(zImposterCols);
         1633  +      sqlite3_free(zImposterPK);
         1634  +      sqlite3_free(zWhere);
         1635  +      sqlite3_free(zBind);
         1636  +    }else{
         1637  +      int bOtaRowid = (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE);
         1638  +      const char *zTbl = pIter->zTbl;       /* Table this step applies to */
         1639  +      const char *zWrite;                   /* Imposter table name */
         1640  +
         1641  +      char *zBindings = otaObjIterGetBindlist(p, pIter->nTblCol + bOtaRowid);
         1642  +      char *zWhere = otaObjIterGetWhere(p, pIter);
         1643  +      char *zOldlist = otaObjIterGetOldlist(p, pIter, "old");
         1644  +      char *zNewlist = otaObjIterGetOldlist(p, pIter, "new");
         1645  +
         1646  +      zCollist = otaObjIterGetCollist(p, pIter);
         1647  +      pIter->nCol = pIter->nTblCol;
         1648  +
         1649  +      /* Create the SELECT statement to read keys from data_xxx */
         1650  +      if( p->rc==SQLITE_OK ){
         1651  +        p->rc = prepareFreeAndCollectError(p->dbOta, &pIter->pSelect, pz,
         1652  +            sqlite3_mprintf(
         1653  +              "SELECT %s, ota_control%s FROM 'data_%q'%s", 
         1654  +              zCollist, (bOtaRowid ? ", ota_rowid" : ""), zTbl, zLimit
         1655  +            )
         1656  +        );
         1657  +      }
         1658  +
         1659  +      /* Create the imposter table or tables (if required). */
         1660  +      otaCreateImposterTable(p, pIter);
         1661  +      otaCreateImposterTable2(p, pIter);
         1662  +      zWrite = (pIter->eType==OTA_PK_VTAB ? "" : "ota_imp_");
         1663  +
         1664  +      /* Create the INSERT statement to write to the target PK b-tree */
         1665  +      if( p->rc==SQLITE_OK ){
         1666  +        p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz,
         1667  +            sqlite3_mprintf(
         1668  +              "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)", 
         1669  +              zWrite, zTbl, zCollist, (bOtaRowid ? ", _rowid_" : ""), zBindings
         1670  +            )
         1671  +        );
         1672  +      }
         1673  +
         1674  +      /* Create the DELETE statement to write to the target PK b-tree */
         1675  +      if( p->rc==SQLITE_OK ){
         1676  +        p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz,
         1677  +            sqlite3_mprintf(
         1678  +              "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere
         1679  +            )
         1680  +        );
         1681  +      }
         1682  +
         1683  +      if( pIter->abIndexed ){
         1684  +        const char *zOtaRowid = "";
         1685  +        if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
         1686  +          zOtaRowid = ", ota_rowid";
         1687  +        }
         1688  +
         1689  +        /* Create the ota_tmp_xxx table and the triggers to populate it. */
         1690  +        otaMPrintfExec(p, p->dbOta,
         1691  +            "CREATE TABLE IF NOT EXISTS %s.'ota_tmp_%q' AS "
         1692  +            "SELECT *%s FROM 'data_%q' WHERE 0;"
         1693  +            , p->zStateDb
         1694  +            , zTbl, (pIter->eType==OTA_PK_EXTERNAL ? ", 0 AS ota_rowid" : "")
         1695  +            , zTbl
         1696  +        );
         1697  +
         1698  +        otaMPrintfExec(p, p->dbMain,
         1699  +            "CREATE TEMP TRIGGER ota_delete_tr BEFORE DELETE ON \"%s%w\" "
         1700  +            "BEGIN "
         1701  +            "  SELECT ota_tmp_insert(2, %s);"
         1702  +            "END;"
         1703  +
         1704  +            "CREATE TEMP TRIGGER ota_update1_tr BEFORE UPDATE ON \"%s%w\" "
         1705  +            "BEGIN "
         1706  +            "  SELECT ota_tmp_insert(2, %s);"
         1707  +            "END;"
         1708  +
         1709  +            "CREATE TEMP TRIGGER ota_update2_tr AFTER UPDATE ON \"%s%w\" "
         1710  +            "BEGIN "
         1711  +            "  SELECT ota_tmp_insert(3, %s);"
         1712  +            "END;",
         1713  +            zWrite, zTbl, zOldlist,
         1714  +            zWrite, zTbl, zOldlist,
         1715  +            zWrite, zTbl, zNewlist
         1716  +        );
         1717  +
         1718  +        if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
         1719  +          otaMPrintfExec(p, p->dbMain,
         1720  +              "CREATE TEMP TRIGGER ota_insert_tr AFTER INSERT ON \"%s%w\" "
         1721  +              "BEGIN "
         1722  +              "  SELECT ota_tmp_insert(0, %s);"
         1723  +              "END;",
         1724  +              zWrite, zTbl, zNewlist
         1725  +          );
         1726  +        }
         1727  +
         1728  +        otaObjIterPrepareTmpInsert(p, pIter, zCollist, zOtaRowid);
         1729  +      }
         1730  +
         1731  +      sqlite3_free(zWhere);
         1732  +      sqlite3_free(zOldlist);
         1733  +      sqlite3_free(zNewlist);
         1734  +      sqlite3_free(zBindings);
         1735  +    }
         1736  +    sqlite3_free(zCollist);
         1737  +    sqlite3_free(zLimit);
         1738  +  }
         1739  +  
         1740  +  return p->rc;
         1741  +}
         1742  +
         1743  +/*
         1744  +** Set output variable *ppStmt to point to an UPDATE statement that may
         1745  +** be used to update the imposter table for the main table b-tree of the
         1746  +** table object that pIter currently points to, assuming that the 
         1747  +** ota_control column of the data_xyz table contains zMask.
         1748  +** 
         1749  +** If the zMask string does not specify any columns to update, then this
         1750  +** is not an error. Output variable *ppStmt is set to NULL in this case.
         1751  +*/
         1752  +static int otaGetUpdateStmt(
         1753  +  sqlite3ota *p,                  /* OTA handle */
         1754  +  OtaObjIter *pIter,              /* Object iterator */
         1755  +  const char *zMask,              /* ota_control value ('x.x.') */
         1756  +  sqlite3_stmt **ppStmt           /* OUT: UPDATE statement handle */
         1757  +){
         1758  +  OtaUpdateStmt **pp;
         1759  +  OtaUpdateStmt *pUp = 0;
         1760  +  int nUp = 0;
         1761  +
         1762  +  /* In case an error occurs */
         1763  +  *ppStmt = 0;
         1764  +
         1765  +  /* Search for an existing statement. If one is found, shift it to the front
         1766  +  ** of the LRU queue and return immediately. Otherwise, leave nUp pointing
         1767  +  ** to the number of statements currently in the cache and pUp to the
         1768  +  ** last object in the list.  */
         1769  +  for(pp=&pIter->pOtaUpdate; *pp; pp=&((*pp)->pNext)){
         1770  +    pUp = *pp;
         1771  +    if( strcmp(pUp->zMask, zMask)==0 ){
         1772  +      *pp = pUp->pNext;
         1773  +      pUp->pNext = pIter->pOtaUpdate;
         1774  +      pIter->pOtaUpdate = pUp;
         1775  +      *ppStmt = pUp->pUpdate; 
         1776  +      return SQLITE_OK;
         1777  +    }
         1778  +    nUp++;
         1779  +  }
         1780  +  assert( pUp==0 || pUp->pNext==0 );
         1781  +
         1782  +  if( nUp>=SQLITE_OTA_UPDATE_CACHESIZE ){
         1783  +    for(pp=&pIter->pOtaUpdate; *pp!=pUp; pp=&((*pp)->pNext));
         1784  +    *pp = 0;
         1785  +    sqlite3_finalize(pUp->pUpdate);
         1786  +    pUp->pUpdate = 0;
         1787  +  }else{
         1788  +    pUp = (OtaUpdateStmt*)otaMalloc(p, sizeof(OtaUpdateStmt)+pIter->nTblCol+1);
         1789  +  }
         1790  +
         1791  +  if( pUp ){
         1792  +    char *zWhere = otaObjIterGetWhere(p, pIter);
         1793  +    char *zSet = otaObjIterGetSetlist(p, pIter, zMask);
         1794  +    char *zUpdate = 0;
         1795  +
         1796  +    pUp->zMask = (char*)&pUp[1];
         1797  +    memcpy(pUp->zMask, zMask, pIter->nTblCol);
         1798  +    pUp->pNext = pIter->pOtaUpdate;
         1799  +    pIter->pOtaUpdate = pUp;
         1800  +
         1801  +    if( zSet ){
         1802  +      const char *zPrefix = "";
         1803  +
         1804  +      if( pIter->eType!=OTA_PK_VTAB ) zPrefix = "ota_imp_";
         1805  +      zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s", 
         1806  +          zPrefix, pIter->zTbl, zSet, zWhere
         1807  +      );
         1808  +      p->rc = prepareFreeAndCollectError(
         1809  +          p->dbMain, &pUp->pUpdate, &p->zErrmsg, zUpdate
         1810  +      );
         1811  +      *ppStmt = pUp->pUpdate;
         1812  +    }
         1813  +    sqlite3_free(zWhere);
         1814  +    sqlite3_free(zSet);
         1815  +  }
         1816  +
         1817  +  return p->rc;
         1818  +}
         1819  +
         1820  +static sqlite3 *otaOpenDbhandle(sqlite3ota *p, const char *zName){
         1821  +  sqlite3 *db = 0;
         1822  +  if( p->rc==SQLITE_OK ){
         1823  +    const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI;
         1824  +    p->rc = sqlite3_open_v2(zName, &db, flags, p->zVfsName);
         1825  +    if( p->rc ){
         1826  +      p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
         1827  +      sqlite3_close(db);
         1828  +      db = 0;
         1829  +    }
         1830  +  }
         1831  +  return db;
         1832  +}
         1833  +
         1834  +/*
         1835  +** Open the database handle and attach the OTA database as "ota". If an
         1836  +** error occurs, leave an error code and message in the OTA handle.
         1837  +*/
         1838  +static void otaOpenDatabase(sqlite3ota *p){
         1839  +  assert( p->rc==SQLITE_OK );
         1840  +  assert( p->dbMain==0 && p->dbOta==0 );
         1841  +
         1842  +  p->eStage = 0;
         1843  +  p->dbMain = otaOpenDbhandle(p, p->zTarget);
         1844  +  p->dbOta = otaOpenDbhandle(p, p->zOta);
         1845  +
         1846  +  /* If using separate OTA and state databases, attach the state database to
         1847  +  ** the OTA db handle now.  */
         1848  +  if( p->zState ){
         1849  +    otaMPrintfExec(p, p->dbOta, "ATTACH %Q AS stat", p->zState);
         1850  +    memcpy(p->zStateDb, "stat", 4);
         1851  +  }else{
         1852  +    memcpy(p->zStateDb, "main", 4);
         1853  +  }
         1854  +
         1855  +  if( p->rc==SQLITE_OK ){
         1856  +    p->rc = sqlite3_create_function(p->dbMain, 
         1857  +        "ota_tmp_insert", -1, SQLITE_UTF8, (void*)p, otaTmpInsertFunc, 0, 0
         1858  +    );
         1859  +  }
         1860  +
         1861  +  if( p->rc==SQLITE_OK ){
         1862  +    p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_OTA, (void*)p);
         1863  +  }
         1864  +  otaMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master");
         1865  +
         1866  +  /* Mark the database file just opened as an OTA target database. If 
         1867  +  ** this call returns SQLITE_NOTFOUND, then the OTA vfs is not in use.
         1868  +  ** This is an error.  */
         1869  +  if( p->rc==SQLITE_OK ){
         1870  +    p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_OTA, (void*)p);
         1871  +  }
         1872  +
         1873  +  if( p->rc==SQLITE_NOTFOUND ){
         1874  +    p->rc = SQLITE_ERROR;
         1875  +    p->zErrmsg = sqlite3_mprintf("ota vfs not found");
         1876  +  }
         1877  +}
         1878  +
         1879  +/*
         1880  +** This routine is a copy of the sqlite3FileSuffix3() routine from the core.
         1881  +** It is a no-op unless SQLITE_ENABLE_8_3_NAMES is defined.
         1882  +**
         1883  +** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database
         1884  +** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and
         1885  +** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
         1886  +** three characters, then shorten the suffix on z[] to be the last three
         1887  +** characters of the original suffix.
         1888  +**
         1889  +** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always
         1890  +** do the suffix shortening regardless of URI parameter.
         1891  +**
         1892  +** Examples:
         1893  +**
         1894  +**     test.db-journal    =>   test.nal
         1895  +**     test.db-wal        =>   test.wal
         1896  +**     test.db-shm        =>   test.shm
         1897  +**     test.db-mj7f3319fa =>   test.9fa
         1898  +*/
         1899  +static void otaFileSuffix3(const char *zBase, char *z){
         1900  +#ifdef SQLITE_ENABLE_8_3_NAMES
         1901  +#if SQLITE_ENABLE_8_3_NAMES<2
         1902  +  if( sqlite3_uri_boolean(zBase, "8_3_names", 0) )
         1903  +#endif
         1904  +  {
         1905  +    int i, sz;
         1906  +    sz = sqlite3Strlen30(z);
         1907  +    for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
         1908  +    if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);
         1909  +  }
         1910  +#endif
         1911  +}
         1912  +
         1913  +/*
         1914  +** Return the current wal-index header checksum for the target database 
         1915  +** as a 64-bit integer.
         1916  +**
         1917  +** The checksum is store in the first page of xShmMap memory as an 8-byte 
         1918  +** blob starting at byte offset 40.
         1919  +*/
         1920  +static i64 otaShmChecksum(sqlite3ota *p){
         1921  +  i64 iRet = 0;
         1922  +  if( p->rc==SQLITE_OK ){
         1923  +    sqlite3_file *pDb = p->pTargetFd->pReal;
         1924  +    u32 volatile *ptr;
         1925  +    p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr);
         1926  +    if( p->rc==SQLITE_OK ){
         1927  +      iRet = ((i64)ptr[10] << 32) + ptr[11];
         1928  +    }
         1929  +  }
         1930  +  return iRet;
         1931  +}
         1932  +
         1933  +/*
         1934  +** This function is called as part of initializing or reinitializing an
         1935  +** incremental checkpoint. 
         1936  +**
         1937  +** It populates the sqlite3ota.aFrame[] array with the set of 
         1938  +** (wal frame -> db page) copy operations required to checkpoint the 
         1939  +** current wal file, and obtains the set of shm locks required to safely 
         1940  +** perform the copy operations directly on the file-system.
         1941  +**
         1942  +** If argument pState is not NULL, then the incremental checkpoint is
         1943  +** being resumed. In this case, if the checksum of the wal-index-header
         1944  +** following recovery is not the same as the checksum saved in the OtaState
         1945  +** object, then the ota handle is set to DONE state. This occurs if some
         1946  +** other client appends a transaction to the wal file in the middle of
         1947  +** an incremental checkpoint.
         1948  +*/
         1949  +static void otaSetupCheckpoint(sqlite3ota *p, OtaState *pState){
         1950  +
         1951  +  /* If pState is NULL, then the wal file may not have been opened and
         1952  +  ** recovered. Running a read-statement here to ensure that doing so
         1953  +  ** does not interfere with the "capture" process below.  */
         1954  +  if( pState==0 ){
         1955  +    p->eStage = 0;
         1956  +    if( p->rc==SQLITE_OK ){
         1957  +      p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_master", 0, 0, 0);
         1958  +    }
         1959  +  }
         1960  +
         1961  +  /* Assuming no error has occurred, run a "restart" checkpoint with the
         1962  +  ** sqlite3ota.eStage variable set to CAPTURE. This turns on the following
         1963  +  ** special behaviour in the ota VFS:
         1964  +  **
         1965  +  **   * If the exclusive shm WRITER or READ0 lock cannot be obtained,
         1966  +  **     the checkpoint fails with SQLITE_BUSY (normally SQLite would
         1967  +  **     proceed with running a passive checkpoint instead of failing).
         1968  +  **
         1969  +  **   * Attempts to read from the *-wal file or write to the database file
         1970  +  **     do not perform any IO. Instead, the frame/page combinations that
         1971  +  **     would be read/written are recorded in the sqlite3ota.aFrame[]
         1972  +  **     array.
         1973  +  **
         1974  +  **   * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER, 
         1975  +  **     READ0 and CHECKPOINT locks taken as part of the checkpoint are
         1976  +  **     no-ops. These locks will not be released until the connection
         1977  +  **     is closed.
         1978  +  **
         1979  +  **   * Attempting to xSync() the database file causes an SQLITE_INTERNAL 
         1980  +  **     error.
         1981  +  **
         1982  +  ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the
         1983  +  ** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[]
         1984  +  ** array populated with a set of (frame -> page) mappings. Because the 
         1985  +  ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy 
         1986  +  ** data from the wal file into the database file according to the 
         1987  +  ** contents of aFrame[].
         1988  +  */
         1989  +  if( p->rc==SQLITE_OK ){
         1990  +    int rc2;
         1991  +    p->eStage = OTA_STAGE_CAPTURE;
         1992  +    rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0);
         1993  +    if( rc2!=SQLITE_INTERNAL ) p->rc = rc2;
         1994  +  }
         1995  +
         1996  +  if( p->rc==SQLITE_OK ){
         1997  +    p->eStage = OTA_STAGE_CKPT;
         1998  +    p->nStep = (pState ? pState->nRow : 0);
         1999  +    p->aBuf = otaMalloc(p, p->pgsz);
         2000  +    p->iWalCksum = otaShmChecksum(p);
         2001  +  }
         2002  +
         2003  +  if( p->rc==SQLITE_OK && pState && pState->iWalCksum!=p->iWalCksum ){
         2004  +    p->rc = SQLITE_DONE;
         2005  +    p->eStage = OTA_STAGE_DONE;
         2006  +  }
         2007  +}
         2008  +
         2009  +/*
         2010  +** Called when iAmt bytes are read from offset iOff of the wal file while
         2011  +** the ota object is in capture mode. Record the frame number of the frame
         2012  +** being read in the aFrame[] array.
         2013  +*/
         2014  +static int otaCaptureWalRead(sqlite3ota *pOta, i64 iOff, int iAmt){
         2015  +  const u32 mReq = (1<<WAL_LOCK_WRITE)|(1<<WAL_LOCK_CKPT)|(1<<WAL_LOCK_READ0);
         2016  +  u32 iFrame;
         2017  +
         2018  +  if( pOta->mLock!=mReq ){
         2019  +    pOta->rc = SQLITE_BUSY;
         2020  +    return SQLITE_INTERNAL;
         2021  +  }
         2022  +
         2023  +  pOta->pgsz = iAmt;
         2024  +  if( pOta->nFrame==pOta->nFrameAlloc ){
         2025  +    int nNew = (pOta->nFrameAlloc ? pOta->nFrameAlloc : 64) * 2;
         2026  +    OtaFrame *aNew;
         2027  +    aNew = (OtaFrame*)sqlite3_realloc(pOta->aFrame, nNew * sizeof(OtaFrame));
         2028  +    if( aNew==0 ) return SQLITE_NOMEM;
         2029  +    pOta->aFrame = aNew;
         2030  +    pOta->nFrameAlloc = nNew;
         2031  +  }
         2032  +
         2033  +  iFrame = (u32)((iOff-32) / (i64)(iAmt+24)) + 1;
         2034  +  if( pOta->iMaxFrame<iFrame ) pOta->iMaxFrame = iFrame;
         2035  +  pOta->aFrame[pOta->nFrame].iWalFrame = iFrame;
         2036  +  pOta->aFrame[pOta->nFrame].iDbPage = 0;
         2037  +  pOta->nFrame++;
         2038  +  return SQLITE_OK;
         2039  +}
         2040  +
         2041  +/*
         2042  +** Called when a page of data is written to offset iOff of the database
         2043  +** file while the ota handle is in capture mode. Record the page number 
         2044  +** of the page being written in the aFrame[] array.
         2045  +*/
         2046  +static int otaCaptureDbWrite(sqlite3ota *pOta, i64 iOff){
         2047  +  pOta->aFrame[pOta->nFrame-1].iDbPage = (u32)(iOff / pOta->pgsz) + 1;
         2048  +  return SQLITE_OK;
         2049  +}
         2050  +
         2051  +/*
         2052  +** This is called as part of an incremental checkpoint operation. Copy
         2053  +** a single frame of data from the wal file into the database file, as
         2054  +** indicated by the OtaFrame object.
         2055  +*/
         2056  +static void otaCheckpointFrame(sqlite3ota *p, OtaFrame *pFrame){
         2057  +  sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
         2058  +  sqlite3_file *pDb = p->pTargetFd->pReal;
         2059  +  i64 iOff;
         2060  +
         2061  +  assert( p->rc==SQLITE_OK );
         2062  +  iOff = (i64)(pFrame->iWalFrame-1) * (p->pgsz + 24) + 32 + 24;
         2063  +  p->rc = pWal->pMethods->xRead(pWal, p->aBuf, p->pgsz, iOff);
         2064  +  if( p->rc ) return;
         2065  +
         2066  +  iOff = (i64)(pFrame->iDbPage-1) * p->pgsz;
         2067  +  p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
         2068  +}
         2069  +
         2070  +
         2071  +/*
         2072  +** Take an EXCLUSIVE lock on the database file.
         2073  +*/
         2074  +static void otaLockDatabase(sqlite3ota *p){
         2075  +  sqlite3_file *pReal = p->pTargetFd->pReal;
         2076  +  assert( p->rc==SQLITE_OK );
         2077  +  p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
         2078  +  if( p->rc==SQLITE_OK ){
         2079  +    p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
         2080  +  }
         2081  +}
         2082  +
         2083  +/*
         2084  +** The OTA handle is currently in OTA_STAGE_OAL state, with a SHARED lock
         2085  +** on the database file. This proc moves the *-oal file to the *-wal path,
         2086  +** then reopens the database file (this time in vanilla, non-oal, WAL mode).
         2087  +** If an error occurs, leave an error code and error message in the ota 
         2088  +** handle.
         2089  +*/
         2090  +static void otaMoveOalFile(sqlite3ota *p){
         2091  +  const char *zBase = sqlite3_db_filename(p->dbMain, "main");
         2092  +
         2093  +  char *zWal = sqlite3_mprintf("%s-wal", zBase);
         2094  +  char *zOal = sqlite3_mprintf("%s-oal", zBase);
         2095  +
         2096  +  assert( p->eStage==OTA_STAGE_MOVE );
         2097  +  assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
         2098  +  if( zWal==0 || zOal==0 ){
         2099  +    p->rc = SQLITE_NOMEM;
         2100  +  }else{
         2101  +    /* Move the *-oal file to *-wal. At this point connection p->db is
         2102  +    ** holding a SHARED lock on the target database file (because it is
         2103  +    ** in WAL mode). So no other connection may be writing the db. 
         2104  +    **
         2105  +    ** In order to ensure that there are no database readers, an EXCLUSIVE
         2106  +    ** lock is obtained here before the *-oal is moved to *-wal.
         2107  +    */
         2108  +    otaLockDatabase(p);
         2109  +    if( p->rc==SQLITE_OK ){
         2110  +      otaFileSuffix3(zBase, zWal);
         2111  +      otaFileSuffix3(zBase, zOal);
         2112  +
         2113  +      /* Re-open the databases. */
         2114  +      otaObjIterFinalize(&p->objiter);
         2115  +      sqlite3_close(p->dbMain);
         2116  +      sqlite3_close(p->dbOta);
         2117  +      p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
         2118  +      if( p->rc==SQLITE_OK ){
         2119  +        p->dbMain = 0;
         2120  +        p->dbOta = 0;
         2121  +        otaOpenDatabase(p);
         2122  +        otaSetupCheckpoint(p, 0);
         2123  +      }
         2124  +    }
         2125  +  }
         2126  +
         2127  +  sqlite3_free(zWal);
         2128  +  sqlite3_free(zOal);
         2129  +}
         2130  +
         2131  +/*
         2132  +** The SELECT statement iterating through the keys for the current object
         2133  +** (p->objiter.pSelect) currently points to a valid row. This function
         2134  +** determines the type of operation requested by this row and returns
         2135  +** one of the following values to indicate the result:
         2136  +**
         2137  +**     * OTA_INSERT
         2138  +**     * OTA_DELETE
         2139  +**     * OTA_IDX_DELETE
         2140  +**     * OTA_UPDATE
         2141  +**
         2142  +** If OTA_UPDATE is returned, then output variable *pzMask is set to
         2143  +** point to the text value indicating the columns to update.
         2144  +**
         2145  +** If the ota_control field contains an invalid value, an error code and
         2146  +** message are left in the OTA handle and zero returned.
         2147  +*/
         2148  +static int otaStepType(sqlite3ota *p, const char **pzMask){
         2149  +  int iCol = p->objiter.nCol;     /* Index of ota_control column */
         2150  +  int res = 0;                    /* Return value */
         2151  +
         2152  +  switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){
         2153  +    case SQLITE_INTEGER: {
         2154  +      int iVal = sqlite3_column_int(p->objiter.pSelect, iCol);
         2155  +      if( iVal==0 ){
         2156  +        res = OTA_INSERT;
         2157  +      }else if( iVal==1 ){
         2158  +        res = OTA_DELETE;
         2159  +      }else if( iVal==2 ){
         2160  +        res = OTA_IDX_DELETE;
         2161  +      }else if( iVal==3 ){
         2162  +        res = OTA_IDX_INSERT;
         2163  +      }
         2164  +      break;
         2165  +    }
         2166  +
         2167  +    case SQLITE_TEXT: {
         2168  +      const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol);
         2169  +      if( z==0 ){
         2170  +        p->rc = SQLITE_NOMEM;
         2171  +      }else{
         2172  +        *pzMask = (const char*)z;
         2173  +      }
         2174  +      res = OTA_UPDATE;
         2175  +
         2176  +      break;
         2177  +    }
         2178  +
         2179  +    default:
         2180  +      break;
         2181  +  }
         2182  +
         2183  +  if( res==0 ){
         2184  +    otaBadControlError(p);
         2185  +  }
         2186  +  return res;
         2187  +}
         2188  +
         2189  +#ifdef SQLITE_DEBUG
         2190  +/*
         2191  +** Assert that column iCol of statement pStmt is named zName.
         2192  +*/
         2193  +static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){
         2194  +  const char *zCol = sqlite3_column_name(pStmt, iCol);
         2195  +  assert( 0==sqlite3_stricmp(zName, zCol) );
         2196  +}
         2197  +#else
         2198  +# define assertColumnName(x,y,z)
         2199  +#endif
         2200  +
         2201  +/*
         2202  +** This function does the work for an sqlite3ota_step() call.
         2203  +**
         2204  +** The object-iterator (p->objiter) currently points to a valid object,
         2205  +** and the input cursor (p->objiter.pSelect) currently points to a valid
         2206  +** input row. Perform whatever processing is required and return.
         2207  +**
         2208  +** If no  error occurs, SQLITE_OK is returned. Otherwise, an error code
         2209  +** and message is left in the OTA handle and a copy of the error code
         2210  +** returned.
         2211  +*/
         2212  +static int otaStep(sqlite3ota *p){
         2213  +  OtaObjIter *pIter = &p->objiter;
         2214  +  const char *zMask = 0;
         2215  +  int i;
         2216  +  int eType = otaStepType(p, &zMask);
         2217  +
         2218  +  if( eType ){
         2219  +    assert( eType!=OTA_UPDATE || pIter->zIdx==0 );
         2220  +
         2221  +    if( pIter->zIdx==0 && eType==OTA_IDX_DELETE ){
         2222  +      otaBadControlError(p);
         2223  +    }
         2224  +    else if( 
         2225  +        eType==OTA_INSERT 
         2226  +     || eType==OTA_DELETE
         2227  +     || eType==OTA_IDX_DELETE 
         2228  +     || eType==OTA_IDX_INSERT
         2229  +    ){
         2230  +      sqlite3_value *pVal;
         2231  +      sqlite3_stmt *pWriter;
         2232  +
         2233  +      assert( eType!=OTA_UPDATE );
         2234  +      assert( eType!=OTA_DELETE || pIter->zIdx==0 );
         2235  +
         2236  +      if( eType==OTA_IDX_DELETE || eType==OTA_DELETE ){
         2237  +        pWriter = pIter->pDelete;
         2238  +      }else{
         2239  +        pWriter = pIter->pInsert;
         2240  +      }
         2241  +
         2242  +      for(i=0; i<pIter->nCol; i++){
         2243  +        /* If this is an INSERT into a table b-tree and the table has an
         2244  +        ** explicit INTEGER PRIMARY KEY, check that this is not an attempt
         2245  +        ** to write a NULL into the IPK column. That is not permitted.  */
         2246  +        if( eType==OTA_INSERT 
         2247  +         && pIter->zIdx==0 && pIter->eType==OTA_PK_IPK && pIter->abTblPk[i] 
         2248  +         && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
         2249  +        ){
         2250  +          p->rc = SQLITE_MISMATCH;
         2251  +          p->zErrmsg = sqlite3_mprintf("datatype mismatch");
         2252  +          goto step_out;
         2253  +        }
         2254  +
         2255  +        if( eType==OTA_DELETE && pIter->abTblPk[i]==0 ){
         2256  +          continue;
         2257  +        }
         2258  +
         2259  +        pVal = sqlite3_column_value(pIter->pSelect, i);
         2260  +        p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
         2261  +        if( p->rc ) goto step_out;
         2262  +      }
         2263  +      if( pIter->zIdx==0
         2264  +       && (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE) 
         2265  +      ){
         2266  +        /* For a virtual table, or a table with no primary key, the 
         2267  +        ** SELECT statement is:
         2268  +        **
         2269  +        **   SELECT <cols>, ota_control, ota_rowid FROM ....
         2270  +        **
         2271  +        ** Hence column_value(pIter->nCol+1).
         2272  +        */
         2273  +        assertColumnName(pIter->pSelect, pIter->nCol+1, "ota_rowid");
         2274  +        pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
         2275  +        p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
         2276  +      }
         2277  +      if( p->rc==SQLITE_OK ){
         2278  +        sqlite3_step(pWriter);
         2279  +        p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
         2280  +      }
         2281  +    }else{
         2282  +      sqlite3_value *pVal;
         2283  +      sqlite3_stmt *pUpdate = 0;
         2284  +      assert( eType==OTA_UPDATE );
         2285  +      otaGetUpdateStmt(p, pIter, zMask, &pUpdate);
         2286  +      if( pUpdate ){
         2287  +        for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){
         2288  +          char c = zMask[pIter->aiSrcOrder[i]];
         2289  +          pVal = sqlite3_column_value(pIter->pSelect, i);
         2290  +          if( pIter->abTblPk[i] || c=='x' || c=='d' ){
         2291  +            p->rc = sqlite3_bind_value(pUpdate, i+1, pVal);
         2292  +          }
         2293  +        }
         2294  +        if( p->rc==SQLITE_OK 
         2295  +         && (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE) 
         2296  +        ){
         2297  +          /* Bind the ota_rowid value to column _rowid_ */
         2298  +          assertColumnName(pIter->pSelect, pIter->nCol+1, "ota_rowid");
         2299  +          pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
         2300  +          p->rc = sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal);
         2301  +        }
         2302  +        if( p->rc==SQLITE_OK ){
         2303  +          sqlite3_step(pUpdate);
         2304  +          p->rc = resetAndCollectError(pUpdate, &p->zErrmsg);
         2305  +        }
         2306  +      }
         2307  +    }
         2308  +  }
         2309  +
         2310  + step_out:
         2311  +  return p->rc;
         2312  +}
         2313  +
         2314  +/*
         2315  +** Increment the schema cookie of the main database opened by p->dbMain.
         2316  +*/
         2317  +static void otaIncrSchemaCookie(sqlite3ota *p){
         2318  +  if( p->rc==SQLITE_OK ){
         2319  +    int iCookie = 1000000;
         2320  +    sqlite3_stmt *pStmt;
         2321  +
         2322  +    p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, 
         2323  +        "PRAGMA schema_version"
         2324  +    );
         2325  +    if( p->rc==SQLITE_OK ){
         2326  +      /* Coverage: it may be that this sqlite3_step() cannot fail. There
         2327  +      ** is already a transaction open, so the prepared statement cannot
         2328  +      ** throw an SQLITE_SCHEMA exception. The only database page the
         2329  +      ** statement reads is page 1, which is guaranteed to be in the cache.
         2330  +      ** And no memory allocations are required.  */
         2331  +      if( SQLITE_ROW==sqlite3_step(pStmt) ){
         2332  +        iCookie = sqlite3_column_int(pStmt, 0);
         2333  +      }
         2334  +      otaFinalize(p, pStmt);
         2335  +    }
         2336  +    if( p->rc==SQLITE_OK ){
         2337  +      otaMPrintfExec(p, p->dbMain, "PRAGMA schema_version = %d", iCookie+1);
         2338  +    }
         2339  +  }
         2340  +}
         2341  +
         2342  +/*
         2343  +** Update the contents of the ota_state table within the ota database. The
         2344  +** value stored in the OTA_STATE_STAGE column is eStage. All other values
         2345  +** are determined by inspecting the ota handle passed as the first argument.
         2346  +*/
         2347  +static void otaSaveState(sqlite3ota *p, int eStage){
         2348  +  if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){
         2349  +    sqlite3_stmt *pInsert = 0;
         2350  +    int rc;
         2351  +
         2352  +    assert( p->zErrmsg==0 );
         2353  +    rc = prepareFreeAndCollectError(p->dbOta, &pInsert, &p->zErrmsg, 
         2354  +        sqlite3_mprintf(
         2355  +          "INSERT OR REPLACE INTO %s.ota_state(k, v) VALUES "
         2356  +          "(%d, %d), "
         2357  +          "(%d, %Q), "
         2358  +          "(%d, %Q), "
         2359  +          "(%d, %d), "
         2360  +          "(%d, %d), "
         2361  +          "(%d, %lld), "
         2362  +          "(%d, %lld), "
         2363  +          "(%d, %lld) ",
         2364  +          p->zStateDb,
         2365  +          OTA_STATE_STAGE, eStage,
         2366  +          OTA_STATE_TBL, p->objiter.zTbl, 
         2367  +          OTA_STATE_IDX, p->objiter.zIdx, 
         2368  +          OTA_STATE_ROW, p->nStep, 
         2369  +          OTA_STATE_PROGRESS, p->nProgress,
         2370  +          OTA_STATE_CKPT, p->iWalCksum,
         2371  +          OTA_STATE_COOKIE, (i64)p->pTargetFd->iCookie,
         2372  +          OTA_STATE_OALSZ, p->iOalSz
         2373  +      )
         2374  +    );
         2375  +    assert( pInsert==0 || rc==SQLITE_OK );
         2376  +
         2377  +    if( rc==SQLITE_OK ){
         2378  +      sqlite3_step(pInsert);
         2379  +      rc = sqlite3_finalize(pInsert);
         2380  +    }
         2381  +    if( rc!=SQLITE_OK ) p->rc = rc;
         2382  +  }
         2383  +}
         2384  +
         2385  +
         2386  +/*
         2387  +** Step the OTA object.
         2388  +*/
         2389  +int sqlite3ota_step(sqlite3ota *p){
         2390  +  if( p ){
         2391  +    switch( p->eStage ){
         2392  +      case OTA_STAGE_OAL: {
         2393  +        OtaObjIter *pIter = &p->objiter;
         2394  +        while( p->rc==SQLITE_OK && pIter->zTbl ){
         2395  +
         2396  +          if( pIter->bCleanup ){
         2397  +            /* Clean up the ota_tmp_xxx table for the previous table. It 
         2398  +            ** cannot be dropped as there are currently active SQL statements.
         2399  +            ** But the contents can be deleted.  */
         2400  +            if( pIter->abIndexed ){
         2401  +              otaMPrintfExec(p, p->dbOta, 
         2402  +                  "DELETE FROM %s.'ota_tmp_%q'", p->zStateDb, pIter->zTbl
         2403  +              );
         2404  +            }
         2405  +          }else{
         2406  +            otaObjIterPrepareAll(p, pIter, 0);
         2407  +
         2408  +            /* Advance to the next row to process. */
         2409  +            if( p->rc==SQLITE_OK ){
         2410  +              int rc = sqlite3_step(pIter->pSelect);
         2411  +              if( rc==SQLITE_ROW ){
         2412  +                p->nProgress++;
         2413  +                p->nStep++;
         2414  +                return otaStep(p);
         2415  +              }
         2416  +              p->rc = sqlite3_reset(pIter->pSelect);
         2417  +              p->nStep = 0;
         2418  +            }
         2419  +          }
         2420  +
         2421  +          otaObjIterNext(p, pIter);
         2422  +        }
         2423  +
         2424  +        if( p->rc==SQLITE_OK ){
         2425  +          assert( pIter->zTbl==0 );
         2426  +          otaSaveState(p, OTA_STAGE_MOVE);
         2427  +          otaIncrSchemaCookie(p);
         2428  +          if( p->rc==SQLITE_OK ){
         2429  +            p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
         2430  +          }
         2431  +          if( p->rc==SQLITE_OK ){
         2432  +            p->rc = sqlite3_exec(p->dbOta, "COMMIT", 0, 0, &p->zErrmsg);
         2433  +          }
         2434  +          p->eStage = OTA_STAGE_MOVE;
         2435  +        }
         2436  +        break;
         2437  +      }
         2438  +
         2439  +      case OTA_STAGE_MOVE: {
         2440  +        if( p->rc==SQLITE_OK ){
         2441  +          otaMoveOalFile(p);
         2442  +          p->nProgress++;
         2443  +        }
         2444  +        break;
         2445  +      }
         2446  +
         2447  +      case OTA_STAGE_CKPT: {
         2448  +        if( p->rc==SQLITE_OK ){
         2449  +          if( p->nStep>=p->nFrame ){
         2450  +            sqlite3_file *pDb = p->pTargetFd->pReal;
         2451  +  
         2452  +            /* Sync the db file */
         2453  +            p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
         2454  +  
         2455  +            /* Update nBackfill */
         2456  +            if( p->rc==SQLITE_OK ){
         2457  +              void volatile *ptr;
         2458  +              p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, &ptr);
         2459  +              if( p->rc==SQLITE_OK ){
         2460  +                ((u32 volatile*)ptr)[24] = p->iMaxFrame;
         2461  +              }
         2462  +            }
         2463  +  
         2464  +            if( p->rc==SQLITE_OK ){
         2465  +              p->eStage = OTA_STAGE_DONE;
         2466  +              p->rc = SQLITE_DONE;
         2467  +            }
         2468  +          }else{
         2469  +            OtaFrame *pFrame = &p->aFrame[p->nStep];
         2470  +            otaCheckpointFrame(p, pFrame);
         2471  +            p->nStep++;
         2472  +          }
         2473  +          p->nProgress++;
         2474  +        }
         2475  +        break;
         2476  +      }
         2477  +
         2478  +      default:
         2479  +        break;
         2480  +    }
         2481  +    return p->rc;
         2482  +  }else{
         2483  +    return SQLITE_NOMEM;
         2484  +  }
         2485  +}
         2486  +
         2487  +/*
         2488  +** Free an OtaState object allocated by otaLoadState().
         2489  +*/
         2490  +static void otaFreeState(OtaState *p){
         2491  +  if( p ){
         2492  +    sqlite3_free(p->zTbl);
         2493  +    sqlite3_free(p->zIdx);
         2494  +    sqlite3_free(p);
         2495  +  }
         2496  +}
         2497  +
         2498  +/*
         2499  +** Allocate an OtaState object and load the contents of the ota_state 
         2500  +** table into it. Return a pointer to the new object. It is the 
         2501  +** responsibility of the caller to eventually free the object using
         2502  +** sqlite3_free().
         2503  +**
         2504  +** If an error occurs, leave an error code and message in the ota handle
         2505  +** and return NULL.
         2506  +*/
         2507  +static OtaState *otaLoadState(sqlite3ota *p){
         2508  +  OtaState *pRet = 0;
         2509  +  sqlite3_stmt *pStmt = 0;
         2510  +  int rc;
         2511  +  int rc2;
         2512  +
         2513  +  pRet = (OtaState*)otaMalloc(p, sizeof(OtaState));
         2514  +  if( pRet==0 ) return 0;
         2515  +
         2516  +  rc = prepareFreeAndCollectError(p->dbOta, &pStmt, &p->zErrmsg, 
         2517  +      sqlite3_mprintf("SELECT k, v FROM %s.ota_state", p->zStateDb)
         2518  +  );
         2519  +  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
         2520  +    switch( sqlite3_column_int(pStmt, 0) ){
         2521  +      case OTA_STATE_STAGE:
         2522  +        pRet->eStage = sqlite3_column_int(pStmt, 1);
         2523  +        if( pRet->eStage!=OTA_STAGE_OAL
         2524  +         && pRet->eStage!=OTA_STAGE_MOVE
         2525  +         && pRet->eStage!=OTA_STAGE_CKPT
         2526  +        ){
         2527  +          p->rc = SQLITE_CORRUPT;
         2528  +        }
         2529  +        break;
         2530  +
         2531  +      case OTA_STATE_TBL:
         2532  +        pRet->zTbl = otaStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
         2533  +        break;
         2534  +
         2535  +      case OTA_STATE_IDX:
         2536  +        pRet->zIdx = otaStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
         2537  +        break;
         2538  +
         2539  +      case OTA_STATE_ROW:
         2540  +        pRet->nRow = sqlite3_column_int(pStmt, 1);
         2541  +        break;
         2542  +
         2543  +      case OTA_STATE_PROGRESS:
         2544  +        pRet->nProgress = sqlite3_column_int64(pStmt, 1);
         2545  +        break;
         2546  +
         2547  +      case OTA_STATE_CKPT:
         2548  +        pRet->iWalCksum = sqlite3_column_int64(pStmt, 1);
         2549  +        break;
         2550  +
         2551  +      case OTA_STATE_COOKIE:
         2552  +        pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
         2553  +        break;
         2554  +
         2555  +      case OTA_STATE_OALSZ:
         2556  +        pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
         2557  +        break;
         2558  +
         2559  +      default:
         2560  +        rc = SQLITE_CORRUPT;
         2561  +        break;
         2562  +    }
         2563  +  }
         2564  +  rc2 = sqlite3_finalize(pStmt);
         2565  +  if( rc==SQLITE_OK ) rc = rc2;
         2566  +
         2567  +  p->rc = rc;
         2568  +  return pRet;
         2569  +}
         2570  +
         2571  +/*
         2572  +** Compare strings z1 and z2, returning 0 if they are identical, or non-zero
         2573  +** otherwise. Either or both argument may be NULL. Two NULL values are
         2574  +** considered equal, and NULL is considered distinct from all other values.
         2575  +*/
         2576  +static int otaStrCompare(const char *z1, const char *z2){
         2577  +  if( z1==0 && z2==0 ) return 0;
         2578  +  if( z1==0 || z2==0 ) return 1;
         2579  +  return (sqlite3_stricmp(z1, z2)!=0);
         2580  +}
         2581  +
         2582  +/*
         2583  +** This function is called as part of sqlite3ota_open() when initializing
         2584  +** an ota handle in OAL stage. If the ota update has not started (i.e.
         2585  +** the ota_state table was empty) it is a no-op. Otherwise, it arranges
         2586  +** things so that the next call to sqlite3ota_step() continues on from
         2587  +** where the previous ota handle left off.
         2588  +**
         2589  +** If an error occurs, an error code and error message are left in the
         2590  +** ota handle passed as the first argument.
         2591  +*/
         2592  +static void otaSetupOal(sqlite3ota *p, OtaState *pState){
         2593  +  assert( p->rc==SQLITE_OK );
         2594  +  if( pState->zTbl ){
         2595  +    OtaObjIter *pIter = &p->objiter;
         2596  +    int rc = SQLITE_OK;
         2597  +
         2598  +    while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup 
         2599  +       || otaStrCompare(pIter->zIdx, pState->zIdx)
         2600  +       || otaStrCompare(pIter->zTbl, pState->zTbl) 
         2601  +    )){
         2602  +      rc = otaObjIterNext(p, pIter);
         2603  +    }
         2604  +
         2605  +    if( rc==SQLITE_OK && !pIter->zTbl ){
         2606  +      rc = SQLITE_ERROR;
         2607  +      p->zErrmsg = sqlite3_mprintf("ota_state mismatch error");
         2608  +    }
         2609  +
         2610  +    if( rc==SQLITE_OK ){
         2611  +      p->nStep = pState->nRow;
         2612  +      rc = otaObjIterPrepareAll(p, &p->objiter, p->nStep);
         2613  +    }
         2614  +
         2615  +    p->rc = rc;
         2616  +  }
         2617  +}
         2618  +
         2619  +/*
         2620  +** If there is a "*-oal" file in the file-system corresponding to the
         2621  +** target database in the file-system, delete it. If an error occurs,
         2622  +** leave an error code and error message in the ota handle.
         2623  +*/
         2624  +static void otaDeleteOalFile(sqlite3ota *p){
         2625  +  char *zOal = sqlite3_mprintf("%s-oal", p->zTarget);
         2626  +  assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
         2627  +  unlink(zOal);
         2628  +  sqlite3_free(zOal);
         2629  +}
         2630  +
         2631  +/*
         2632  +** Allocate a private ota VFS for the ota handle passed as the only
         2633  +** argument. This VFS will be used unless the call to sqlite3ota_open()
         2634  +** specified a URI with a vfs=? option in place of a target database
         2635  +** file name.
         2636  +*/
         2637  +static void otaCreateVfs(sqlite3ota *p){
         2638  +  int rnd;
         2639  +  char zRnd[64];
         2640  +
         2641  +  assert( p->rc==SQLITE_OK );
         2642  +  sqlite3_randomness(sizeof(int), (void*)&rnd);
         2643  +  sprintf(zRnd, "ota_vfs_%d", rnd);
         2644  +  p->rc = sqlite3ota_create_vfs(zRnd, 0);
         2645  +  if( p->rc==SQLITE_OK ){
         2646  +    sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd);
         2647  +    assert( pVfs );
         2648  +    p->zVfsName = pVfs->zName;
         2649  +  }
         2650  +}
         2651  +
         2652  +/*
         2653  +** Destroy the private VFS created for the ota handle passed as the only
         2654  +** argument by an earlier call to otaCreateVfs().
         2655  +*/
         2656  +static void otaDeleteVfs(sqlite3ota *p){
         2657  +  if( p->zVfsName ){
         2658  +    sqlite3ota_destroy_vfs(p->zVfsName);
         2659  +    p->zVfsName = 0;
         2660  +  }
         2661  +}
         2662  +
         2663  +static sqlite3ota *otaOpen(
         2664  +  const char *zTarget, 
         2665  +  const char *zOta,
         2666  +  const char *zState
         2667  +){
         2668  +  sqlite3ota *p;
         2669  +  int nTarget = strlen(zTarget);
         2670  +  int nOta = strlen(zOta);
         2671  +  int nState = zState ? strlen(zState) : 0;
         2672  +
         2673  +  p = (sqlite3ota*)sqlite3_malloc(sizeof(sqlite3ota)+nTarget+1+nOta+1+nState+1);
         2674  +  if( p ){
         2675  +    OtaState *pState = 0;
         2676  +
         2677  +    /* Create the custom VFS. */
         2678  +    memset(p, 0, sizeof(sqlite3ota));
         2679  +    otaCreateVfs(p);
         2680  +
         2681  +    /* Open the target database */
         2682  +    if( p->rc==SQLITE_OK ){
         2683  +      p->zTarget = (char*)&p[1];
         2684  +      memcpy(p->zTarget, zTarget, nTarget+1);
         2685  +      p->zOta = &p->zTarget[nTarget+1];
         2686  +      memcpy(p->zOta, zOta, nOta+1);
         2687  +      if( zState ){
         2688  +        p->zState = &p->zOta[nOta+1];
         2689  +        memcpy(p->zState, zState, nState+1);
         2690  +      }
         2691  +      otaOpenDatabase(p);
         2692  +    }
         2693  +
         2694  +    /* If it has not already been created, create the ota_state table */
         2695  +    otaMPrintfExec(p, p->dbOta, OTA_CREATE_STATE, p->zStateDb);
         2696  +
         2697  +    if( p->rc==SQLITE_OK ){
         2698  +      pState = otaLoadState(p);
         2699  +      assert( pState || p->rc!=SQLITE_OK );
         2700  +      if( p->rc==SQLITE_OK ){
         2701  +
         2702  +        if( pState->eStage==0 ){ 
         2703  +          otaDeleteOalFile(p);
         2704  +          p->eStage = OTA_STAGE_OAL;
         2705  +        }else{
         2706  +          p->eStage = pState->eStage;
         2707  +        }
         2708  +        p->nProgress = pState->nProgress;
         2709  +        p->iOalSz = pState->iOalSz;
         2710  +      }
         2711  +    }
         2712  +    assert( p->rc!=SQLITE_OK || p->eStage!=0 );
         2713  +
         2714  +    if( p->rc==SQLITE_OK && p->pTargetFd->pWalFd ){
         2715  +      if( p->eStage==OTA_STAGE_OAL ){
         2716  +        p->rc = SQLITE_ERROR;
         2717  +        p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
         2718  +      }else if( p->eStage==OTA_STAGE_MOVE ){
         2719  +        p->eStage = OTA_STAGE_CKPT;
         2720  +        p->nStep = 0;
         2721  +      }
         2722  +    }
         2723  +
         2724  +    if( p->rc==SQLITE_OK
         2725  +     && (p->eStage==OTA_STAGE_OAL || p->eStage==OTA_STAGE_MOVE)
         2726  +     && pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie
         2727  +    ){   
         2728  +      /* At this point (pTargetFd->iCookie) contains the value of the
         2729  +      ** change-counter cookie (the thing that gets incremented when a 
         2730  +      ** transaction is committed in rollback mode) currently stored on 
         2731  +      ** page 1 of the database file. */
         2732  +      p->rc = SQLITE_BUSY;
         2733  +      p->zErrmsg = sqlite3_mprintf("database modified during ota update");
         2734  +    }
         2735  +
         2736  +    if( p->rc==SQLITE_OK ){
         2737  +      if( p->eStage==OTA_STAGE_OAL ){
         2738  +
         2739  +        /* Open transactions both databases. The *-oal file is opened or
         2740  +        ** created at this point. */
         2741  +        p->rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
         2742  +        if( p->rc==SQLITE_OK ){
         2743  +          p->rc = sqlite3_exec(p->dbOta, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
         2744  +        }
         2745  +  
         2746  +        /* Point the object iterator at the first object */
         2747  +        if( p->rc==SQLITE_OK ){
         2748  +          p->rc = otaObjIterFirst(p, &p->objiter);
         2749  +        }
         2750  +
         2751  +        /* If the OTA database contains no data_xxx tables, declare the OTA
         2752  +        ** update finished.  */
         2753  +        if( p->rc==SQLITE_OK && p->objiter.zTbl==0 ){
         2754  +          p->rc = SQLITE_DONE;
         2755  +        }
         2756  +
         2757  +        if( p->rc==SQLITE_OK ){
         2758  +          otaSetupOal(p, pState);
         2759  +        }
         2760  +
         2761  +      }else if( p->eStage==OTA_STAGE_MOVE ){
         2762  +        /* no-op */
         2763  +      }else if( p->eStage==OTA_STAGE_CKPT ){
         2764  +        otaSetupCheckpoint(p, pState);
         2765  +      }else if( p->eStage==OTA_STAGE_DONE ){
         2766  +        p->rc = SQLITE_DONE;
         2767  +      }else{
         2768  +        p->rc = SQLITE_CORRUPT;
         2769  +      }
         2770  +    }
         2771  +
         2772  +    otaFreeState(pState);
         2773  +  }
         2774  +
         2775  +  return p;
         2776  +}
         2777  +
         2778  +
         2779  +/*
         2780  +** Open and return a new OTA handle. 
         2781  +*/
         2782  +sqlite3ota *sqlite3ota_open_v2(
         2783  +  const char *zDb, 
         2784  +  const char *zOta, 
         2785  +  const char *zState
         2786  +){
         2787  +  return otaOpen(zDb, zOta, zState);
         2788  +}
         2789  +
         2790  +/*
         2791  +** Open and return a new OTA handle. 
         2792  +*/
         2793  +sqlite3ota *sqlite3ota_open(
         2794  +  const char *zDb, 
         2795  +  const char *zOta 
         2796  +){
         2797  +  return otaOpen(zDb, zOta, 0);
         2798  +}
         2799  +
         2800  +/*
         2801  +** Return the database handle used by pOta.
         2802  +*/
         2803  +sqlite3 *sqlite3ota_db(sqlite3ota *pOta, int bOta){
         2804  +  sqlite3 *db = 0;
         2805  +  if( pOta ){
         2806  +    db = (bOta ? pOta->dbOta : pOta->dbMain);
         2807  +  }
         2808  +  return db;
         2809  +}
         2810  +
         2811  +
         2812  +/*
         2813  +** If the error code currently stored in the OTA handle is SQLITE_CONSTRAINT,
         2814  +** then edit any error message string so as to remove all occurrences of
         2815  +** the pattern "ota_imp_[0-9]*".
         2816  +*/
         2817  +static void otaEditErrmsg(sqlite3ota *p){
         2818  +  if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){
         2819  +    int i;
         2820  +    int nErrmsg = strlen(p->zErrmsg);
         2821  +    for(i=0; i<(nErrmsg-8); i++){
         2822  +      if( memcmp(&p->zErrmsg[i], "ota_imp_", 8)==0 ){
         2823  +        int nDel = 8;
         2824  +        while( p->zErrmsg[i+nDel]>='0' && p->zErrmsg[i+nDel]<='9' ) nDel++;
         2825  +        memmove(&p->zErrmsg[i], &p->zErrmsg[i+nDel], nErrmsg + 1 - i - nDel);
         2826  +        nErrmsg -= nDel;
         2827  +      }
         2828  +    }
         2829  +  }
         2830  +}
         2831  +
         2832  +/*
         2833  +** Close the OTA handle.
         2834  +*/
         2835  +int sqlite3ota_close(sqlite3ota *p, char **pzErrmsg){
         2836  +  int rc;
         2837  +  if( p ){
         2838  +
         2839  +    /* Commit the transaction to the *-oal file. */
         2840  +    if( p->rc==SQLITE_OK && p->eStage==OTA_STAGE_OAL ){
         2841  +      p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
         2842  +    }
         2843  +
         2844  +    otaSaveState(p, p->eStage);
         2845  +
         2846  +    if( p->rc==SQLITE_OK && p->eStage==OTA_STAGE_OAL ){
         2847  +      p->rc = sqlite3_exec(p->dbOta, "COMMIT", 0, 0, &p->zErrmsg);
         2848  +    }
         2849  +
         2850  +    /* Close any open statement handles. */
         2851  +    otaObjIterFinalize(&p->objiter);
         2852  +
         2853  +    /* Close the open database handle and VFS object. */
         2854  +    sqlite3_close(p->dbMain);
         2855  +    sqlite3_close(p->dbOta);
         2856  +    otaDeleteVfs(p);
         2857  +    sqlite3_free(p->aBuf);
         2858  +    sqlite3_free(p->aFrame);
         2859  +
         2860  +    otaEditErrmsg(p);
         2861  +    rc = p->rc;
         2862  +    *pzErrmsg = p->zErrmsg;
         2863  +    sqlite3_free(p);
         2864  +  }else{
         2865  +    rc = SQLITE_NOMEM;
         2866  +    *pzErrmsg = 0;
         2867  +  }
         2868  +  return rc;
         2869  +}
         2870  +
         2871  +/*
         2872  +** Return the total number of key-value operations (inserts, deletes or 
         2873  +** updates) that have been performed on the target database since the
         2874  +** current OTA update was started.
         2875  +*/
         2876  +sqlite3_int64 sqlite3ota_progress(sqlite3ota *pOta){
         2877  +  return pOta->nProgress;
         2878  +}
         2879  +
         2880  +/**************************************************************************
         2881  +** Beginning of OTA VFS shim methods. The VFS shim modifies the behaviour
         2882  +** of a standard VFS in the following ways:
         2883  +**
         2884  +** 1. Whenever the first page of a main database file is read or 
         2885  +**    written, the value of the change-counter cookie is stored in
         2886  +**    ota_file.iCookie. Similarly, the value of the "write-version"
         2887  +**    database header field is stored in ota_file.iWriteVer. This ensures
         2888  +**    that the values are always trustworthy within an open transaction.
         2889  +**
         2890  +** 2. Whenever an SQLITE_OPEN_WAL file is opened, the (ota_file.pWalFd)
         2891  +**    member variable of the associated database file descriptor is set
         2892  +**    to point to the new file. A mutex protected linked list of all main 
         2893  +**    db fds opened using a particular OTA VFS is maintained at 
         2894  +**    ota_vfs.pMain to facilitate this.
         2895  +**
         2896  +** 3. Using a new file-control "SQLITE_FCNTL_OTA", a main db ota_file 
         2897  +**    object can be marked as the target database of an OTA update. This
         2898  +**    turns on the following extra special behaviour:
         2899  +**
         2900  +** 3a. If xAccess() is called to check if there exists a *-wal file 
         2901  +**     associated with an OTA target database currently in OTA_STAGE_OAL
         2902  +**     stage (preparing the *-oal file), the following special handling
         2903  +**     applies:
         2904  +**
         2905  +**      * if the *-wal file does exist, return SQLITE_CANTOPEN. An OTA
         2906  +**        target database may not be in wal mode already.
         2907  +**
         2908  +**      * if the *-wal file does not exist, set the output parameter to
         2909  +**        non-zero (to tell SQLite that it does exist) anyway.
         2910  +**
         2911  +**     Then, when xOpen() is called to open the *-wal file associated with
         2912  +**     the OTA target in OTA_STAGE_OAL stage, instead of opening the *-wal
         2913  +**     file, the ota vfs opens the corresponding *-oal file instead. 
         2914  +**
         2915  +** 3b. The *-shm pages returned by xShmMap() for a target db file in
         2916  +**     OTA_STAGE_OAL mode are actually stored in heap memory. This is to
         2917  +**     avoid creating a *-shm file on disk. Additionally, xShmLock() calls
         2918  +**     are no-ops on target database files in OTA_STAGE_OAL mode. This is
         2919  +**     because assert() statements in some VFS implementations fail if 
         2920  +**     xShmLock() is called before xShmMap().
         2921  +**
         2922  +** 3c. If an EXCLUSIVE lock is attempted on a target database file in any
         2923  +**     mode except OTA_STAGE_DONE (all work completed and checkpointed), it 
         2924  +**     fails with an SQLITE_BUSY error. This is to stop OTA connections
         2925  +**     from automatically checkpointing a *-wal (or *-oal) file from within
         2926  +**     sqlite3_close().
         2927  +**
         2928  +** 3d. In OTA_STAGE_CAPTURE mode, all xRead() calls on the wal file, and
         2929  +**     all xWrite() calls on the target database file perform no IO. 
         2930  +**     Instead the frame and page numbers that would be read and written
         2931  +**     are recorded. Additionally, successful attempts to obtain exclusive
         2932  +**     xShmLock() WRITER, CHECKPOINTER and READ0 locks on the target 
         2933  +**     database file are recorded. xShmLock() calls to unlock the same
         2934  +**     locks are no-ops (so that once obtained, these locks are never
         2935  +**     relinquished). Finally, calls to xSync() on the target database
         2936  +**     file fail with SQLITE_INTERNAL errors.
         2937  +*/
         2938  +
         2939  +static void otaUnlockShm(ota_file *p){
         2940  +  if( p->pOta ){
         2941  +    int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock;
         2942  +    int i;
         2943  +    for(i=0; i<SQLITE_SHM_NLOCK;i++){
         2944  +      if( (1<<i) & p->pOta->mLock ){
         2945  +        xShmLock(p->pReal, i, 1, SQLITE_SHM_UNLOCK|SQLITE_SHM_EXCLUSIVE);
         2946  +      }
         2947  +    }
         2948  +    p->pOta->mLock = 0;
         2949  +  }
         2950  +}
         2951  +
         2952  +/*
         2953  +** Close an ota file.
         2954  +*/
         2955  +static int otaVfsClose(sqlite3_file *pFile){
         2956  +  ota_file *p = (ota_file*)pFile;
         2957  +  int rc;
         2958  +  int i;
         2959  +
         2960  +  /* Free the contents of the apShm[] array. And the array itself. */
         2961  +  for(i=0; i<p->nShm; i++){
         2962  +    sqlite3_free(p->apShm[i]);
         2963  +  }
         2964  +  sqlite3_free(p->apShm);
         2965  +  p->apShm = 0;
         2966  +  sqlite3_free(p->zDel);
         2967  +
         2968  +  if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
         2969  +    ota_file **pp;
         2970  +    sqlite3_mutex_enter(p->pOtaVfs->mutex);
         2971  +    for(pp=&p->pOtaVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
         2972  +    *pp = p->pMainNext;
         2973  +    sqlite3_mutex_leave(p->pOtaVfs->mutex);
         2974  +    otaUnlockShm(p);
         2975  +    p->pReal->pMethods->xShmUnmap(p->pReal, 0);
         2976  +  }
         2977  +
         2978  +  /* Close the underlying file handle */
         2979  +  rc = p->pReal->pMethods->xClose(p->pReal);
         2980  +  return rc;
         2981  +}
         2982  +
         2983  +
         2984  +/*
         2985  +** Read and return an unsigned 32-bit big-endian integer from the buffer 
         2986  +** passed as the only argument.
         2987  +*/
         2988  +static u32 otaGetU32(u8 *aBuf){
         2989  +  return ((u32)aBuf[0] << 24)
         2990  +       + ((u32)aBuf[1] << 16)
         2991  +       + ((u32)aBuf[2] <<  8)
         2992  +       + ((u32)aBuf[3]);
         2993  +}
         2994  +
         2995  +/*
         2996  +** Read data from an otaVfs-file.
         2997  +*/
         2998  +static int otaVfsRead(
         2999  +  sqlite3_file *pFile, 
         3000  +  void *zBuf, 
         3001  +  int iAmt, 
         3002  +  sqlite_int64 iOfst
         3003  +){
         3004  +  ota_file *p = (ota_file*)pFile;
         3005  +  sqlite3ota *pOta = p->pOta;
         3006  +  int rc;
         3007  +
         3008  +  if( pOta && pOta->eStage==OTA_STAGE_CAPTURE ){
         3009  +    assert( p->openFlags & SQLITE_OPEN_WAL );
         3010  +    rc = otaCaptureWalRead(p->pOta, iOfst, iAmt);
         3011  +  }else{
         3012  +    if( pOta && pOta->eStage==OTA_STAGE_OAL 
         3013  +     && (p->openFlags & SQLITE_OPEN_WAL) 
         3014  +     && iOfst>=pOta->iOalSz 
         3015  +    ){
         3016  +      rc = SQLITE_OK;
         3017  +      memset(zBuf, 0, iAmt);
         3018  +    }else{
         3019  +      rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
         3020  +    }
         3021  +    if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
         3022  +      /* These look like magic numbers. But they are stable, as they are part
         3023  +       ** of the definition of the SQLite file format, which may not change. */
         3024  +      u8 *pBuf = (u8*)zBuf;
         3025  +      p->iCookie = otaGetU32(&pBuf[24]);
         3026  +      p->iWriteVer = pBuf[19];
         3027  +    }
         3028  +  }
         3029  +  return rc;
         3030  +}
         3031  +
         3032  +/*
         3033  +** Write data to an otaVfs-file.
         3034  +*/
         3035  +static int otaVfsWrite(
         3036  +  sqlite3_file *pFile, 
         3037  +  const void *zBuf, 
         3038  +  int iAmt, 
         3039  +  sqlite_int64 iOfst
         3040  +){
         3041  +  ota_file *p = (ota_file*)pFile;
         3042  +  sqlite3ota *pOta = p->pOta;
         3043  +  int rc;
         3044  +
         3045  +  if( pOta && pOta->eStage==OTA_STAGE_CAPTURE ){
         3046  +    assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
         3047  +    rc = otaCaptureDbWrite(p->pOta, iOfst);
         3048  +  }else{
         3049  +    if( pOta && pOta->eStage==OTA_STAGE_OAL 
         3050  +     && (p->openFlags & SQLITE_OPEN_WAL) 
         3051  +     && iOfst>=pOta->iOalSz
         3052  +    ){
         3053  +      pOta->iOalSz = iAmt + iOfst;
         3054  +    }
         3055  +    rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
         3056  +    if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
         3057  +      /* These look like magic numbers. But they are stable, as they are part
         3058  +      ** of the definition of the SQLite file format, which may not change. */
         3059  +      u8 *pBuf = (u8*)zBuf;
         3060  +      p->iCookie = otaGetU32(&pBuf[24]);
         3061  +      p->iWriteVer = pBuf[19];
         3062  +    }
         3063  +  }
         3064  +  return rc;
         3065  +}
         3066  +
         3067  +/*
         3068  +** Truncate an otaVfs-file.
         3069  +*/
         3070  +static int otaVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
         3071  +  ota_file *p = (ota_file*)pFile;
         3072  +  return p->pReal->pMethods->xTruncate(p->pReal, size);
         3073  +}
         3074  +
         3075  +/*
         3076  +** Sync an otaVfs-file.
         3077  +*/
         3078  +static int otaVfsSync(sqlite3_file *pFile, int flags){
         3079  +  ota_file *p = (ota_file *)pFile;
         3080  +  if( p->pOta && p->pOta->eStage==OTA_STAGE_CAPTURE ){
         3081  +    if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
         3082  +      return SQLITE_INTERNAL;
         3083  +    }
         3084  +    return SQLITE_OK;
         3085  +  }
         3086  +  return p->pReal->pMethods->xSync(p->pReal, flags);
         3087  +}
         3088  +
         3089  +/*
         3090  +** Return the current file-size of an otaVfs-file.
         3091  +*/
         3092  +static int otaVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
         3093  +  ota_file *p = (ota_file *)pFile;
         3094  +  return p->pReal->pMethods->xFileSize(p->pReal, pSize);
         3095  +}
         3096  +
         3097  +/*
         3098  +** Lock an otaVfs-file.
         3099  +*/
         3100  +static int otaVfsLock(sqlite3_file *pFile, int eLock){
         3101  +  ota_file *p = (ota_file*)pFile;
         3102  +  sqlite3ota *pOta = p->pOta;
         3103  +  int rc = SQLITE_OK;
         3104  +
         3105  +  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
         3106  +  if( pOta && eLock==SQLITE_LOCK_EXCLUSIVE && pOta->eStage!=OTA_STAGE_DONE ){
         3107  +    /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this 
         3108  +    ** prevents it from checkpointing the database from sqlite3_close(). */
         3109  +    rc = SQLITE_BUSY;
         3110  +  }else{
         3111  +    rc = p->pReal->pMethods->xLock(p->pReal, eLock);
         3112  +  }
         3113  +
         3114  +  return rc;
         3115  +}
         3116  +
         3117  +/*
         3118  +** Unlock an otaVfs-file.
         3119  +*/
         3120  +static int otaVfsUnlock(sqlite3_file *pFile, int eLock){
         3121  +  ota_file *p = (ota_file *)pFile;
         3122  +  return p->pReal->pMethods->xUnlock(p->pReal, eLock);
         3123  +}
         3124  +
         3125  +/*
         3126  +** Check if another file-handle holds a RESERVED lock on an otaVfs-file.
         3127  +*/
         3128  +static int otaVfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
         3129  +  ota_file *p = (ota_file *)pFile;
         3130  +  return p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
         3131  +}
         3132  +
         3133  +/*
         3134  +** File control method. For custom operations on an otaVfs-file.
         3135  +*/
         3136  +static int otaVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
         3137  +  ota_file *p = (ota_file *)pFile;
         3138  +  int (*xControl)(sqlite3_file*,int,void*) = p->pReal->pMethods->xFileControl;
         3139  +  int rc;
         3140  +
         3141  +  assert( p->openFlags & 
         3142  +      (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB|SQLITE_OPEN_TRANSIENT_DB) 
         3143  +  );
         3144  +  if( op==SQLITE_FCNTL_OTA ){
         3145  +    sqlite3ota *pOta = (sqlite3ota*)pArg;
         3146  +
         3147  +    /* First try to find another OTA vfs lower down in the vfs stack. If
         3148  +    ** one is found, this vfs will operate in pass-through mode. The lower
         3149  +    ** level vfs will do the special OTA handling.  */
         3150  +    rc = xControl(p->pReal, op, pArg);
         3151  +
         3152  +    if( rc==SQLITE_NOTFOUND ){
         3153  +      /* Now search for a zipvfs instance lower down in the VFS stack. If
         3154  +      ** one is found, this is an error.  */
         3155  +      void *dummy = 0;
         3156  +      rc = xControl(p->pReal, SQLITE_FCNTL_ZIPVFS, &dummy);
         3157  +      if( rc==SQLITE_OK ){
         3158  +        rc = SQLITE_ERROR;
         3159  +        pOta->zErrmsg = sqlite3_mprintf("ota/zipvfs setup error");
         3160  +      }else if( rc==SQLITE_NOTFOUND ){
         3161  +        pOta->pTargetFd = p;
         3162  +        p->pOta = pOta;
         3163  +        if( p->pWalFd ) p->pWalFd->pOta = pOta;
         3164  +        rc = SQLITE_OK;
         3165  +      }
         3166  +    }
         3167  +    return rc;
         3168  +  }
         3169  +
         3170  +  rc = xControl(p->pReal, op, pArg);
         3171  +  if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
         3172  +    ota_vfs *pOtaVfs = p->pOtaVfs;
         3173  +    char *zIn = *(char**)pArg;
         3174  +    char *zOut = sqlite3_mprintf("ota(%s)/%z", pOtaVfs->base.zName, zIn);
         3175  +    *(char**)pArg = zOut;
         3176  +    if( zOut==0 ) rc = SQLITE_NOMEM;
         3177  +  }
         3178  +
         3179  +  return rc;
         3180  +}
         3181  +
         3182  +/*
         3183  +** Return the sector-size in bytes for an otaVfs-file.
         3184  +*/
         3185  +static int otaVfsSectorSize(sqlite3_file *pFile){
         3186  +  ota_file *p = (ota_file *)pFile;
         3187  +  return p->pReal->pMethods->xSectorSize(p->pReal);
         3188  +}
         3189  +
         3190  +/*
         3191  +** Return the device characteristic flags supported by an otaVfs-file.
         3192  +*/
         3193  +static int otaVfsDeviceCharacteristics(sqlite3_file *pFile){
         3194  +  ota_file *p = (ota_file *)pFile;
         3195  +  return p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
         3196  +}
         3197  +
         3198  +/*
         3199  +** Take or release a shared-memory lock.
         3200  +*/
         3201  +static int otaVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
         3202  +  ota_file *p = (ota_file*)pFile;
         3203  +  sqlite3ota *pOta = p->pOta;
         3204  +  int rc = SQLITE_OK;
         3205  +
         3206  +#ifdef SQLITE_AMALGAMATION
         3207  +    assert( WAL_CKPT_LOCK==1 );
         3208  +#endif
         3209  +
         3210  +  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
         3211  +  if( pOta && (pOta->eStage==OTA_STAGE_OAL || pOta->eStage==OTA_STAGE_MOVE) ){
         3212  +    /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from
         3213  +    ** taking this lock also prevents any checkpoints from occurring. 
         3214  +    ** todo: really, it's not clear why this might occur, as 
         3215  +    ** wal_autocheckpoint ought to be turned off.  */
         3216  +    if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
         3217  +  }else{
         3218  +    int bCapture = 0;
         3219  +    if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
         3220  +     && pOta && pOta->eStage==OTA_STAGE_CAPTURE
         3221  +     && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
         3222  +    ){
         3223  +      bCapture = 1;
         3224  +    }
         3225  +
         3226  +    if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){
         3227  +      rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
         3228  +      if( bCapture && rc==SQLITE_OK ){
         3229  +        pOta->mLock |= (1 << ofst);
         3230  +      }
         3231  +    }
         3232  +  }
         3233  +
         3234  +  return rc;
         3235  +}
         3236  +
         3237  +/*
         3238  +** Obtain a pointer to a mapping of a single 32KiB page of the *-shm file.
         3239  +*/
         3240  +static int otaVfsShmMap(
         3241  +  sqlite3_file *pFile, 
         3242  +  int iRegion, 
         3243  +  int szRegion, 
         3244  +  int isWrite, 
         3245  +  void volatile **pp
         3246  +){
         3247  +  ota_file *p = (ota_file*)pFile;
         3248  +  int rc = SQLITE_OK;
         3249  +  int eStage = (p->pOta ? p->pOta->eStage : 0);
         3250  +
         3251  +  /* If not in OTA_STAGE_OAL, allow this call to pass through. Or, if this
         3252  +  ** ota is in the OTA_STAGE_OAL state, use heap memory for *-shm space 
         3253  +  ** instead of a file on disk.  */
         3254  +  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
         3255  +  if( eStage==OTA_STAGE_OAL || eStage==OTA_STAGE_MOVE ){
         3256  +    if( iRegion<=p->nShm ){
         3257  +      int nByte = (iRegion+1) * sizeof(char*);
         3258  +      char **apNew = (char**)sqlite3_realloc(p->apShm, nByte);
         3259  +      if( apNew==0 ){
         3260  +        rc = SQLITE_NOMEM;
         3261  +      }else{
         3262  +        memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
         3263  +        p->apShm = apNew;
         3264  +        p->nShm = iRegion+1;
         3265  +      }
         3266  +    }
         3267  +
         3268  +    if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
         3269  +      char *pNew = (char*)sqlite3_malloc(szRegion);
         3270  +      if( pNew==0 ){
         3271  +        rc = SQLITE_NOMEM;
         3272  +      }else{
         3273  +        memset(pNew, 0, szRegion);
         3274  +        p->apShm[iRegion] = pNew;
         3275  +      }
         3276  +    }
         3277  +
         3278  +    if( rc==SQLITE_OK ){
         3279  +      *pp = p->apShm[iRegion];
         3280  +    }else{
         3281  +      *pp = 0;
         3282  +    }
         3283  +  }else{
         3284  +    assert( p->apShm==0 );
         3285  +    rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
         3286  +  }
         3287  +
         3288  +  return rc;
         3289  +}
         3290  +
         3291  +/*
         3292  +** Memory barrier.
         3293  +*/
         3294  +static void otaVfsShmBarrier(sqlite3_file *pFile){
         3295  +  ota_file *p = (ota_file *)pFile;
         3296  +  p->pReal->pMethods->xShmBarrier(p->pReal);
         3297  +}
         3298  +
         3299  +/*
         3300  +** The xShmUnmap method.
         3301  +*/
         3302  +static int otaVfsShmUnmap(sqlite3_file *pFile, int delFlag){
         3303  +  ota_file *p = (ota_file*)pFile;
         3304  +  int rc = SQLITE_OK;
         3305  +  int eStage = (p->pOta ? p->pOta->eStage : 0);
         3306  +
         3307  +  assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
         3308  +  if( eStage==OTA_STAGE_OAL || eStage==OTA_STAGE_MOVE ){
         3309  +    /* no-op */
         3310  +  }else{
         3311  +    /* Release the checkpointer and writer locks */
         3312  +    otaUnlockShm(p);
         3313  +    rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
         3314  +  }
         3315  +  return rc;
         3316  +}
         3317  +
         3318  +/*
         3319  +** Given that zWal points to a buffer containing a wal file name passed to 
         3320  +** either the xOpen() or xAccess() VFS method, return a pointer to the
         3321  +** file-handle opened by the same database connection on the corresponding
         3322  +** database file.
         3323  +*/
         3324  +static ota_file *otaFindMaindb(ota_vfs *pOtaVfs, const char *zWal){
         3325  +  ota_file *pDb;
         3326  +  sqlite3_mutex_enter(pOtaVfs->mutex);
         3327  +  for(pDb=pOtaVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext);
         3328  +  sqlite3_mutex_leave(pOtaVfs->mutex);
         3329  +  return pDb;
         3330  +}
         3331  +
         3332  +/*
         3333  +** Open an ota file handle.
         3334  +*/
         3335  +static int otaVfsOpen(
         3336  +  sqlite3_vfs *pVfs,
         3337  +  const char *zName,
         3338  +  sqlite3_file *pFile,
         3339  +  int flags,
         3340  +  int *pOutFlags
         3341  +){
         3342  +  static sqlite3_io_methods otavfs_io_methods = {
         3343  +    2,                            /* iVersion */
         3344  +    otaVfsClose,                  /* xClose */
         3345  +    otaVfsRead,                   /* xRead */
         3346  +    otaVfsWrite,                  /* xWrite */
         3347  +    otaVfsTruncate,               /* xTruncate */
         3348  +    otaVfsSync,                   /* xSync */
         3349  +    otaVfsFileSize,               /* xFileSize */
         3350  +    otaVfsLock,                   /* xLock */
         3351  +    otaVfsUnlock,                 /* xUnlock */
         3352  +    otaVfsCheckReservedLock,      /* xCheckReservedLock */
         3353  +    otaVfsFileControl,            /* xFileControl */
         3354  +    otaVfsSectorSize,             /* xSectorSize */
         3355  +    otaVfsDeviceCharacteristics,  /* xDeviceCharacteristics */
         3356  +    otaVfsShmMap,                 /* xShmMap */
         3357  +    otaVfsShmLock,                /* xShmLock */
         3358  +    otaVfsShmBarrier,             /* xShmBarrier */
         3359  +    otaVfsShmUnmap                /* xShmUnmap */
         3360  +  };
         3361  +  ota_vfs *pOtaVfs = (ota_vfs*)pVfs;
         3362  +  sqlite3_vfs *pRealVfs = pOtaVfs->pRealVfs;
         3363  +  ota_file *pFd = (ota_file *)pFile;
         3364  +  int rc = SQLITE_OK;
         3365  +  const char *zOpen = zName;
         3366  +
         3367  +  memset(pFd, 0, sizeof(ota_file));
         3368  +  pFd->pReal = (sqlite3_file*)&pFd[1];
         3369  +  pFd->pOtaVfs = pOtaVfs;
         3370  +  pFd->openFlags = flags;
         3371  +  if( zName ){
         3372  +    if( flags & SQLITE_OPEN_MAIN_DB ){
         3373  +      /* A main database has just been opened. The following block sets
         3374  +      ** (pFd->zWal) to point to a buffer owned by SQLite that contains
         3375  +      ** the name of the *-wal file this db connection will use. SQLite
         3376  +      ** happens to pass a pointer to this buffer when using xAccess()
         3377  +      ** or xOpen() to operate on the *-wal file.  */
         3378  +      int n = strlen(zName);
         3379  +      const char *z = &zName[n];
         3380  +      if( flags & SQLITE_OPEN_URI ){
         3381  +        int odd = 0;
         3382  +        while( 1 ){
         3383  +          if( z[0]==0 ){
         3384  +            odd = 1 - odd;
         3385  +            if( odd && z[1]==0 ) break;
         3386  +          }
         3387  +          z++;
         3388  +        }
         3389  +        z += 2;
         3390  +      }else{
         3391  +        while( *z==0 ) z++;
         3392  +      }
         3393  +      z += (n + 8 + 1);
         3394  +      pFd->zWal = z;
         3395  +    }
         3396  +    else if( flags & SQLITE_OPEN_WAL ){
         3397  +      ota_file *pDb = otaFindMaindb(pOtaVfs, zName);
         3398  +      if( pDb ){
         3399  +        if( pDb->pOta && pDb->pOta->eStage==OTA_STAGE_OAL ){
         3400  +          /* This call is to open a *-wal file. Intead, open the *-oal. This
         3401  +          ** code ensures that the string passed to xOpen() is terminated by a
         3402  +          ** pair of '\0' bytes in case the VFS attempts to extract a URI 
         3403  +          ** parameter from it.  */
         3404  +          int nCopy = strlen(zName);
         3405  +          char *zCopy = sqlite3_malloc(nCopy+2);
         3406  +          if( zCopy ){
         3407  +            memcpy(zCopy, zName, nCopy);
         3408  +            zCopy[nCopy-3] = 'o';
         3409  +            zCopy[nCopy] = '\0';
         3410  +            zCopy[nCopy+1] = '\0';
         3411  +            zOpen = (const char*)(pFd->zDel = zCopy);
         3412  +          }else{
         3413  +            rc = SQLITE_NOMEM;
         3414  +          }
         3415  +          pFd->pOta = pDb->pOta;
         3416  +        }
         3417  +        pDb->pWalFd = pFd;
         3418  +      }
         3419  +    }
         3420  +  }
         3421  +
         3422  +  if( rc==SQLITE_OK ){
         3423  +    rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, flags, pOutFlags);
         3424  +  }
         3425  +  if( pFd->pReal->pMethods ){
         3426  +    /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
         3427  +    ** pointer and, if the file is a main database file, link it into the
         3428  +    ** mutex protected linked list of all such files.  */
         3429  +    pFile->pMethods = &otavfs_io_methods;
         3430  +    if( flags & SQLITE_OPEN_MAIN_DB ){
         3431  +      sqlite3_mutex_enter(pOtaVfs->mutex);
         3432  +      pFd->pMainNext = pOtaVfs->pMain;
         3433  +      pOtaVfs->pMain = pFd;
         3434  +      sqlite3_mutex_leave(pOtaVfs->mutex);
         3435  +    }
         3436  +  }else{
         3437  +    sqlite3_free(pFd->zDel);
         3438  +  }
         3439  +
         3440  +  return rc;
         3441  +}
         3442  +
         3443  +/*
         3444  +** Delete the file located at zPath.
         3445  +*/
         3446  +static int otaVfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
         3447  +  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
         3448  +  return pRealVfs->xDelete(pRealVfs, zPath, dirSync);
         3449  +}
         3450  +
         3451  +/*
         3452  +** Test for access permissions. Return true if the requested permission
         3453  +** is available, or false otherwise.
         3454  +*/
         3455  +static int otaVfsAccess(
         3456  +  sqlite3_vfs *pVfs, 
         3457  +  const char *zPath, 
         3458  +  int flags, 
         3459  +  int *pResOut
         3460  +){
         3461  +  ota_vfs *pOtaVfs = (ota_vfs*)pVfs;
         3462  +  sqlite3_vfs *pRealVfs = pOtaVfs->pRealVfs;
         3463  +  int rc;
         3464  +
         3465  +  rc = pRealVfs->xAccess(pRealVfs, zPath, flags, pResOut);
         3466  +
         3467  +  /* If this call is to check if a *-wal file associated with an OTA target
         3468  +  ** database connection exists, and the OTA update is in OTA_STAGE_OAL,
         3469  +  ** the following special handling is activated:
         3470  +  **
         3471  +  **   a) if the *-wal file does exist, return SQLITE_CANTOPEN. This
         3472  +  **      ensures that the OTA extension never tries to update a database
         3473  +  **      in wal mode, even if the first page of the database file has
         3474  +  **      been damaged. 
         3475  +  **
         3476  +  **   b) if the *-wal file does not exist, claim that it does anyway,
         3477  +  **      causing SQLite to call xOpen() to open it. This call will also
         3478  +  **      be intercepted (see the otaVfsOpen() function) and the *-oal
         3479  +  **      file opened instead.
         3480  +  */
         3481  +  if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
         3482  +    ota_file *pDb = otaFindMaindb(pOtaVfs, zPath);
         3483  +    if( pDb && pDb->pOta && pDb->pOta->eStage==OTA_STAGE_OAL ){
         3484  +      if( *pResOut ){
         3485  +        rc = SQLITE_CANTOPEN;
         3486  +      }else{
         3487  +        *pResOut = 1;
         3488  +      }
         3489  +    }
         3490  +  }
         3491  +
         3492  +  return rc;
         3493  +}
         3494  +
         3495  +/*
         3496  +** Populate buffer zOut with the full canonical pathname corresponding
         3497  +** to the pathname in zPath. zOut is guaranteed to point to a buffer
         3498  +** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
         3499  +*/
         3500  +static int otaVfsFullPathname(
         3501  +  sqlite3_vfs *pVfs, 
         3502  +  const char *zPath, 
         3503  +  int nOut, 
         3504  +  char *zOut
         3505  +){
         3506  +  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
         3507  +  return pRealVfs->xFullPathname(pRealVfs, zPath, nOut, zOut);
         3508  +}
         3509  +
         3510  +#ifndef SQLITE_OMIT_LOAD_EXTENSION
         3511  +/*
         3512  +** Open the dynamic library located at zPath and return a handle.
         3513  +*/
         3514  +static void *otaVfsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
         3515  +  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
         3516  +  return pRealVfs->xDlOpen(pRealVfs, zPath);
         3517  +}
         3518  +
         3519  +/*
         3520  +** Populate the buffer zErrMsg (size nByte bytes) with a human readable
         3521  +** utf-8 string describing the most recent error encountered associated 
         3522  +** with dynamic libraries.
         3523  +*/
         3524  +static void otaVfsDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
         3525  +  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
         3526  +  pRealVfs->xDlError(pRealVfs, nByte, zErrMsg);
         3527  +}
         3528  +
         3529  +/*
         3530  +** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
         3531  +*/
         3532  +static void (*otaVfsDlSym(
         3533  +  sqlite3_vfs *pVfs, 
         3534  +  void *pArg, 
         3535  +  const char *zSym
         3536  +))(void){
         3537  +  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
         3538  +  return pRealVfs->xDlSym(pRealVfs, pArg, zSym);
         3539  +}
         3540  +
         3541  +/*
         3542  +** Close the dynamic library handle pHandle.
         3543  +*/
         3544  +static void otaVfsDlClose(sqlite3_vfs *pVfs, void *pHandle){
         3545  +  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
         3546  +  return pRealVfs->xDlClose(pRealVfs, pHandle);
         3547  +}
         3548  +#endif /* SQLITE_OMIT_LOAD_EXTENSION */
         3549  +
         3550  +/*
         3551  +** Populate the buffer pointed to by zBufOut with nByte bytes of 
         3552  +** random data.
         3553  +*/
         3554  +static int otaVfsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
         3555  +  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
         3556  +  return pRealVfs->xRandomness(pRealVfs, nByte, zBufOut);
         3557  +}
         3558  +
         3559  +/*
         3560  +** Sleep for nMicro microseconds. Return the number of microseconds 
         3561  +** actually slept.
         3562  +*/
         3563  +static int otaVfsSleep(sqlite3_vfs *pVfs, int nMicro){
         3564  +  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
         3565  +  return pRealVfs->xSleep(pRealVfs, nMicro);
         3566  +}
         3567  +
         3568  +/*
         3569  +** Return the current time as a Julian Day number in *pTimeOut.
         3570  +*/
         3571  +static int otaVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
         3572  +  sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
         3573  +  return pRealVfs->xCurrentTime(pRealVfs, pTimeOut);
         3574  +}
         3575  +
         3576  +/*
         3577  +** No-op.
         3578  +*/
         3579  +static int otaVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
         3580  +  return 0;
         3581  +}
         3582  +
         3583  +/*
         3584  +** Deregister and destroy an OTA vfs created by an earlier call to
         3585  +** sqlite3ota_create_vfs().
         3586  +*/
         3587  +void sqlite3ota_destroy_vfs(const char *zName){
         3588  +  sqlite3_vfs *pVfs = sqlite3_vfs_find(zName);
         3589  +  if( pVfs && pVfs->xOpen==otaVfsOpen ){
         3590  +    sqlite3_mutex_free(((ota_vfs*)pVfs)->mutex);
         3591  +    sqlite3_vfs_unregister(pVfs);
         3592  +    sqlite3_free(pVfs);
         3593  +  }
         3594  +}
         3595  +
         3596  +/*
         3597  +** Create an OTA VFS named zName that accesses the underlying file-system
         3598  +** via existing VFS zParent. The new object is registered as a non-default
         3599  +** VFS with SQLite before returning.
         3600  +*/
         3601  +int sqlite3ota_create_vfs(const char *zName, const char *zParent){
         3602  +
         3603  +  /* Template for VFS */
         3604  +  static sqlite3_vfs vfs_template = {
         3605  +    1,                            /* iVersion */
         3606  +    0,                            /* szOsFile */
         3607  +    0,                            /* mxPathname */
         3608  +    0,                            /* pNext */
         3609  +    0,                            /* zName */
         3610  +    0,                            /* pAppData */
         3611  +    otaVfsOpen,                   /* xOpen */
         3612  +    otaVfsDelete,                 /* xDelete */
         3613  +    otaVfsAccess,                 /* xAccess */
         3614  +    otaVfsFullPathname,           /* xFullPathname */
         3615  +
         3616  +#ifndef SQLITE_OMIT_LOAD_EXTENSION
         3617  +    otaVfsDlOpen,                 /* xDlOpen */
         3618  +    otaVfsDlError,                /* xDlError */
         3619  +    otaVfsDlSym,                  /* xDlSym */
         3620  +    otaVfsDlClose,                /* xDlClose */
         3621  +#else
         3622  +    0, 0, 0, 0,
         3623  +#endif
         3624  +
         3625  +    otaVfsRandomness,             /* xRandomness */
         3626  +    otaVfsSleep,                  /* xSleep */
         3627  +    otaVfsCurrentTime,            /* xCurrentTime */
         3628  +    otaVfsGetLastError,           /* xGetLastError */
         3629  +    0,                            /* xCurrentTimeInt64 (version 2) */
         3630  +    0, 0, 0                       /* Unimplemented version 3 methods */
         3631  +  };
         3632  +
         3633  +  ota_vfs *pNew = 0;              /* Newly allocated VFS */
         3634  +  int nName;
         3635  +  int rc = SQLITE_OK;
         3636  +
         3637  +  int nByte;
         3638  +  nName = strlen(zName);
         3639  +  nByte = sizeof(ota_vfs) + nName + 1;
         3640  +  pNew = (ota_vfs*)sqlite3_malloc(nByte);
         3641  +  if( pNew==0 ){
         3642  +    rc = SQLITE_NOMEM;
         3643  +  }else{
         3644  +    sqlite3_vfs *pParent;           /* Parent VFS */
         3645  +    memset(pNew, 0, nByte);
         3646  +    pParent = sqlite3_vfs_find(zParent);
         3647  +    if( pParent==0 ){
         3648  +      rc = SQLITE_NOTFOUND;
         3649  +    }else{
         3650  +      char *zSpace;
         3651  +      memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs));
         3652  +      pNew->base.mxPathname = pParent->mxPathname;
         3653  +      pNew->base.szOsFile = sizeof(ota_file) + pParent->szOsFile;
         3654  +      pNew->pRealVfs = pParent;
         3655  +      pNew->base.zName = (const char*)(zSpace = (char*)&pNew[1]);
         3656  +      memcpy(zSpace, zName, nName);
         3657  +
         3658  +      /* Allocate the mutex and register the new VFS (not as the default) */
         3659  +      pNew->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE);
         3660  +      if( pNew->mutex==0 ){
         3661  +        rc = SQLITE_NOMEM;
         3662  +      }else{
         3663  +        rc = sqlite3_vfs_register(&pNew->base, 0);
         3664  +      }
         3665  +    }
         3666  +
         3667  +    if( rc!=SQLITE_OK ){
         3668  +      sqlite3_mutex_free(pNew->mutex);
         3669  +      sqlite3_free(pNew);
         3670  +    }
         3671  +  }
         3672  +
         3673  +  return rc;
         3674  +}
         3675  +
         3676  +
         3677  +/**************************************************************************/
         3678  +
         3679  +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_OTA) */

Added ext/ota/sqlite3ota.h.

            1  +/*
            2  +** 2014 August 30
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +** This file contains the public interface for the OTA extension. 
           14  +*/
           15  +
           16  +/*
           17  +** SUMMARY
           18  +**
           19  +** Writing a transaction containing a large number of operations on 
           20  +** b-tree indexes that are collectively larger than the available cache
           21  +** memory can be very inefficient. 
           22  +**
           23  +** The problem is that in order to update a b-tree, the leaf page (at least)
           24  +** containing the entry being inserted or deleted must be modified. If the
           25  +** working set of leaves is larger than the available cache memory, then a 
           26  +** single leaf that is modified more than once as part of the transaction 
           27  +** may be loaded from or written to the persistent media multiple times.
           28  +** Additionally, because the index updates are likely to be applied in
           29  +** random order, access to pages within the database is also likely to be in 
           30  +** random order, which is itself quite inefficient.
           31  +**
           32  +** One way to improve the situation is to sort the operations on each index
           33  +** by index key before applying them to the b-tree. This leads to an IO
           34  +** pattern that resembles a single linear scan through the index b-tree,
           35  +** and all but guarantees each modified leaf page is loaded and stored 
           36  +** exactly once. SQLite uses this trick to improve the performance of
           37  +** CREATE INDEX commands. This extension allows it to be used to improve
           38  +** the performance of large transactions on existing databases.
           39  +**
           40  +** Additionally, this extension allows the work involved in writing the 
           41  +** large transaction to be broken down into sub-transactions performed 
           42  +** sequentially by separate processes. This is useful if the system cannot 
           43  +** guarantee that a single update process will run for long enough to apply 
           44  +** the entire update, for example because the update is being applied on a 
           45  +** mobile device that is frequently rebooted. Even after the writer process 
           46  +** has committed one or more sub-transactions, other database clients continue
           47  +** to read from the original database snapshot. In other words, partially 
           48  +** applied transactions are not visible to other clients. 
           49  +**
           50  +** "OTA" stands for "Over The Air" update. As in a large database update
           51  +** transmitted via a wireless network to a mobile device. A transaction
           52  +** applied using this extension is hence refered to as an "OTA update".
           53  +**
           54  +**
           55  +** LIMITATIONS
           56  +**
           57  +** An "OTA update" transaction is subject to the following limitations:
           58  +**
           59  +**   * The transaction must consist of INSERT, UPDATE and DELETE operations
           60  +**     only.
           61  +**
           62  +**   * INSERT statements may not use any default values.
           63  +**
           64  +**   * UPDATE and DELETE statements must identify their target rows by 
           65  +**     non-NULL PRIMARY KEY values. Rows with NULL values stored in PRIMARY
           66  +**     KEY fields may not be updated or deleted. If the table being written 
           67  +**     has no PRIMARY KEY, affected rows must be identified by rowid.
           68  +**
           69  +**   * UPDATE statements may not modify PRIMARY KEY columns.
           70  +**
           71  +**   * No triggers will be fired.
           72  +**
           73  +**   * No foreign key violations are detected or reported.
           74  +**
           75  +**   * CHECK constraints are not enforced.
           76  +**
           77  +**   * No constraint handling mode except for "OR ROLLBACK" is supported.
           78  +**
           79  +**
           80  +** PREPARATION
           81  +**
           82  +** An "OTA update" is stored as a separate SQLite database. A database
           83  +** containing an OTA update is an "OTA database". For each table in the 
           84  +** target database to be updated, the OTA database should contain a table
           85  +** named "data_<target name>" containing the same set of columns as the
           86  +** target table, and one more - "ota_control". The data_% table should 
           87  +** have no PRIMARY KEY or UNIQUE constraints, but each column should have
           88  +** the same type as the corresponding column in the target database.
           89  +** The "ota_control" column should have no type at all. For example, if
           90  +** the target database contains:
           91  +**
           92  +**   CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c UNIQUE);
           93  +**
           94  +** Then the OTA database should contain:
           95  +**
           96  +**   CREATE TABLE data_t1(a INTEGER, b TEXT, c, ota_control);
           97  +**
           98  +** The order of the columns in the data_% table does not matter.
           99  +**
          100  +** If the target database table is a virtual table or a table that has no
          101  +** PRIMARY KEY declaration, the data_% table must also contain a column 
          102  +** named "ota_rowid". This column is mapped to the tables implicit primary 
          103  +** key column - "rowid". Virtual tables for which the "rowid" column does 
          104  +** not function like a primary key value cannot be updated using OTA. For 
          105  +** example, if the target db contains either of the following:
          106  +**
          107  +**   CREATE VIRTUAL TABLE x1 USING fts3(a, b);
          108  +**   CREATE TABLE x1(a, b)
          109  +**
          110  +** then the OTA database should contain:
          111  +**
          112  +**   CREATE TABLE data_x1(a, b, ota_rowid, ota_control);
          113  +**
          114  +** All non-hidden columns (i.e. all columns matched by "SELECT *") of the
          115  +** target table must be present in the input table. For virtual tables,
          116  +** hidden columns are optional - they are updated by OTA if present in
          117  +** the input table, or not otherwise. For example, to write to an fts4
          118  +** table with a hidden languageid column such as:
          119  +**
          120  +**   CREATE VIRTUAL TABLE ft1 USING fts4(a, b, languageid='langid');
          121  +**
          122  +** Either of the following input table schemas may be used:
          123  +**
          124  +**   CREATE TABLE data_ft1(a, b, langid, ota_rowid, ota_control);
          125  +**   CREATE TABLE data_ft1(a, b, ota_rowid, ota_control);
          126  +**
          127  +** For each row to INSERT into the target database as part of the OTA 
          128  +** update, the corresponding data_% table should contain a single record
          129  +** with the "ota_control" column set to contain integer value 0. The
          130  +** other columns should be set to the values that make up the new record 
          131  +** to insert. 
          132  +**
          133  +** If the target database table has an INTEGER PRIMARY KEY, it is not 
          134  +** possible to insert a NULL value into the IPK column. Attempting to 
          135  +** do so results in an SQLITE_MISMATCH error.
          136  +**
          137  +** For each row to DELETE from the target database as part of the OTA 
          138  +** update, the corresponding data_% table should contain a single record
          139  +** with the "ota_control" column set to contain integer value 1. The
          140  +** real primary key values of the row to delete should be stored in the
          141  +** corresponding columns of the data_% table. The values stored in the
          142  +** other columns are not used.
          143  +**
          144  +** For each row to UPDATE from the target database as part of the OTA 
          145  +** update, the corresponding data_% table should contain a single record
          146  +** with the "ota_control" column set to contain a value of type text.
          147  +** The real primary key values identifying the row to update should be 
          148  +** stored in the corresponding columns of the data_% table row, as should
          149  +** the new values of all columns being update. The text value in the 
          150  +** "ota_control" column must contain the same number of characters as
          151  +** there are columns in the target database table, and must consist entirely
          152  +** of 'x' and '.' characters (or in some special cases 'd' - see below). For 
          153  +** each column that is being updated, the corresponding character is set to
          154  +** 'x'. For those that remain as they are, the corresponding character of the
          155  +** ota_control value should be set to '.'. For example, given the tables 
          156  +** above, the update statement:
          157  +**
          158  +**   UPDATE t1 SET c = 'usa' WHERE a = 4;
          159  +**
          160  +** is represented by the data_t1 row created by:
          161  +**
          162  +**   INSERT INTO data_t1(a, b, c, ota_control) VALUES(4, NULL, 'usa', '..x');
          163  +**
          164  +** Instead of an 'x' character, characters of the ota_control value specified
          165  +** for UPDATEs may also be set to 'd'. In this case, instead of updating the
          166  +** target table with the value stored in the corresponding data_% column, the
          167  +** user-defined SQL function "ota_delta()" is invoked and the result stored in
          168  +** the target table column. ota_delta() is invoked with two arguments - the
          169  +** original value currently stored in the target table column and the 
          170  +** value specified in the data_xxx table.
          171  +**
          172  +** For example, this row:
          173  +**
          174  +**   INSERT INTO data_t1(a, b, c, ota_control) VALUES(4, NULL, 'usa', '..d');
          175  +**
          176  +** is similar to an UPDATE statement such as: 
          177  +**
          178  +**   UPDATE t1 SET c = ota_delta(c, 'usa') WHERE a = 4;
          179  +**
          180  +** If the target database table is a virtual table or a table with no PRIMARY
          181  +** KEY, the ota_control value should not include a character corresponding 
          182  +** to the ota_rowid value. For example, this:
          183  +**
          184  +**   INSERT INTO data_ft1(a, b, ota_rowid, ota_control) 
          185  +**       VALUES(NULL, 'usa', 12, '.x');
          186  +**
          187  +** causes a result similar to:
          188  +**
          189  +**   UPDATE ft1 SET b = 'usa' WHERE rowid = 12;
          190  +**
          191  +** The data_xxx tables themselves should have no PRIMARY KEY declarations.
          192  +** However, OTA is more efficient if reading the rows in from each data_xxx
          193  +** table in "rowid" order is roughly the same as reading them sorted by
          194  +** the PRIMARY KEY of the corresponding target database table. In other 
          195  +** words, rows should be sorted using the destination table PRIMARY KEY 
          196  +** fields before they are inserted into the data_xxx tables.
          197  +**
          198  +** USAGE
          199  +**
          200  +** The API declared below allows an application to apply an OTA update 
          201  +** stored on disk to an existing target database. Essentially, the 
          202  +** application:
          203  +**
          204  +**     1) Opens an OTA handle using the sqlite3ota_open() function.
          205  +**
          206  +**     2) Registers any required virtual table modules with the database
          207  +**        handle returned by sqlite3ota_db(). Also, if required, register
          208  +**        the ota_delta() implementation.
          209  +**
          210  +**     3) Calls the sqlite3ota_step() function one or more times on
          211  +**        the new handle. Each call to sqlite3ota_step() performs a single
          212  +**        b-tree operation, so thousands of calls may be required to apply 
          213  +**        a complete update.
          214  +**
          215  +**     4) Calls sqlite3ota_close() to close the OTA update handle. If
          216  +**        sqlite3ota_step() has been called enough times to completely
          217  +**        apply the update to the target database, then the OTA database
          218  +**        is marked as fully applied. Otherwise, the state of the OTA 
          219  +**        update application is saved in the OTA database for later 
          220  +**        resumption.
          221  +**
          222  +** See comments below for more detail on APIs.
          223  +**
          224  +** If an update is only partially applied to the target database by the
          225  +** time sqlite3ota_close() is called, various state information is saved 
          226  +** within the OTA database. This allows subsequent processes to automatically
          227  +** resume the OTA update from where it left off.
          228  +**
          229  +** To remove all OTA extension state information, returning an OTA database 
          230  +** to its original contents, it is sufficient to drop all tables that begin
          231  +** with the prefix "ota_"
          232  +**
          233  +** DATABASE LOCKING
          234  +**
          235  +** An OTA update may not be applied to a database in WAL mode. Attempting
          236  +** to do so is an error (SQLITE_ERROR).
          237  +**
          238  +** While an OTA handle is open, a SHARED lock may be held on the target
          239  +** database file. This means it is possible for other clients to read the
          240  +** database, but not to write it.
          241  +**
          242  +** If an OTA update is started and then suspended before it is completed,
          243  +** then an external client writes to the database, then attempting to resume
          244  +** the suspended OTA update is also an error (SQLITE_BUSY).
          245  +*/
          246  +
          247  +#ifndef _SQLITE3OTA_H
          248  +#define _SQLITE3OTA_H
          249  +
          250  +#include "sqlite3.h"              /* Required for error code definitions */
          251  +
          252  +typedef struct sqlite3ota sqlite3ota;
          253  +
          254  +/*
          255  +** Open an OTA handle.
          256  +**
          257  +** Argument zTarget is the path to the target database. Argument zOta is
          258  +** the path to the OTA database. Each call to this function must be matched
          259  +** by a call to sqlite3ota_close(). When opening the databases, OTA passes
          260  +** the SQLITE_CONFIG_URI flag to sqlite3_open_v2(). So if either zTarget
          261  +** or zOta begin with "file:", it will be interpreted as an SQLite 
          262  +** database URI, not a regular file name.
          263  +**
          264  +** By default, OTA uses the default VFS to access the files on disk. To
          265  +** use a VFS other than the default, an SQLite "file:" URI containing a
          266  +** "vfs=..." option may be passed as the zTarget option.
          267  +**
          268  +** IMPORTANT NOTE FOR ZIPVFS USERS: The OTA extension works with all of
          269  +** SQLite's built-in VFSs, including the multiplexor VFS. However it does
          270  +** not work out of the box with zipvfs. Refer to the comment describing
          271  +** the zipvfs_create_vfs() API below for details on using OTA with zipvfs.
          272  +*/
          273  +sqlite3ota *sqlite3ota_open(const char *zTarget, const char *zOta);
          274  +
          275  +/*
          276  +** Open an OTA handle with an auxiliary state file.
          277  +**
          278  +** This API is similar to sqlite3ota_open(), except that it allows the user 
          279  +** to specify a separate SQLite database in which to store the OTA update 
          280  +** state.
          281  +**
          282  +** While executing, the OTA extension usually stores the current state 
          283  +** of the update (how many rows have been updated, which indexes are yet
          284  +** to be updated etc.) within the OTA database itself. This can be 
          285  +** convenient, as it means that the OTA application does not need to
          286  +** organize removing a separate state file after the update is concluded.
          287  +** However, it can also be inconvenient - for example if the OTA update
          288  +** database is sto be stored on a read-only media.
          289  +**
          290  +** If an OTA update started using a handle opened with this function is
          291  +** suspended, the application must use this function to resume it, and 
          292  +** must pass the same zState argument each time the update is resumed.
          293  +** Attempting to resume an sqlite3ota_open_v2() update using sqlite3ota_open(),
          294  +** or with a call to sqlite3ota_open_v2() specifying a different zState
          295  +** argument leads to undefined behaviour.
          296  +**
          297  +** Once the OTA update is finished, the OTA extension does not 
          298  +** automatically remove the zState database file, even if it created it.
          299  +*/
          300  +sqlite3ota *sqlite3ota_open_v2(
          301  +  const char *zTarget,
          302  +  const char *zOta,
          303  +  const char *zState
          304  +);
          305  +
          306  +/*
          307  +** Internally, each OTA connection uses a separate SQLite database 
          308  +** connection to access the target and ota update databases. This
          309  +** API allows the application direct access to these database handles.
          310  +**
          311  +** The first argument passed to this function must be a valid, open, OTA
          312  +** handle. The second argument should be passed zero to access the target
          313  +** database handle, or non-zero to access the ota update database handle.
          314  +** Accessing the underlying database handles may be useful in the
          315  +** following scenarios:
          316  +**
          317  +**   * If any target tables are virtual tables, it may be necessary to
          318  +**     call sqlite3_create_module() on the target database handle to 
          319  +**     register the required virtual table implementations.
          320  +**
          321  +**   * If the data_xxx tables in the OTA source database are virtual 
          322  +**     tables, the application may need to call sqlite3_create_module() on
          323  +**     the ota update db handle to any required virtual table
          324  +**     implementations.
          325  +**
          326  +**   * If the application uses the "ota_delta()" feature described above,
          327  +**     it must use sqlite3_create_function() or similar to register the
          328  +**     ota_delta() implementation with the target database handle.
          329  +**
          330  +** If an error has occurred, either while opening or stepping the OTA object,
          331  +** this function may return NULL. The error code and message may be collected
          332  +** when sqlite3ota_close() is called.
          333  +*/
          334  +sqlite3 *sqlite3ota_db(sqlite3ota*, int bOta);
          335  +
          336  +/*
          337  +** Do some work towards applying the OTA update to the target db. 
          338  +**
          339  +** Return SQLITE_DONE if the update has been completely applied, or 
          340  +** SQLITE_OK if no error occurs but there remains work to do to apply
          341  +** the OTA update. If an error does occur, some other error code is 
          342  +** returned. 
          343  +**
          344  +** Once a call to sqlite3ota_step() has returned a value other than
          345  +** SQLITE_OK, all subsequent calls on the same OTA handle are no-ops
          346  +** that immediately return the same value.
          347  +*/
          348  +int sqlite3ota_step(sqlite3ota *pOta);
          349  +
          350  +/*
          351  +** Close an OTA handle. 
          352  +**
          353  +** If the OTA update has been completely applied, mark the OTA database
          354  +** as fully applied. Otherwise, assuming no error has occurred, save the
          355  +** current state of the OTA update appliation to the OTA database.
          356  +**
          357  +** If an error has already occurred as part of an sqlite3ota_step()
          358  +** or sqlite3ota_open() call, or if one occurs within this function, an
          359  +** SQLite error code is returned. Additionally, *pzErrmsg may be set to
          360  +** point to a buffer containing a utf-8 formatted English language error
          361  +** message. It is the responsibility of the caller to eventually free any 
          362  +** such buffer using sqlite3_free().
          363  +**
          364  +** Otherwise, if no error occurs, this function returns SQLITE_OK if the
          365  +** update has been partially applied, or SQLITE_DONE if it has been 
          366  +** completely applied.
          367  +*/
          368  +int sqlite3ota_close(sqlite3ota *pOta, char **pzErrmsg);
          369  +
          370  +/*
          371  +** Return the total number of key-value operations (inserts, deletes or 
          372  +** updates) that have been performed on the target database since the
          373  +** current OTA update was started.
          374  +*/
          375  +sqlite3_int64 sqlite3ota_progress(sqlite3ota *pOta);
          376  +
          377  +/*
          378  +** Create an OTA VFS named zName that accesses the underlying file-system
          379  +** via existing VFS zParent. Or, if the zParent parameter is passed NULL, 
          380  +** then the new OTA VFS uses the default system VFS to access the file-system.
          381  +** The new object is registered as a non-default VFS with SQLite before 
          382  +** returning.
          383  +**
          384  +** Part of the OTA implementation uses a custom VFS object. Usually, this
          385  +** object is created and deleted automatically by OTA. 
          386  +**
          387  +** The exception is for applications that also use zipvfs. In this case,
          388  +** the custom VFS must be explicitly created by the user before the OTA
          389  +** handle is opened. The OTA VFS should be installed so that the zipvfs
          390  +** VFS uses the OTA VFS, which in turn uses any other VFS layers in use 
          391  +** (for example multiplexor) to access the file-system. For example,
          392  +** to assemble an OTA enabled VFS stack that uses both zipvfs and 
          393  +** multiplexor (error checking omitted):
          394  +**
          395  +**     // Create a VFS named "multiplex" (not the default).
          396  +**     sqlite3_multiplex_initialize(0, 0);
          397  +**
          398  +**     // Create an ota VFS named "ota" that uses multiplexor. If the
          399  +**     // second argument were replaced with NULL, the "ota" VFS would
          400  +**     // access the file-system via the system default VFS, bypassing the
          401  +**     // multiplexor.
          402  +**     sqlite3ota_create_vfs("ota", "multiplex");
          403  +**
          404  +**     // Create a zipvfs VFS named "zipvfs" that uses ota.
          405  +**     zipvfs_create_vfs_v3("zipvfs", "ota", 0, xCompressorAlgorithmDetector);
          406  +**
          407  +**     // Make zipvfs the default VFS.
          408  +**     sqlite3_vfs_register(sqlite3_vfs_find("zipvfs"), 1);
          409  +**
          410  +** Because the default VFS created above includes a OTA functionality, it
          411  +** may be used by OTA clients. Attempting to use OTA with a zipvfs VFS stack
          412  +** that does not include the OTA layer results in an error.
          413  +**
          414  +** The overhead of adding the "ota" VFS to the system is negligible for 
          415  +** non-OTA users. There is no harm in an application accessing the 
          416  +** file-system via "ota" all the time, even if it only uses OTA functionality 
          417  +** occasionally.
          418  +*/
          419  +int sqlite3ota_create_vfs(const char *zName, const char *zParent);
          420  +
          421  +/*
          422  +** Deregister and destroy an OTA vfs created by an earlier call to
          423  +** sqlite3ota_create_vfs().
          424  +**
          425  +** VFS objects are not reference counted. If a VFS object is destroyed
          426  +** before all database handles that use it have been closed, the results
          427  +** are undefined.
          428  +*/
          429  +void sqlite3ota_destroy_vfs(const char *zName);
          430  +
          431  +#endif /* _SQLITE3OTA_H */
          432  +

Added ext/ota/test_ota.c.

            1  +/*
            2  +** 2015 February 16
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +*/
           13  +
           14  +#include "sqlite3.h"
           15  +
           16  +#if defined(SQLITE_TEST)
           17  +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_OTA)
           18  +
           19  +#include "sqlite3ota.h"
           20  +#include <tcl.h>
           21  +#include <assert.h>
           22  +
           23  +/* From main.c (apparently...) */
           24  +extern const char *sqlite3ErrName(int);
           25  +
           26  +void test_ota_delta(sqlite3_context *pCtx, int nArg, sqlite3_value **apVal){
           27  +  Tcl_Interp *interp = (Tcl_Interp*)sqlite3_user_data(pCtx);
           28  +  Tcl_Obj *pScript;
           29  +  int i;
           30  +
           31  +  pScript = Tcl_NewObj();
           32  +  Tcl_IncrRefCount(pScript);
           33  +  Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj("ota_delta", -1));
           34  +  for(i=0; i<nArg; i++){
           35  +    sqlite3_value *pIn = apVal[i];
           36  +    const char *z = (const char*)sqlite3_value_text(pIn);
           37  +    Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(z, -1));
           38  +  }
           39  +
           40  +  if( TCL_OK==Tcl_EvalObjEx(interp, pScript, TCL_GLOBAL_ONLY) ){
           41  +    const char *z = Tcl_GetStringResult(interp);
           42  +    sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
           43  +  }else{
           44  +    Tcl_BackgroundError(interp);
           45  +  }
           46  +
           47  +  Tcl_DecrRefCount(pScript);
           48  +}
           49  +
           50  +
           51  +static int test_sqlite3ota_cmd(
           52  +  ClientData clientData,
           53  +  Tcl_Interp *interp,
           54  +  int objc,
           55  +  Tcl_Obj *CONST objv[]
           56  +){
           57  +  int ret = TCL_OK;
           58  +  sqlite3ota *pOta = (sqlite3ota*)clientData;
           59  +  const char *azMethod[] = { "step", "close", "create_ota_delta", 0 };
           60  +  int iMethod;
           61  +
           62  +  if( objc!=2 ){
           63  +    Tcl_WrongNumArgs(interp, 1, objv, "METHOD");
           64  +    return TCL_ERROR;
           65  +  }
           66  +  if( Tcl_GetIndexFromObj(interp, objv[1], azMethod, "method", 0, &iMethod) ){
           67  +    return TCL_ERROR;
           68  +  }
           69  +
           70  +  switch( iMethod ){
           71  +    case 0: /* step */ {
           72  +      int rc = sqlite3ota_step(pOta);
           73  +      Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
           74  +      break;
           75  +    }
           76  +
           77  +    case 1: /* close */ {
           78  +      char *zErrmsg = 0;
           79  +      int rc;
           80  +      Tcl_DeleteCommand(interp, Tcl_GetString(objv[0]));
           81  +      rc = sqlite3ota_close(pOta, &zErrmsg);
           82  +      if( rc==SQLITE_OK || rc==SQLITE_DONE ){
           83  +        Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
           84  +        assert( zErrmsg==0 );
           85  +      }else{
           86  +        Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
           87  +        if( zErrmsg ){
           88  +          Tcl_AppendResult(interp, " - ", zErrmsg, 0);
           89  +          sqlite3_free(zErrmsg);
           90  +        }
           91  +        ret = TCL_ERROR;
           92  +      }
           93  +      break;
           94  +    }
           95  +
           96  +    case 2: /* create_ota_delta */ {
           97  +      sqlite3 *db = sqlite3ota_db(pOta, 0);
           98  +      int rc = sqlite3_create_function(
           99  +          db, "ota_delta", -1, SQLITE_UTF8, (void*)interp, test_ota_delta, 0, 0
          100  +      );
          101  +      Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
          102  +      ret = (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
          103  +      break;
          104  +    }
          105  +
          106  +    default: /* seems unlikely */
          107  +      assert( !"cannot happen" );
          108  +      break;
          109  +  }
          110  +
          111  +  return ret;
          112  +}
          113  +
          114  +/*
          115  +** Tclcmd: sqlite3ota CMD <target-db> <ota-db> ?<state-db>?
          116  +*/
          117  +static int test_sqlite3ota(
          118  +  ClientData clientData,
          119  +  Tcl_Interp *interp,
          120  +  int objc,
          121  +  Tcl_Obj *CONST objv[]
          122  +){
          123  +  sqlite3ota *pOta = 0;
          124  +  const char *zCmd;
          125  +  const char *zTarget;
          126  +  const char *zOta;
          127  +
          128  +  if( objc!=4 && objc!=5 ){
          129  +    Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB OTA-DB ?STATE-DB?");
          130  +    return TCL_ERROR;
          131  +  }
          132  +  zCmd = Tcl_GetString(objv[1]);
          133  +  zTarget = Tcl_GetString(objv[2]);
          134  +  zOta = Tcl_GetString(objv[3]);
          135  +
          136  +  if( objc==4 ){
          137  +    pOta = sqlite3ota_open(zTarget, zOta);
          138  +  }else{
          139  +    const char *zStateDb = Tcl_GetString(objv[4]);
          140  +    pOta = sqlite3ota_open_v2(zTarget, zOta, zStateDb);
          141  +  }
          142  +  Tcl_CreateObjCommand(interp, zCmd, test_sqlite3ota_cmd, (ClientData)pOta, 0);
          143  +  Tcl_SetObjResult(interp, objv[1]);
          144  +  return TCL_OK;
          145  +}
          146  +
          147  +/*
          148  +** Tclcmd: sqlite3ota_create_vfs ?-default? NAME PARENT
          149  +*/
          150  +static int test_sqlite3ota_create_vfs(
          151  +  ClientData clientData,
          152  +  Tcl_Interp *interp,
          153  +  int objc,
          154  +  Tcl_Obj *CONST objv[]
          155  +){
          156  +  const char *zName;
          157  +  const char *zParent;
          158  +  int rc;
          159  +
          160  +  if( objc!=3 && objc!=4 ){
          161  +    Tcl_WrongNumArgs(interp, 1, objv, "?-default? NAME PARENT");
          162  +    return TCL_ERROR;
          163  +  }
          164  +
          165  +  zName = Tcl_GetString(objv[objc-2]);
          166  +  zParent = Tcl_GetString(objv[objc-1]);
          167  +  if( zParent[0]=='\0' ) zParent = 0;
          168  +
          169  +  rc = sqlite3ota_create_vfs(zName, zParent);
          170  +  if( rc!=SQLITE_OK ){
          171  +    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
          172  +    return TCL_ERROR;
          173  +  }else if( objc==4 ){
          174  +    sqlite3_vfs *pVfs = sqlite3_vfs_find(zName);
          175  +    sqlite3_vfs_register(pVfs, 1);
          176  +  }
          177  +
          178  +  Tcl_ResetResult(interp);
          179  +  return TCL_OK;
          180  +}
          181  +
          182  +/*
          183  +** Tclcmd: sqlite3ota_destroy_vfs NAME
          184  +*/
          185  +static int test_sqlite3ota_destroy_vfs(
          186  +  ClientData clientData,
          187  +  Tcl_Interp *interp,
          188  +  int objc,
          189  +  Tcl_Obj *CONST objv[]
          190  +){
          191  +  const char *zName;
          192  +
          193  +  if( objc!=2 ){
          194  +    Tcl_WrongNumArgs(interp, 1, objv, "NAME");
          195  +    return TCL_ERROR;
          196  +  }
          197  +
          198  +  zName = Tcl_GetString(objv[1]);
          199  +  sqlite3ota_destroy_vfs(zName);
          200  +  return TCL_OK;
          201  +}
          202  +
          203  +/*
          204  +** Tclcmd: sqlite3ota_internal_test
          205  +*/
          206  +static int test_sqlite3ota_internal_test(
          207  +  ClientData clientData,
          208  +  Tcl_Interp *interp,
          209  +  int objc,
          210  +  Tcl_Obj *CONST objv[]
          211  +){
          212  +  sqlite3 *db;
          213  +
          214  +  if( objc!=1 ){
          215  +    Tcl_WrongNumArgs(interp, 1, objv, "");
          216  +    return TCL_ERROR;
          217  +  }
          218  +
          219  +  db = sqlite3ota_db(0, 0);
          220  +  if( db!=0 ){
          221  +    Tcl_AppendResult(interp, "sqlite3ota_db(0, 0)!=0", 0);
          222  +    return TCL_ERROR;
          223  +  }
          224  +
          225  +  return TCL_OK;
          226  +}
          227  +
          228  +int SqliteOta_Init(Tcl_Interp *interp){ 
          229  +  static struct {
          230  +     char *zName;
          231  +     Tcl_ObjCmdProc *xProc;
          232  +  } aObjCmd[] = {
          233  +    { "sqlite3ota", test_sqlite3ota },
          234  +    { "sqlite3ota_create_vfs", test_sqlite3ota_create_vfs },
          235  +    { "sqlite3ota_destroy_vfs", test_sqlite3ota_destroy_vfs },
          236  +    { "sqlite3ota_internal_test", test_sqlite3ota_internal_test },
          237  +  };
          238  +  int i;
          239  +  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
          240  +    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
          241  +  }
          242  +  return TCL_OK;
          243  +}
          244  +
          245  +#else
          246  +#include <tcl.h>
          247  +int SqliteOta_Init(Tcl_Interp *interp){ return TCL_OK; }
          248  +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_OTA) */
          249  +#endif /* defined(SQLITE_TEST) */
          250  +

Changes to main.mk.

    61     61            fts3_write.o func.o global.o hash.o \
    62     62            icu.o insert.o journal.o legacy.o loadext.o \
    63     63            main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
    64     64            memjournal.o \
    65     65            mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
    66     66            notify.o opcodes.o os.o os_unix.o os_win.o \
    67     67            pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \
    68         -         random.o resolve.o rowset.o rtree.o select.o status.o \
           68  +         random.o resolve.o rowset.o rtree.o select.o sqlite3ota.o status.o \
    69     69            table.o threads.o tokenize.o trigger.o \
    70     70            update.o userauth.o util.o vacuum.o \
    71     71            vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o vdbesort.o \
    72     72   	 vdbetrace.o wal.o walker.o where.o utf.o vtab.o
    73     73   
    74     74   
    75     75   
................................................................................
   217    217   SRC += \
   218    218     $(TOP)/ext/rtree/sqlite3rtree.h \
   219    219     $(TOP)/ext/rtree/rtree.h \
   220    220     $(TOP)/ext/rtree/rtree.c
   221    221   SRC += \
   222    222     $(TOP)/ext/userauth/userauth.c \
   223    223     $(TOP)/ext/userauth/sqlite3userauth.h
          224  +SRC += \
          225  +  $(TOP)/ext/ota/sqlite3ota.c \
          226  +  $(TOP)/ext/ota/sqlite3ota.h
   224    227   
   225    228   # Generated source code files
   226    229   #
   227    230   SRC += \
   228    231     keywordhash.h \
   229    232     opcodes.c \
   230    233     opcodes.h \
................................................................................
   234    237   
   235    238   
   236    239   # Source code to the test files.
   237    240   #
   238    241   TESTSRC = \
   239    242     $(TOP)/ext/fts3/fts3_term.c \
   240    243     $(TOP)/ext/fts3/fts3_test.c \
          244  +  $(TOP)/ext/ota/test_ota.c \
   241    245     $(TOP)/src/test1.c \
   242    246     $(TOP)/src/test2.c \
   243    247     $(TOP)/src/test3.c \
   244    248     $(TOP)/src/test4.c \
   245    249     $(TOP)/src/test5.c \
   246    250     $(TOP)/src/test6.c \
   247    251     $(TOP)/src/test7.c \
................................................................................
   335    339     $(TOP)/src/where.c \
   336    340     parse.c \
   337    341     $(TOP)/ext/fts3/fts3.c \
   338    342     $(TOP)/ext/fts3/fts3_aux.c \
   339    343     $(TOP)/ext/fts3/fts3_expr.c \
   340    344     $(TOP)/ext/fts3/fts3_tokenizer.c \
   341    345     $(TOP)/ext/fts3/fts3_write.c \
   342         -  $(TOP)/ext/async/sqlite3async.c
          346  +  $(TOP)/ext/async/sqlite3async.c 
   343    347   
   344    348   # Header files used by all library source files.
   345    349   #
   346    350   HDR = \
   347    351      $(TOP)/src/btree.h \
   348    352      $(TOP)/src/btreeInt.h \
   349    353      $(TOP)/src/hash.h \
................................................................................
   599    603   
   600    604   rtree.o:	$(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
   601    605   	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
   602    606   
   603    607   userauth.o:	$(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR)
   604    608   	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c
   605    609   
          610  +sqlite3ota.o:	$(TOP)/ext/ota/sqlite3ota.c $(HDR) $(EXTHDR)
          611  +	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/ota/sqlite3ota.c
          612  +
   606    613   
   607    614   # Rules for building test programs and for running tests
   608    615   #
   609    616   tclsqlite3:	$(TOP)/src/tclsqlite.c libsqlite3.a
   610    617   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \
   611    618   		$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)
   612    619   
................................................................................
   730    737   	$(TCC) -o LogEst$(EXE) $(TOP)/tool/logest.c
   731    738   
   732    739   wordcount$(EXE):	$(TOP)/test/wordcount.c sqlite3.c
   733    740   	$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o wordcount$(EXE) \
   734    741   		$(TOP)/test/wordcount.c sqlite3.c
   735    742   
   736    743   speedtest1$(EXE):	$(TOP)/test/speedtest1.c sqlite3.o
   737         -	$(TCC) -I. -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB)
          744  +	$(TCC) -I. $(OTAFLAGS) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB) 
          745  +
          746  +ota$(EXE): $(TOP)/ext/ota/ota.c $(TOP)/ext/ota/sqlite3ota.c sqlite3.o 
          747  +	$(TCC) -I. -o ota$(EXE) $(TOP)/ext/ota/ota.c sqlite3.o \
          748  +	  $(THREADLIB)
   738    749   
   739    750   # This target will fail if the SQLite amalgamation contains any exported
   740    751   # symbols that do not begin with "sqlite3_". It is run as part of the
   741    752   # releasetest.tcl script.
   742    753   #
   743    754   checksymbols: sqlite3.o
   744    755   	nm -g --defined-only sqlite3.o | grep -v " sqlite3_" ; test $$? -ne 0

Changes to src/sqlite.h.in.

   952    952   **
   953    953   ** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
   954    954   ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging.  This
   955    955   ** opcode causes the xFileControl method to swap the file handle with the one
   956    956   ** pointed to by the pArg argument.  This capability is used during testing
   957    957   ** and only needs to be supported when SQLITE_TEST is defined.
   958    958   **
   959         -** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
          959  +* <li>[[SQLITE_FCNTL_WAL_BLOCK]]
   960    960   ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
   961    961   ** be advantageous to block on the next WAL lock if the lock is not immediately
   962    962   ** available.  The WAL subsystem issues this signal during rare
   963    963   ** circumstances in order to fix a problem with priority inversion.
   964    964   ** Applications should <em>not</em> use this file-control.
   965    965   **
          966  +** <li>[[SQLITE_FCNTL_ZIPVFS]]
          967  +** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other
          968  +** VFS should return SQLITE_NOTFOUND for this opcode.
          969  +**
          970  +** <li>[[SQLITE_FCNTL_OTA]]
          971  +** The [SQLITE_FCNTL_OTA] opcode is implemented by the special VFS used by
          972  +** the OTA extension only.  All other VFS should return SQLITE_NOTFOUND for
          973  +** this opcode.  
   966    974   ** </ul>
   967    975   */
   968    976   #define SQLITE_FCNTL_LOCKSTATE               1
   969    977   #define SQLITE_FCNTL_GET_LOCKPROXYFILE       2
   970    978   #define SQLITE_FCNTL_SET_LOCKPROXYFILE       3
   971    979   #define SQLITE_FCNTL_LAST_ERRNO              4
   972    980   #define SQLITE_FCNTL_SIZE_HINT               5
................................................................................
   984    992   #define SQLITE_FCNTL_MMAP_SIZE              18
   985    993   #define SQLITE_FCNTL_TRACE                  19
   986    994   #define SQLITE_FCNTL_HAS_MOVED              20
   987    995   #define SQLITE_FCNTL_SYNC                   21
   988    996   #define SQLITE_FCNTL_COMMIT_PHASETWO        22
   989    997   #define SQLITE_FCNTL_WIN32_SET_HANDLE       23
   990    998   #define SQLITE_FCNTL_WAL_BLOCK              24
          999  +#define SQLITE_FCNTL_ZIPVFS                 25
         1000  +#define SQLITE_FCNTL_OTA                    26
   991   1001   
   992   1002   /* deprecated names */
   993   1003   #define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
   994   1004   #define SQLITE_SET_LOCKPROXYFILE      SQLITE_FCNTL_SET_LOCKPROXYFILE
   995   1005   #define SQLITE_LAST_ERRNO             SQLITE_FCNTL_LAST_ERRNO
   996   1006   
   997   1007   

Changes to src/tclsqlite.c.

  3756   3756       extern int Sqlitetestintarray_Init(Tcl_Interp*);
  3757   3757       extern int Sqlitetestvfs_Init(Tcl_Interp *);
  3758   3758       extern int Sqlitetestrtree_Init(Tcl_Interp*);
  3759   3759       extern int Sqlitequota_Init(Tcl_Interp*);
  3760   3760       extern int Sqlitemultiplex_Init(Tcl_Interp*);
  3761   3761       extern int SqliteSuperlock_Init(Tcl_Interp*);
  3762   3762       extern int SqlitetestSyscall_Init(Tcl_Interp*);
         3763  +    extern int SqliteOta_Init(Tcl_Interp*);
  3763   3764   
  3764   3765   #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
  3765   3766       extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
  3766   3767   #endif
  3767   3768   
  3768   3769   #ifdef SQLITE_ENABLE_ZIPVFS
  3769   3770       extern int Zipvfs_Init(Tcl_Interp*);
................................................................................
  3799   3800       Sqlitetestintarray_Init(interp);
  3800   3801       Sqlitetestvfs_Init(interp);
  3801   3802       Sqlitetestrtree_Init(interp);
  3802   3803       Sqlitequota_Init(interp);
  3803   3804       Sqlitemultiplex_Init(interp);
  3804   3805       SqliteSuperlock_Init(interp);
  3805   3806       SqlitetestSyscall_Init(interp);
         3807  +    SqliteOta_Init(interp);
  3806   3808   
  3807   3809   #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
  3808   3810       Sqlitetestfts3_Init(interp);
  3809   3811   #endif
  3810   3812   
  3811   3813       Tcl_CreateObjCommand(
  3812   3814           interp, "load_testfixture_extensions", init_all_cmd, 0, 0

Changes to src/test_config.c.

   425    425   Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);
   426    426   
   427    427   #ifdef SQLITE_OMIT_OR_OPTIMIZATION
   428    428     Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY);
   429    429   #else
   430    430     Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY);
   431    431   #endif
          432  +
          433  +#ifdef SQLITE_ENABLE_OTA
          434  +  Tcl_SetVar2(interp, "sqlite_options", "ota", "1", TCL_GLOBAL_ONLY);
          435  +#else
          436  +  Tcl_SetVar2(interp, "sqlite_options", "ota", "0", TCL_GLOBAL_ONLY);
          437  +#endif
   432    438   
   433    439   #ifdef SQLITE_OMIT_PAGER_PRAGMAS
   434    440     Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY);
   435    441   #else
   436    442     Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "1", TCL_GLOBAL_ONLY);
   437    443   #endif
   438    444   

Added test/ota.test.

            1  +# 2014 September 20
            2  +#
            3  +#    May you do good and not evil.
            4  +#    May you find forgiveness for yourself and forgive others.
            5  +#    May you share freely, never taking more than you give.
            6  +#
            7  +#***********************************************************************
            8  +# This file runs all rtree related tests.
            9  +#
           10  +
           11  +set testdir [file dirname $argv0]
           12  +source $testdir/permutations.test
           13  +
           14  +ifcapable !ota { finish_test ; return }
           15  +
           16  +run_test_suite ota
           17  +finish_test
           18  +

Changes to test/permutations.test.

   109    109     speed1.test speed1p.test speed2.test speed3.test speed4.test 
   110    110     speed4p.test sqllimits1.test tkt2686.test thread001.test thread002.test
   111    111     thread003.test thread004.test thread005.test trans2.test vacuum3.test 
   112    112     incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test
   113    113     vtab_err.test walslow.test walcrash.test walcrash3.test
   114    114     walthread.test rtree3.test indexfault.test securedel2.test
   115    115     sort3.test sort4.test fts4growth.test fts4growth2.test
   116         -  bigsort.test
          116  +  bigsort.test ota.test
   117    117   }]
   118    118   if {[info exists ::env(QUICKTEST_INCLUDE)]} {
   119    119     set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]
   120    120   }
   121    121   if {[info exists ::env(QUICKTEST_OMIT)]} {
   122    122     foreach x [split $::env(QUICKTEST_OMIT) ,] {
   123    123       regsub -all \\y$x\\y $allquicktests {} allquicktests
................................................................................
   934    934     fts3am.test  fts3an.test  fts3ao.test  fts3b.test
   935    935     fts3c.test   fts3d.test   fts3e.test   fts3query.test 
   936    936   }
   937    937   
   938    938   test_suite "rtree" -description {
   939    939     All R-tree related tests. Provides coverage of source file rtree.c.
   940    940   } -files [glob -nocomplain $::testdir/../ext/rtree/*.test]
          941  +
          942  +test_suite "ota" -description {
          943  +  OTA tests.
          944  +} -files [
          945  +  test_set [glob -nocomplain $::testdir/../ext/ota/*.test] -exclude ota.test
          946  +]
   941    947   
   942    948   test_suite "no_optimization" -description {
   943    949     Run test scripts with optimizations disabled using the
   944    950     sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) interface.
   945    951   } -files {
   946    952     where.test where2.test where3.test where4.test where5.test
   947    953     where6.test where7.test where8.test where9.test

Changes to test/releasetest.tcl.

   112    112       -DSQLITE_MAX_ATTACHED=125
   113    113     }
   114    114     "Fast-One" {
   115    115       -O6
   116    116       -DSQLITE_ENABLE_FTS4=1
   117    117       -DSQLITE_ENABLE_RTREE=1
   118    118       -DSQLITE_ENABLE_STAT4
          119  +    -DSQLITE_ENABLE_OTA
   119    120       -DSQLITE_MAX_ATTACHED=125
   120    121     }
   121    122     "Device-One" {
   122    123       -O2
   123    124       -DSQLITE_DEBUG=1
   124    125       -DSQLITE_DEFAULT_AUTOVACUUM=1
   125    126       -DSQLITE_DEFAULT_CACHE_SIZE=64

Changes to test/speedtest1.c.

    38     38   #include "sqlite3.h"
    39     39   #include <assert.h>
    40     40   #include <stdio.h>
    41     41   #include <stdlib.h>
    42     42   #include <stdarg.h>
    43     43   #include <string.h>
    44     44   #include <ctype.h>
           45  +
           46  +#ifdef SQLITE_ENABLE_OTA
           47  +# include "sqlite3ota.h"
           48  +#endif
    45     49   
    46     50   /* All global state is held in this structure */
    47     51   static struct Global {
    48     52     sqlite3 *db;               /* The open database connection */
    49     53     sqlite3_stmt *pStmt;       /* Current SQL statement */
    50     54     sqlite3_int64 iStart;      /* Start-time for the current test */
    51     55     sqlite3_int64 iTotal;      /* Total time */
................................................................................
   530    534       zNum[len+1] = 0;
   531    535       sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
   532    536       speedtest1_run();
   533    537     }
   534    538     speedtest1_exec("COMMIT");
   535    539     speedtest1_end_test();
   536    540   
   537         -  n = 10; //g.szTest/5;
          541  +  n = 10; /* g.szTest/5; */
   538    542     speedtest1_begin_test(145, "%d SELECTS w/ORDER BY and LIMIT, unindexed", n);
   539    543     speedtest1_exec("BEGIN");
   540    544     speedtest1_prepare(
   541    545       "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
   542    546       " ORDER BY a LIMIT 10; -- %d times", n
   543    547     );
   544    548     for(i=1; i<=n; i++){
................................................................................
  1200   1204           nLook = integerValue(argv[i+1]);
  1201   1205           szLook = integerValue(argv[i+2]);
  1202   1206           i += 2;
  1203   1207         }else if( strcmp(z,"nosync")==0 ){
  1204   1208           noSync = 1;
  1205   1209         }else if( strcmp(z,"notnull")==0 ){
  1206   1210           g.zNN = "NOT NULL";
         1211  +#ifdef SQLITE_ENABLE_OTA
         1212  +      }else if( strcmp(z,"ota")==0 ){
         1213  +        sqlite3ota_create_vfs("ota", 0);
         1214  +        sqlite3_vfs_register(sqlite3_vfs_find("ota"), 1);
         1215  +#endif
  1207   1216         }else if( strcmp(z,"pagesize")==0 ){
  1208   1217           if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
  1209   1218           pageSize = integerValue(argv[++i]);
  1210   1219         }else if( strcmp(z,"pcache")==0 ){
  1211   1220           if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
  1212   1221           nPCache = integerValue(argv[i+1]);
  1213   1222           szPCache = integerValue(argv[i+2]);

Changes to test/tester.tcl.

  1338   1338     # default, so here we force it to the "nativename" format.
  1339   1339     set cfile [string map {\\ \\\\} [file nativename [file join [get_pwd] $crashfile]]]
  1340   1340   
  1341   1341     set f [open crash.tcl w]
  1342   1342     puts $f "sqlite3_crash_enable 1"
  1343   1343     puts $f "sqlite3_crashparams $blocksize $dc $crashdelay $cfile"
  1344   1344     puts $f "sqlite3_test_control_pending_byte $::sqlite_pending_byte"
  1345         -  puts $f $opendb 
  1346   1345   
  1347   1346     # This block sets the cache size of the main database to 10
  1348   1347     # pages. This is done in case the build is configured to omit
  1349   1348     # "PRAGMA cache_size".
  1350         -  puts $f {db eval {SELECT * FROM sqlite_master;}}
  1351         -  puts $f {set bt [btree_from_db db]}
  1352         -  puts $f {btree_set_cache_size $bt 10}
         1349  +  if {$opendb!=""} {
         1350  +    puts $f $opendb 
         1351  +    puts $f {db eval {SELECT * FROM sqlite_master;}}
         1352  +    puts $f {set bt [btree_from_db db]}
         1353  +    puts $f {btree_set_cache_size $bt 10}
         1354  +  }
  1353   1355   
  1354   1356     if {$prngseed} {
  1355   1357       set seed [expr {$prngseed%10007+1}]
  1356   1358       # puts seed=$seed
  1357   1359       puts $f "db eval {SELECT randomblob($seed)}"
  1358   1360     }
  1359   1361   

Changes to tool/mksqlite3c.tcl.

   107    107      os_win.h
   108    108      os.h
   109    109      pager.h
   110    110      parse.h
   111    111      pcache.h
   112    112      pragma.h
   113    113      rtree.h
   114         -   sqlite3ext.h
   115    114      sqlite3.h
          115  +   sqlite3ext.h
          116  +   sqlite3ota.h
   116    117      sqliteicu.h
   117    118      sqliteInt.h
   118    119      sqliteLimit.h
   119    120      vdbe.h
   120    121      vdbeInt.h
   121    122      vxworks.h
   122    123      wal.h
................................................................................
   210    211         # Skip adding the SQLITE_PRIVATE or SQLITE_API keyword before
   211    212         # functions if this header file does not need it.
   212    213         if {![info exists varonly_hdr($tail)]
   213    214          && [regexp $declpattern $line all rettype funcname rest]} {
   214    215           regsub {^SQLITE_API } $line {} line
   215    216           # Add the SQLITE_PRIVATE or SQLITE_API keyword before functions.
   216    217           # so that linkage can be modified at compile-time.
   217         -        if {[regexp {^sqlite3_} $funcname]} {
          218  +        if {[regexp {^sqlite3(_|ota_)} $funcname]} {
   218    219             set line SQLITE_API
   219    220             append line " " [string trim $rettype]
   220    221             if {[string index $rettype end] ne "*"} {
   221    222               append line " "
   222    223             }
   223    224             if {[lsearch -exact $cdecllist $funcname] >= 0} {
   224    225               append line SQLITE_CDECL
................................................................................
   364    365      fts3_snippet.c
   365    366      fts3_unicode.c
   366    367      fts3_unicode2.c
   367    368   
   368    369      rtree.c
   369    370      icu.c
   370    371      fts3_icu.c
          372  +   sqlite3ota.c
   371    373      dbstat.c
   372    374   } {
   373    375     copy_file tsrc/$file
   374    376   }
   375    377   
   376    378   close $out