/ Check-in [6fc5d4d2]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Ensure that an error is reported if an attempt is made to update a wal mode database via ota.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | ota-update-no-pager_ota_mode
Files: files | file ages | folders
SHA1: 6fc5d4d26a603b3906f02ceea0f507780d0c35eb
User & Date: dan 2015-02-11 16:25:27
Context
2015-02-11
16:54
Merge latest trunk changes with this branch. Closed-Leaf check-in: 0b63e8dc user: dan tags: ota-update-no-pager_ota_mode
16:25
Ensure that an error is reported if an attempt is made to update a wal mode database via ota. check-in: 6fc5d4d2 user: dan tags: ota-update-no-pager_ota_mode
2015-02-10
20:00
Further tweaks to work with zipvfs. check-in: 0f152416 user: dan tags: ota-update-no-pager_ota_mode
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added ext/ota/otaA.test.





































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
# 2014 August 30
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests for the OTA module. More specifically, it
# contains tests to ensure that it is an error to attempt to update
# a wal mode database via OTA.
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
set ::testprefix otaA

set db_sql {
  CREATE TABLE t1(a PRIMARY KEY, b, c);
}
set ota_sql {
  CREATE TABLE data_t1(a, b, c, ota_control);
  INSERT INTO data_t1 VALUES(1, 2, 3, 0);
  INSERT INTO data_t1 VALUES(4, 5, 6, 0);
  INSERT INTO data_t1 VALUES(7, 8, 9, 0);
}

do_test 1.0 {
  forcedelete test.db ota.db

  sqlite3 db test.db
  db eval $db_sql
  db eval { PRAGMA journal_mode = wal }
  db close

  sqlite3 db ota.db
  db eval $ota_sql
  db close

  sqlite3ota ota test.db ota.db
  ota step
} {SQLITE_ERROR}
do_test 1.1 {
  list [catch { ota close } msg] $msg
} {1 {SQLITE_ERROR - cannot update wal mode database}}

do_test 2.0 {
  forcedelete test.db ota.db

  sqlite3 db test.db
  db eval $db_sql
  db close

  sqlite3 db ota.db
  db eval $ota_sql
  db close

  sqlite3ota ota test.db ota.db
  ota step
  ota close
} {SQLITE_OK}

do_test 2.1 {
  sqlite3 db test.db
  db eval {PRAGMA journal_mode = wal}
  db close
  sqlite3ota ota test.db ota.db
  ota step
} {SQLITE_ERROR}

do_test 2.2 {
  list [catch { ota close } msg] $msg
} {1 {SQLITE_ERROR - cannot update wal mode database}}


finish_test

Changes to ext/ota/sqlite3ota.c.

184
185
186
187
188
189
190

191
192

193
194
195
196
197
198
199
....
2051
2052
2053
2054
2055
2056
2057





2058
2059
2060
2061
2062
2063
2064
....
2260
2261
2262
2263
2264
2265
2266



2267

2268
2269
2270
2271
2272
2273
2274
....
2277
2278
2279
2280
2281
2282
2283



2284

2285
2286
2287
2288
2289
2290
2291
};

struct ota_file {
  sqlite3_file base;              /* sqlite3_file methods */
  sqlite3_file *pReal;            /* Underlying file handle */
  ota_vfs *pOtaVfs;               /* Pointer to the ota_vfs object */
  sqlite3ota *pOta;               /* Pointer to ota object (ota target only) */

  int openFlags;                  /* Flags this file was opened with */
  unsigned int iCookie;           /* Cookie value for main db files */


  int nShm;                       /* Number of entries in apShm[] array */
  char **apShm;                   /* Array of mmap'd *-shm regions */
  const char *zWal;               /* Wal filename for this db file */
  char *zDel;                     /* Delete this when closing file */
};

................................................................................
      otaOpenDatabase(p);
    }

    /* 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);
................................................................................
  void *zBuf, 
  int iAmt, 
  sqlite_int64 iOfst
){
  ota_file *p = (ota_file*)pFile;
  int rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
  if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){



    p->iCookie = otaGetU32((unsigned char*)&zBuf[24]);

  }
  return rc;
}

/*
** Write data to an otaVfs-file.
*/
................................................................................
  const void *zBuf, 
  int iAmt, 
  sqlite_int64 iOfst
){
  ota_file *p = (ota_file*)pFile;
  int rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
  if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){



    p->iCookie = otaGetU32((unsigned char*)&zBuf[24]);

  }
  return rc;
}

/*
** Truncate an otaVfs-file.
*/







>


>







 







>
>
>
>
>







 







>
>
>
|
>







 







>
>
>
|
>







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
....
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
....
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
....
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
};

struct ota_file {
  sqlite3_file base;              /* sqlite3_file methods */
  sqlite3_file *pReal;            /* Underlying file handle */
  ota_vfs *pOtaVfs;               /* Pointer to the ota_vfs object */
  sqlite3ota *pOta;               /* Pointer to ota object (ota target only) */

  int openFlags;                  /* Flags this file was opened with */
  unsigned int iCookie;           /* Cookie value for main db files */
  unsigned char iWriteVer;        /* "write-version" value for main db files */

  int nShm;                       /* Number of entries in apShm[] array */
  char **apShm;                   /* Array of mmap'd *-shm regions */
  const char *zWal;               /* Wal filename for this db file */
  char *zDel;                     /* Delete this when closing file */
};

................................................................................
      otaOpenDatabase(p);
    }

    /* 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 && p->pTargetFd->iWriteVer>1 ){
      p->rc = SQLITE_ERROR;
      p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
    }

    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);
................................................................................
  void *zBuf, 
  int iAmt, 
  sqlite_int64 iOfst
){
  ota_file *p = (ota_file*)pFile;
  int 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. */
    unsigned char *pBuf = (unsigned char*)zBuf;
    p->iCookie = otaGetU32(&pBuf[24]);
    p->iWriteVer = pBuf[19];
  }
  return rc;
}

/*
** Write data to an otaVfs-file.
*/
................................................................................
  const void *zBuf, 
  int iAmt, 
  sqlite_int64 iOfst
){
  ota_file *p = (ota_file*)pFile;
  int 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. */
    unsigned char *pBuf = (unsigned char*)zBuf;
    p->iCookie = otaGetU32(&pBuf[24]);
    p->iWriteVer = pBuf[19];
  }
  return rc;
}

/*
** Truncate an otaVfs-file.
*/