SQLite

Check-in [ffa1524ef2]
Login

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

Overview
Comment:Add a command line program that uses the extension. This serves as example code and is also useful for performance testing.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | ota-update
Files: files | file ages | folders
SHA1: ffa1524ef2a4c32652183eb4745685f0d1c93af2
User & Date: dan 2014-09-03 08:25:09.548
Context
2014-09-03
19:30
Split part of "PRAGMA ota_mode" off into "PRAGMA pager_ota_mode". This allows some specialized custom VFS implementations to intercept and implement the expected pager-related effects of this pragma. (check-in: 209f672e58 user: dan tags: ota-update)
08:25
Add a command line program that uses the extension. This serves as example code and is also useful for performance testing. (check-in: ffa1524ef2 user: dan tags: ota-update)
2014-09-02
19:59
Add an experimental extension for applying bulk updates to databases. (check-in: 2954ab5010 user: dan tags: ota-update)
Changes
Unified Diff Show Whitespace Changes Patch
Added ext/ota/ota.c.
























































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
83
84
85
86
87
88
89
90
91
92
/*
** 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 a command-line application that uses the OTA 
** extension. See the usage() function below for an explanation.
*/

#include "sqlite3ota.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
** Print a usage message and exit.
*/
void usage(const char *zArgv0){
  fprintf(stderr, 
"Usage: %s [-step NSTEP] TARGET-DB OTA-DB\n"
"\n"
"  Argument OTA-DB must be an OTA database containing an update suitable for\n"
"  target database TARGET-DB. If NSTEP is set to less than or equal to zero\n"
"  (the default value), this program attempts to apply the entire update to\n"
"  the target database.\n"
"\n"
"  If NSTEP is greater than zero, then a maximum of NSTEP calls are made\n"
"  to sqlite3ota_step(). If the OTA update has not been completely applied\n"
"  after the NSTEP'th call is made, the state is saved in the database OTA-DB\n"
"  and the program exits. Subsequent invocations of this (or any other OTA)\n"
"  application will use this state to resume applying the OTA update to the\n"
"  target db.\n"
"\n"
, zArgv0);
  exit(1);
}

int main(int argc, char **argv){
  int i;
  const char *zTarget;            /* Target database to apply OTA to */
  const char *zOta;               /* Database containing OTA */
  char *zErrmsg;                  /* Error message, if any */
  sqlite3ota *pOta;               /* OTA handle */
  int nStep = 0;                  /* Maximum number of step() calls */
  int rc;

  /* Process command line arguments. Following this block local variables 
  ** zTarget, zOta and nStep are all set. */
  if( argc==5 ){
    int nArg1 = strlen(argv[1]);
    if( nArg1>5 || nArg1<2 || memcmp("-step", argv[1], nArg1) ) usage(argv[0]);
    nStep = atoi(argv[2]);
  }else if( argc!=3 ){
    usage(argv[0]);
  }
  zTarget = argv[argc-2];
  zOta = argv[argc-1];

  /* Open an OTA handle. If nStep is less than or equal to zero, call
  ** sqlite3ota_step() until either the OTA has been completely applied
  ** or an error occurs. Or, if nStep is greater than zero, call
  ** sqlite3ota_step() a maximum of nStep times.  */
  pOta = sqlite3ota_open(zTarget, zOta);
  for(i=0; (nStep<=0 || i<nStep) && sqlite3ota_step(pOta)==SQLITE_OK; i++);
  rc = sqlite3ota_close(pOta, &zErrmsg);

  /* Let the user know what happened. */
  switch( rc ){
    case SQLITE_OK:
      fprintf(stdout, "SQLITE_OK: ota update incomplete\n");
      break;

    case SQLITE_DONE:
      fprintf(stdout, "SQLITE_DONE: ota update completed\n");
      break;

    default:
      fprintf(stderr, "error=%d: %s\n", rc, zErrmsg);
      break;
  }

  sqlite3_free(zErrmsg);
  return (rc==SQLITE_OK || rc==SQLITE_DONE) ? 0 : 1;
}

