Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add extra tests and fixes for ota. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | ota-update |
Files: | files | file ages | folders |
SHA1: |
e0b7151962fedbcac975f2216fd6b33b |
User & Date: | dan 2015-02-16 21:13:19.665 |
Context
2015-02-17
| ||
20:49 | Improve test coverage of ota code a bit. (check-in: a438fa6c9a user: dan tags: ota-update) | |
2015-02-16
| ||
21:13 | Add extra tests and fixes for ota. (check-in: e0b7151962 user: dan tags: ota-update) | |
11:48 | Add further tests and fixes for ota. (check-in: 62dc1fffc3 user: dan tags: ota-update) | |
Changes
Changes to ext/ota/ota1.test.
︙ | ︙ | |||
52 53 54 55 56 57 58 59 60 61 62 63 64 65 | INSERT INTO data_t1 VALUES(2, NULL, 5, 1); INSERT INTO data_t1 VALUES(3, 8, 9, 0); INSERT INTO data_t1 VALUES(4, NULL, 11, 1); } ota1 close return $filename } # Create a simple OTA database. That expects to write to a table: # # CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d); # # This OTA includes update statements. # | > > > > > > > > > > > > > > > > > > > > | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | INSERT INTO data_t1 VALUES(2, NULL, 5, 1); INSERT INTO data_t1 VALUES(3, 8, 9, 0); INSERT INTO data_t1 VALUES(4, NULL, 11, 1); } ota1 close return $filename } # # Create a simple OTA database. That expects to write to a table: # # CREATE TABLE t1(c, b, '(a)' INTEGER PRIMARY KEY); # # This OTA includes both insert and delete operations. # proc create_ota4b {filename} { forcedelete $filename sqlite3 ota1 $filename ota1 eval { CREATE TABLE data_t1(c, b, '(a)', ota_control); INSERT INTO data_t1 VALUES(3, 2, 1, 0); INSERT INTO data_t1 VALUES(5, NULL, 2, 1); INSERT INTO data_t1 VALUES(9, 8, 3, 0); INSERT INTO data_t1 VALUES(11, NULL, 4, 1); } ota1 close return $filename } # Create a simple OTA database. That expects to write to a table: # # CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d); # # This OTA includes update statements. # |
︙ | ︙ | |||
363 364 365 366 367 368 369 370 371 372 373 374 375 376 | 3 8 9 6 hello xyz } do_execsql_test $tn3.4.$tn2.$tn.3 { PRAGMA integrity_check } ok } } #------------------------------------------------------------------------- # foreach {tn2 cmd} {1 run_ota 2 step_ota} { foreach {tn schema} { 1 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | 3 8 9 6 hello xyz } do_execsql_test $tn3.4.$tn2.$tn.3 { PRAGMA integrity_check } ok } } foreach {tn2 cmd} {1 run_ota 2 step_ota} { foreach {tn schema} { 1 { CREATE TABLE t1(c, b, '(a)' INTEGER PRIMARY KEY); CREATE INDEX i1 ON t1(c, b); } 2 { CREATE TABLE t1(c, b, '(a)' PRIMARY KEY); } 3 { CREATE TABLE t1(c, b, '(a)' PRIMARY KEY) WITHOUT ROWID; } } { reset_db execsql $schema execsql { INSERT INTO t1('(a)', b, c) VALUES(2, 'hello', 'world'); INSERT INTO t1('(a)', b, c) VALUES(4, 'hello', 'planet'); INSERT INTO t1('(a)', b, c) VALUES(6, 'hello', 'xyz'); } do_test $tn3.4.$tn2.$tn.1 { create_ota4b ota.db $cmd test.db ota.db } {SQLITE_DONE} do_execsql_test $tn3.4.$tn2.$tn.2 { SELECT * FROM t1 ORDER BY "(a)" ASC; } { 3 2 1 9 8 3 xyz hello 6 } do_execsql_test $tn3.4.$tn2.$tn.3 { PRAGMA integrity_check } ok } } #------------------------------------------------------------------------- # foreach {tn2 cmd} {1 run_ota 2 step_ota} { foreach {tn schema} { 1 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d); |
︙ | ︙ | |||
431 432 433 434 435 436 437 438 439 440 441 442 443 444 | #------------------------------------------------------------------------- # Test some error cases: # # * A virtual table with no ota_rowid column. # * A no-PK table with no ota_rowid column. # * A PK table with an ota_rowid column. # ifcapable fts3 { foreach {tn schema error} { 1 { CREATE TABLE t1(a, b); CREATE TABLE ota.data_t1(a, b, ota_control); } {SQLITE_ERROR - table data_t1 requires ota_rowid column} | > > | 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 | #------------------------------------------------------------------------- # Test some error cases: # # * A virtual table with no ota_rowid column. # * A no-PK table with no ota_rowid column. # * A PK table with an ota_rowid column. # # 6: An update string of the wrong length # ifcapable fts3 { foreach {tn schema error} { 1 { CREATE TABLE t1(a, b); CREATE TABLE ota.data_t1(a, b, ota_control); } {SQLITE_ERROR - table data_t1 requires ota_rowid column} |
︙ | ︙ | |||
457 458 459 460 461 462 463 464 465 466 467 468 469 470 | CREATE TABLE ota.data_t1(a, b, ota_rowid, ota_control); } {SQLITE_ERROR - table data_t1 may not have ota_rowid column} 5 { CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID; CREATE TABLE ota.data_t1(a, b, ota_rowid, ota_control); } {SQLITE_ERROR - table data_t1 may not have ota_rowid column} } { reset_db forcedelete ota.db execsql { ATTACH 'ota.db' AS ota } execsql $schema | > > > > > > | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 | CREATE TABLE ota.data_t1(a, b, ota_rowid, ota_control); } {SQLITE_ERROR - table data_t1 may not have ota_rowid column} 5 { CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID; CREATE TABLE ota.data_t1(a, b, ota_rowid, ota_control); } {SQLITE_ERROR - table data_t1 may not have ota_rowid column} 6 { CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT ROWID; CREATE TABLE ota.data_t1(a, b, ota_control); INSERT INTO ota.data_t1 VALUES(1, 2, 'x.x'); } {SQLITE_ERROR - invalid ota_control value} } { reset_db forcedelete ota.db execsql { ATTACH 'ota.db' AS ota } execsql $schema |
︙ | ︙ |
Changes to ext/ota/ota11.test.
︙ | ︙ | |||
67 68 69 70 71 72 73 | dbo close db_restore hexio_write test.db 18 0101 file exists test.db-wal } {1} | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | dbo close db_restore hexio_write test.db 18 0101 file exists test.db-wal } {1} do_test 2.3 { sqlite3ota ota test.db ota.db ota step } {SQLITE_ERROR} do_test 2.4 { list [catch {ota close} msg] $msg } {1 {SQLITE_ERROR - cannot update wal mode database}} #-------------------------------------------------------------------- # Test a constraint violation message with an unusual table name. # Specifically, one for which the first character is a codepoint # smaller than 30 (character '0'). # reset_db do_execsql_test 3.1 { CREATE TABLE "(t1)"(a PRIMARY KEY, b, c); INSERT INTO "(t1)" VALUES(1, 2, 3); INSERT INTO "(t1)" VALUES(4, 5, 6); } db close do_test 3.2 { forcedelete ota.db sqlite3 dbo ota.db dbo eval { CREATE TABLE "data_(t1)"(a, b, c, ota_control); INSERT INTO "data_(t1)" VALUES(4, 8, 9, 0); } dbo close sqlite3ota ota test.db ota.db ota step ota step } {SQLITE_CONSTRAINT} do_test 3.3 { list [catch {ota close} msg] $msg } {1 {SQLITE_CONSTRAINT - UNIQUE constraint failed: (t1).a}} #-------------------------------------------------------------------- # Check that once an OTA update has been applied, attempting to apply # it a second time is a no-op (as the state stored in the OTA database is # "all steps completed"). # reset_db do_execsql_test 4.1 { CREATE TABLE "(t1)"(a, b, c, PRIMARY KEY(c, b, a)); INSERT INTO "(t1)" VALUES(1, 2, 3); INSERT INTO "(t1)" VALUES(4, 5, 6); } db close do_test 4.2 { forcedelete ota.db sqlite3 dbo ota.db dbo eval { CREATE TABLE "data_(t1)"(a, b, c, ota_control); INSERT INTO "data_(t1)" VALUES(7, 8, 9, 0); INSERT INTO "data_(t1)" VALUES(1, 2, 3, 1); } dbo close sqlite3ota ota test.db ota.db while {[ota step]=="SQLITE_OK"} { } ota close } {SQLITE_DONE} do_test 4.3 { sqlite3ota ota test.db ota.db ota step } {SQLITE_DONE} do_test 4.4 { ota close } {SQLITE_DONE} # Also, check that an invalid state value in the ota_state table is # detected and reported as corruption. do_test 4.5 { sqlite3 dbo ota.db dbo eval { UPDATE ota_state SET v = -1 WHERE k = 1 } dbo close sqlite3ota ota test.db ota.db ota step } {SQLITE_CORRUPT} do_test 4.6 { list [catch {ota close} msg] $msg } {1 SQLITE_CORRUPT} finish_test |
Changes to ext/ota/otafault.test.
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | source $testdir/tester.tcl source $testdir/malloc_common.tcl set ::testprefix otafault do_test 1.1 { forcedelete ota.db execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); CREATE INDEX t1cb ON t1(c, b); INSERT INTO t1 VALUES(1, 1, 1); INSERT INTO t1 VALUES(2, 2, 2); INSERT INTO t1 VALUES(3, 3, 3); CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID; CREATE INDEX t2cb ON t1(c, b); | > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | source $testdir/tester.tcl source $testdir/malloc_common.tcl set ::testprefix otafault do_test 1.1 { forcedelete ota.db execsql { PRAGMA encoding = utf16; CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); CREATE INDEX t1cb ON t1(c, b); INSERT INTO t1 VALUES(1, 1, 1); INSERT INTO t1 VALUES(2, 2, 2); INSERT INTO t1 VALUES(3, 3, 3); CREATE TABLE t2(a PRIMARY KEY, b, c) WITHOUT ROWID; CREATE INDEX t2cb ON t1(c, b); |
︙ | ︙ | |||
45 46 47 48 49 50 51 | } db close forcecopy test.db test.db.bak forcecopy ota.db ota.db.bak } {} | > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | < < < < | | | | | | | | | | | | | | | | | | | > > > > > > > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | } db close forcecopy test.db test.db.bak forcecopy ota.db ota.db.bak } {} sqlite3_shutdown set lookaside_config [sqlite3_config_lookaside 0 0] sqlite3_initialize autoinstall_test_functions foreach {tn f reslist} { 1 oom-tra* { {0 SQLITE_DONE} {1 {SQLITE_NOMEM - out of memory}} {1 SQLITE_NOMEM} {1 SQLITE_IOERR_NOMEM} {1 {SQLITE_NOMEM - unable to open a temporary database file for storing temporary tables}} } 2 ioerr-* { {0 SQLITE_DONE} {1 {SQLITE_IOERR - disk I/O error}} {1 SQLITE_IOERR} {1 SQLITE_IOERR_WRITE} {1 SQLITE_IOERR_READ} {1 SQLITE_IOERR_FSYNC} {1 {SQLITE_ERROR - SQL logic error or missing database}} {1 {SQLITE_ERROR - unable to open database: ota.db}} {1 {SQLITE_IOERR - unable to open database: ota.db}} } } { do_faultsim_test 2 -faults $::f -prep { catch { db close } forcedelete test.db-journal test.db-wal ota.db-journal ota.db-wal forcecopy test.db.bak test.db forcecopy ota.db.bak ota.db } -body { sqlite3ota ota test.db ota.db while {[ota step]=="SQLITE_OK"} {} ota close } -test { faultsim_test_result {*}$::reslist if {$testrc==0} { sqlite3 db test.db faultsim_integrity_check set res [db eval { SELECT * FROM t1 UNION ALL SELECT * FROM t2; }] set expected [list {*}{ 1 1 1 3 three 3 4 4 4 a a a c see c d d d }] if {$res != $expected} { puts "" puts "res: $res" puts "exp: $expected" error "data not as expected!" } } } } catch {db close} sqlite3_shutdown sqlite3_config_lookaside {*}$lookaside_config sqlite3_initialize autoinstall_test_functions proc copy_if_exists {src target} { if {[file exists $src]} { forcecopy $src $target } else { forcedelete $target } |
︙ | ︙ |
Changes to ext/ota/sqlite3ota.c.
︙ | ︙ | |||
390 391 392 393 394 395 396 | rc = sqlite3_step(pIter->pTblIter); if( rc!=SQLITE_ROW ){ rc = sqlite3_reset(pIter->pTblIter); pIter->zTbl = 0; }else{ pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); pIter->iTnum = sqlite3_column_int(pIter->pTblIter, 1); | | > | > | | | | | | | | | | > | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | rc = sqlite3_step(pIter->pTblIter); if( rc!=SQLITE_ROW ){ rc = sqlite3_reset(pIter->pTblIter); pIter->zTbl = 0; }else{ pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); pIter->iTnum = sqlite3_column_int(pIter->pTblIter, 1); rc = pIter->zTbl ? SQLITE_OK : SQLITE_NOMEM; } }else{ if( pIter->zIdx==0 ){ sqlite3_stmt *pIdx = pIter->pIdxIter; rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC); } if( rc==SQLITE_OK ){ rc = sqlite3_step(pIter->pIdxIter); if( rc!=SQLITE_ROW ){ rc = sqlite3_reset(pIter->pIdxIter); pIter->bCleanup = 1; pIter->zIdx = 0; }else{ pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0); pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1); pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2); rc = pIter->zIdx ? SQLITE_OK : SQLITE_NOMEM; } } } } } if( rc!=SQLITE_OK ){ otaObjIterFinalize(pIter); |
︙ | ︙ | |||
721 722 723 724 725 726 727 728 729 730 731 732 733 734 | if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->db, &pStmt, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.table_info(%Q)", pIter->zTbl) ); } while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ const char *zName = (const char*)sqlite3_column_text(pStmt, 1); for(i=iOrder; i<pIter->nTblCol; i++){ if( 0==strcmp(zName, pIter->azTblCol[i]) ) break; } if( i==pIter->nTblCol ){ p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("column missing from data_%q: %s", pIter->zTbl, zName | > | 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 | if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->db, &pStmt, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.table_info(%Q)", pIter->zTbl) ); } while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ const char *zName = (const char*)sqlite3_column_text(pStmt, 1); if( zName==0 ) break; /* An OOM - finalize() below returns S_NOMEM */ for(i=iOrder; i<pIter->nTblCol; i++){ if( 0==strcmp(zName, pIter->azTblCol[i]) ) break; } if( i==pIter->nTblCol ){ p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("column missing from data_%q: %s", pIter->zTbl, zName |
︙ | ︙ | |||
859 860 861 862 863 864 865 | const char *zType; if( iCid<0 ){ /* An integer primary key. If the table has an explicit IPK, use ** its name. Otherwise, use "ota_rowid". */ if( pIter->eType==OTA_PK_IPK ){ int i; | | | 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | const char *zType; if( iCid<0 ){ /* An integer primary key. If the table has an explicit IPK, use ** its name. Otherwise, use "ota_rowid". */ if( pIter->eType==OTA_PK_IPK ){ int i; for(i=0; pIter->abTblPk[i]==0; i++); assert( i<pIter->nTblCol ); zCol = pIter->azTblCol[i]; }else{ zCol = "ota_rowid"; } zType = "INTEGER"; }else{ |
︙ | ︙ | |||
1003 1004 1005 1006 1007 1008 1009 | ** (p->objiter.pSelect) currently points to a valid row. However, there ** is something wrong with the ota_control value in the ota_control value ** stored in the (p->nCol+1)'th column. Set the error code and error message ** of the OTA handle to something reflecting this. */ static void otaBadControlError(sqlite3ota *p){ p->rc = SQLITE_ERROR; | | | 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 | ** (p->objiter.pSelect) currently points to a valid row. However, there ** is something wrong with the ota_control value in the ota_control value ** stored in the (p->nCol+1)'th column. Set the error code and error message ** of the OTA handle to something reflecting this. */ static void otaBadControlError(sqlite3ota *p){ p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("invalid ota_control value"); } static char *otaObjIterGetSetlist( sqlite3ota *p, OtaObjIter *pIter, const char *zMask |
︙ | ︙ | |||
1082 1083 1084 1085 1086 1087 1088 | p->rc = prepareFreeAndCollectError(p->db, &pXList, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) ); while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){ const char *zOrig = (const char*)sqlite3_column_text(pXList,3); | | > > | | < | > | > > < | 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 | p->rc = prepareFreeAndCollectError(p->db, &pXList, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) ); while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){ const char *zOrig = (const char*)sqlite3_column_text(pXList,3); if( zOrig && strcmp(zOrig, "pk")==0 ){ const char *zIdx = (const char*)sqlite3_column_text(pXList,1); if( zIdx ){ p->rc = prepareFreeAndCollectError(p->db, &pXInfo, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); } break; } } rc = sqlite3_finalize(pXList); if( p->rc==SQLITE_OK ) p->rc = rc; while( p->rc==SQLITE_OK && pXInfo && SQLITE_ROW==sqlite3_step(pXInfo) ){ if( sqlite3_column_int(pXInfo, 5) ){ /* int iCid = sqlite3_column_int(pXInfo, 0); */ const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2); const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : ""; z = otaMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc); zSep = ", "; } } z = otaMPrintf(p, "%z)", z); rc = sqlite3_finalize(pXInfo); if( p->rc==SQLITE_OK ) p->rc = rc; } return z; } static void otaCreateImposterTable2(sqlite3ota *p, OtaObjIter *pIter){ |
︙ | ︙ | |||
1726 1727 1728 1729 1730 1731 1732 | res = OTA_IDX_DELETE; }else if( iVal==3 ){ res = OTA_IDX_INSERT; } break; } | | > > > > | > > > | 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 | res = OTA_IDX_DELETE; }else if( iVal==3 ){ res = OTA_IDX_INSERT; } break; } case SQLITE_TEXT: { const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol); if( z==0 ){ p->rc = SQLITE_NOMEM; }else{ *pzMask = (const char*)z; } res = OTA_UPDATE; break; } default: break; } if( res==0 ){ otaBadControlError(p); |
︙ | ︙ | |||
1809 1810 1811 1812 1813 1814 1815 | } if( eType==SQLITE_DELETE && pIter->zIdx==0 && pIter->abTblPk[i]==0 ){ continue; } pVal = sqlite3_column_value(pIter->pSelect, i); | | > > | > | | > > > | | > > | > | > | | > | 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 | } if( eType==SQLITE_DELETE && pIter->zIdx==0 && pIter->abTblPk[i]==0 ){ continue; } pVal = sqlite3_column_value(pIter->pSelect, i); p->rc = sqlite3_bind_value(pWriter, i+1, pVal); if( p->rc==SQLITE_RANGE ) p->rc = SQLITE_OK; if( p->rc ) goto step_out; } if( pIter->zIdx==0 && (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE) ){ /* For a virtual table, or a table with no primary key, the ** SELECT statement is: ** ** SELECT <cols>, ota_control, ota_rowid FROM .... ** ** Hence column_value(pIter->nCol+1). */ assertColumnName(pIter->pSelect, pIter->nCol+1, "ota_rowid"); pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1); p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal); } if( p->rc==SQLITE_OK ){ sqlite3_step(pWriter); p->rc = resetAndCollectError(pWriter, &p->zErrmsg); } }else if( eType==OTA_UPDATE ){ sqlite3_value *pVal; sqlite3_stmt *pUpdate = 0; otaGetUpdateStmt(p, pIter, zMask, &pUpdate); if( pUpdate ){ for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){ char c = zMask[pIter->aiSrcOrder[i]]; pVal = sqlite3_column_value(pIter->pSelect, i); if( pIter->abTblPk[i] || c=='x' || c=='d' ){ p->rc = sqlite3_bind_value(pUpdate, i+1, pVal); } } if( p->rc==SQLITE_OK && (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE) ){ /* Bind the ota_rowid value to column _rowid_ */ assertColumnName(pIter->pSelect, pIter->nCol+1, "ota_rowid"); pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1); p->rc = sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal); } if( p->rc==SQLITE_OK ){ sqlite3_step(pUpdate); p->rc = resetAndCollectError(pUpdate, &p->zErrmsg); } } }else{ /* no-op */ assert( eType==OTA_DELETE && pIter->zIdx ); } } |
︙ | ︙ | |||
2175 2176 2177 2178 2179 2180 2181 | } /* If it has not already been created, create the ota_state table */ if( p->rc==SQLITE_OK ){ p->rc = sqlite3_exec(p->db, OTA_CREATE_STATE, 0, 0, &p->zErrmsg); } | < < < < < < < < < < < < > > > | 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 | } /* If it has not already been created, create the ota_state table */ if( p->rc==SQLITE_OK ){ p->rc = sqlite3_exec(p->db, OTA_CREATE_STATE, 0, 0, &p->zErrmsg); } if( p->rc==SQLITE_OK ){ pState = otaLoadState(p); assert( pState || p->rc!=SQLITE_OK ); if( p->rc==SQLITE_OK ){ if( pState->eStage==0 ){ otaDeleteOalFile(p); p->eStage = OTA_STAGE_OAL; }else{ p->eStage = pState->eStage; } p->nProgress = pState->nProgress; } } assert( p->rc!=SQLITE_OK || p->eStage!=0 ); if( p->rc==SQLITE_OK ){ if( p->eStage==OTA_STAGE_OAL ){ /* Check that this is not a wal mode database. If it is, it cannot ** be updated. */ if( p->pTargetFd->pWalFd ){ p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("cannot update wal mode database"); } /* At this point (pTargetFd->iCookie) contains the value of the ** change-counter cookie (the thing that gets incremented when a |
︙ | ︙ | |||
2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 | otaLoadTransactionState(p, pState); } }else if( p->eStage==OTA_STAGE_CKPT ){ otaSetupCheckpoint(p, pState); p->nStep = pState->nRow; }else if( p->eStage==OTA_STAGE_DONE ){ p->rc = SQLITE_DONE; } } otaFreeState(pState); } return p; | > > | 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 | otaLoadTransactionState(p, pState); } }else if( p->eStage==OTA_STAGE_CKPT ){ otaSetupCheckpoint(p, pState); p->nStep = pState->nRow; }else if( p->eStage==OTA_STAGE_DONE ){ p->rc = SQLITE_DONE; }else{ p->rc = SQLITE_CORRUPT; } } otaFreeState(pState); } return p; |
︙ | ︙ | |||
2414 2415 2416 2417 2418 2419 2420 | void *zBuf, int iAmt, sqlite_int64 iOfst ){ ota_file *p = (ota_file*)pFile; int rc; | < | | < | 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 | void *zBuf, int iAmt, sqlite_int64 iOfst ){ ota_file *p = (ota_file*)pFile; int rc; if( p->pOta && p->pOta->eStage==OTA_STAGE_CAPTURE ){ assert( p->openFlags & SQLITE_OPEN_WAL ); rc = otaCaptureWalRead(p->pOta, iOfst, iAmt); }else{ rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ /* These look like magic numbers. But they are stable, as they are part ** of the definition of the SQLite file format, which may not change. */ u8 *pBuf = (u8*)zBuf; |
︙ | ︙ | |||
2443 2444 2445 2446 2447 2448 2449 | sqlite3_file *pFile, const void *zBuf, int iAmt, sqlite_int64 iOfst ){ ota_file *p = (ota_file*)pFile; int rc; | < | | < | 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 | sqlite3_file *pFile, const void *zBuf, int iAmt, sqlite_int64 iOfst ){ ota_file *p = (ota_file*)pFile; int rc; if( p->pOta && p->pOta->eStage==OTA_STAGE_CAPTURE ){ assert( p->openFlags & SQLITE_OPEN_MAIN_DB ); rc = otaCaptureDbWrite(p->pOta, iOfst); }else{ rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst); if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ /* These look like magic numbers. But they are stable, as they are part ** of the definition of the SQLite file format, which may not change. */ u8 *pBuf = (u8*)zBuf; |
︙ | ︙ |