4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
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.
11 *************************************************************************
13 ** This file contains a command-line application that uses the RBU
14 ** extension. See the usage() function below for an explanation.
17 #include "sqlite3rbu.h"
23 ** Print a usage message and exit.
25 void usage(const char *zArgv0
){
27 "Usage: %s ?OPTIONS? TARGET-DB RBU-DB\n"
29 "Where options are:\n"
32 " -statstep NSTATSTEP\n"
36 " If the -vacuum switch is not present, argument RBU-DB must be an RBU\n"
37 " database containing an update suitable for target database TARGET-DB.\n"
38 " Or, if -vacuum is specified, then TARGET-DB is a database to vacuum using\n"
39 " RBU, and RBU-DB is used as the state database for the vacuum (refer to\n"
40 " API documentation for details).\n"
42 " If NSTEP is set to less than or equal to zero (the default value), this \n"
43 " program attempts to perform the entire update or vacuum operation before\n"
46 " If NSTEP is greater than zero, then a maximum of NSTEP calls are made\n"
47 " to sqlite3rbu_step(). If the RBU update has not been completely applied\n"
48 " after the NSTEP'th call is made, the state is saved in the database RBU-DB\n"
49 " and the program exits. Subsequent invocations of this (or any other RBU)\n"
50 " application will use this state to resume applying the RBU update to the\n"
57 void report_default_vfs(){
58 sqlite3_vfs
*pVfs
= sqlite3_vfs_find(0);
59 fprintf(stdout
, "default vfs is \"%s\"\n", pVfs
? pVfs
->zName
: "NULL");
62 void report_rbu_vfs(sqlite3rbu
*pRbu
){
63 sqlite3
*db
= sqlite3rbu_db(pRbu
, 0);
66 sqlite3_file_control(db
, "main", SQLITE_FCNTL_VFSNAME
, &zName
);
68 fprintf(stdout
, "using vfs \"%s\"\n", zName
);
70 fprintf(stdout
, "vfs name not available\n");
76 int main(int argc
, char **argv
){
78 const char *zTarget
; /* Target database to apply RBU to */
79 const char *zRbu
; /* Database containing RBU */
80 char zBuf
[200]; /* Buffer for printf() */
81 char *zErrmsg
= 0; /* Error message, if any */
82 sqlite3rbu
*pRbu
; /* RBU handle */
83 int nStep
= 0; /* Maximum number of step() calls */
84 int nStatStep
= 0; /* Report stats after this many step calls */
86 const char *zPreSql
= 0;
88 sqlite3_int64 nProgress
= 0;
91 if( argc
<3 ) usage(argv
[0]);
92 for(i
=1; i
<nArgc
; i
++){
93 const char *zArg
= argv
[i
];
94 int nArg
= strlen(zArg
);
95 if( nArg
>1 && nArg
<=8 && 0==memcmp(zArg
, "-vacuum", nArg
) ){
97 }else if( nArg
>1 && nArg
<=7
98 && 0==memcmp(zArg
, "-presql", nArg
) && i
<nArg
-1 ){
101 }else if( nArg
>1 && nArg
<=5 && 0==memcmp(zArg
, "-step", nArg
) && i
<nArg
-1 ){
103 nStep
= atoi(argv
[i
]);
104 }else if( nArg
>1 && nArg
<=9
105 && 0==memcmp(zArg
, "-statstep", nArg
) && i
<nArg
-1
108 nStatStep
= atoi(argv
[i
]);
114 zTarget
= argv
[argc
-2];
117 report_default_vfs();
119 /* Open an RBU handle. A vacuum handle if -vacuum was specified, or a
120 ** regular RBU update handle otherwise. */
122 pRbu
= sqlite3rbu_vacuum(zTarget
, zRbu
);
124 pRbu
= sqlite3rbu_open(zTarget
, zRbu
, 0);
126 report_rbu_vfs(pRbu
);
128 if( zPreSql
&& pRbu
){
129 sqlite3
*dbMain
= sqlite3rbu_db(pRbu
, 0);
130 rc
= sqlite3_exec(dbMain
, zPreSql
, 0, 0, 0);
132 sqlite3
*dbRbu
= sqlite3rbu_db(pRbu
, 1);
133 rc
= sqlite3_exec(dbRbu
, zPreSql
, 0, 0, 0);
137 /* If nStep is less than or equal to zero, call
138 ** sqlite3rbu_step() until either the RBU has been completely applied
139 ** or an error occurs. Or, if nStep is greater than zero, call
140 ** sqlite3rbu_step() a maximum of nStep times. */
142 for(i
=0; (nStep
<=0 || i
<nStep
) && sqlite3rbu_step(pRbu
)==SQLITE_OK
; i
++){
143 if( nStatStep
>0 && (i
% nStatStep
)==0 ){
145 sqlite3_int64 nHighwater
;
146 sqlite3_status64(SQLITE_STATUS_MEMORY_USED
, &nUsed
, &nHighwater
, 0);
147 fprintf(stdout
, "memory used=%lld highwater=%lld", nUsed
, nHighwater
);
151 sqlite3rbu_bp_progress(pRbu
, &one
, &two
);
152 fprintf(stdout
, " progress=%d/%d\n", one
, two
);
154 fprintf(stdout
, "\n");
159 nProgress
= sqlite3rbu_progress(pRbu
);
160 rc
= sqlite3rbu_close(pRbu
, &zErrmsg
);
163 /* Let the user know what happened. */
166 sqlite3_snprintf(sizeof(zBuf
), zBuf
,
167 "SQLITE_OK: rbu update incomplete (%lld operations so far)\n",
170 fprintf(stdout
, "%s", zBuf
);
174 sqlite3_snprintf(sizeof(zBuf
), zBuf
,
175 "SQLITE_DONE: rbu update completed (%lld operations)\n",
178 fprintf(stdout
, "%s", zBuf
);
182 fprintf(stderr
, "error=%d: %s\n", rc
, zErrmsg
);
188 sqlite3_int64 nHighwater
;
189 sqlite3_status64(SQLITE_STATUS_MEMORY_USED
, &nUsed
, &nHighwater
, 0);
190 fprintf(stdout
, "memory used=%lld highwater=%lld\n", nUsed
, nHighwater
);
193 sqlite3_free(zErrmsg
);
194 return (rc
==SQLITE_OK
|| rc
==SQLITE_DONE
) ? 0 : 1;