Changes to ext/ota/sqlite3ota.h.
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
** For each row to DELETE from the target database as part of the OTA 
** update, the corresponding data_% table should contain a single record
** with the "ota_control" column set to contain integer value 1. The
** real primary key values of the row to delete should be stored in the
** corresponding columns of the data_% table. The values stored in the
** other columns are not used.
**
** For each row to DELETE from the target database as part of the OTA 
** update, the corresponding data_% table should contain a single record
** with the "ota_control" column set to contain a value of type text.
** The real primary key values identifying the row to update should be 
** stored in the corresponding columns of the data_% table row, as should
** the new values of all columns being update. The text value in the 
** "ota_control" column must contain the same number of characters as
** there are column in the target database table, and must consist entirely







|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
** For each row to DELETE from the target database as part of the OTA 
** update, the corresponding data_% table should contain a single record
** with the "ota_control" column set to contain integer value 1. The
** real primary key values of the row to delete should be stored in the
** corresponding columns of the data_% table. The values stored in the
** other columns are not used.
**
** For each row to UPDATE from the target database as part of the OTA 
** update, the corresponding data_% table should contain a single record
** with the "ota_control" column set to contain a value of type text.
** The real primary key values identifying the row to update should be 
** stored in the corresponding columns of the data_% table row, as should
** the new values of all columns being update. The text value in the 
** "ota_control" column must contain the same number of characters as
** there are column in the target database table, and must consist entirely
158
159
160
161
162
163
164


165
166
167
168
169
170
171
** To remove all OTA extension state information, returning an OTA database 
** to its original contents, it is sufficient to drop all tables that begin
** with the prefix "ota_"
*/

#ifndef _SQLITE3OTA_H
#define _SQLITE3OTA_H



typedef struct sqlite3ota sqlite3ota;

/*
** Open an OTA handle.
**
** Argument zTarget is the path to the target database. Argument zOta is







>
>







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
** To remove all OTA extension state information, returning an OTA database 
** to its original contents, it is sufficient to drop all tables that begin
** with the prefix "ota_"
*/

#ifndef _SQLITE3OTA_H
#define _SQLITE3OTA_H

#include <sqlite3.h>              /* Required for error code definitions */

typedef struct sqlite3ota sqlite3ota;

/*
** Open an OTA handle.
**
** Argument zTarget is the path to the target database. Argument zOta is
Changes to main.mk.
660
661
662
663
664
665
666





667
668
669
670
671
672
673

wordcount$(EXE):	$(TOP)/test/wordcount.c sqlite3.c
	$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o wordcount$(EXE) \
		$(TOP)/test/wordcount.c sqlite3.c

speedtest1$(EXE):	$(TOP)/test/speedtest1.c sqlite3.o
	$(TCC) -I. -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB)






# This target will fail if the SQLite amalgamation contains any exported
# symbols that do not begin with "sqlite3_". It is run as part of the
# releasetest.tcl script.
#
checksymbols: sqlite3.o
	nm -g --defined-only sqlite3.o | grep -v " sqlite3_" ; test $$? -ne 0







>
>
>
>
>







660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678

wordcount$(EXE):	$(TOP)/test/wordcount.c sqlite3.c
	$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o wordcount$(EXE) \
		$(TOP)/test/wordcount.c sqlite3.c

speedtest1$(EXE):	$(TOP)/test/speedtest1.c sqlite3.o
	$(TCC) -I. -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB)

ota$(EXE): $(TOP)/ext/ota/ota.c $(TOP)/ext/ota/sqlite3ota.c sqlite3.o 
	$(TCC) -I. -o ota$(EXE) \
	  $(TOP)/ext/ota/ota.c $(TOP)/ext/ota/sqlite3ota.c sqlite3.o \
	  $(THREADLIB)

# This target will fail if the SQLite amalgamation contains any exported
# symbols that do not begin with "sqlite3_". It is run as part of the
# releasetest.tcl script.
#
checksymbols: sqlite3.o
	nm -g --defined-only sqlite3.o | grep -v " sqlite3_" ; test $$? -ne 0