blob: cbb57e7774de6589edc6dc2515d1ec3e36cc7cf1 [file] [log] [blame]
drhd62c0f42015-04-09 13:34:29 +00001/*
2** 2015-04-06
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**
drh50be9c42015-04-17 12:16:09 +000013** This is a utility program that computes the differences in content
drhd62c0f42015-04-09 13:34:29 +000014** between two SQLite databases.
drh50be9c42015-04-17 12:16:09 +000015**
16** To compile, simply link against SQLite.
17**
18** See the showHelp() routine below for a brief description of how to
19** run the utility.
drhd62c0f42015-04-09 13:34:29 +000020*/
21#include <stdio.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include <ctype.h>
25#include <string.h>
dana9ca8af2015-07-31 19:52:03 +000026#include <assert.h>
drhd62c0f42015-04-09 13:34:29 +000027#include "sqlite3.h"
28
29/*
30** All global variables are gathered into the "g" singleton.
31*/
32struct GlobalVars {
33 const char *zArgv0; /* Name of program */
34 int bSchemaOnly; /* Only show schema differences */
drha37591c2015-04-09 18:14:03 +000035 int bSchemaPK; /* Use the schema-defined PK, not the true PK */
dan9c987a82016-06-21 10:34:41 +000036 int bHandleVtab; /* Handle fts3, fts4, fts5 and rtree vtabs */
drhd62c0f42015-04-09 13:34:29 +000037 unsigned fDebug; /* Debug flags */
38 sqlite3 *db; /* The database connection */
39} g;
40
41/*
42** Allowed values for g.fDebug
43*/
44#define DEBUG_COLUMN_NAMES 0x000001
45#define DEBUG_DIFF_SQL 0x000002
46
47/*
48** Dynamic string object
49*/
50typedef struct Str Str;
51struct Str {
52 char *z; /* Text of the string */
53 int nAlloc; /* Bytes allocated in z[] */
54 int nUsed; /* Bytes actually used in z[] */
55};
56
57/*
58** Initialize a Str object
59*/
60static void strInit(Str *p){
61 p->z = 0;
62 p->nAlloc = 0;
63 p->nUsed = 0;
64}
65
66/*
67** Print an error resulting from faulting command-line arguments and
68** abort the program.
69*/
70static void cmdlineError(const char *zFormat, ...){
71 va_list ap;
72 fprintf(stderr, "%s: ", g.zArgv0);
73 va_start(ap, zFormat);
74 vfprintf(stderr, zFormat, ap);
75 va_end(ap);
76 fprintf(stderr, "\n\"%s --help\" for more help\n", g.zArgv0);
77 exit(1);
78}
79
80/*
81** Print an error message for an error that occurs at runtime, then
82** abort the program.
83*/
84static void runtimeError(const char *zFormat, ...){
85 va_list ap;
86 fprintf(stderr, "%s: ", g.zArgv0);
87 va_start(ap, zFormat);
88 vfprintf(stderr, zFormat, ap);
89 va_end(ap);
90 fprintf(stderr, "\n");
91 exit(1);
92}
93
94/*
95** Free all memory held by a Str object
96*/
97static void strFree(Str *p){
98 sqlite3_free(p->z);
99 strInit(p);
100}
101
102/*
103** Add formatted text to the end of a Str object
104*/
105static void strPrintf(Str *p, const char *zFormat, ...){
106 int nNew;
107 for(;;){
108 if( p->z ){
109 va_list ap;
110 va_start(ap, zFormat);
111 sqlite3_vsnprintf(p->nAlloc-p->nUsed, p->z+p->nUsed, zFormat, ap);
112 va_end(ap);
113 nNew = (int)strlen(p->z + p->nUsed);
114 }else{
115 nNew = p->nAlloc;
116 }
117 if( p->nUsed+nNew < p->nAlloc-1 ){
118 p->nUsed += nNew;
119 break;
120 }
121 p->nAlloc = p->nAlloc*2 + 1000;
122 p->z = sqlite3_realloc(p->z, p->nAlloc);
123 if( p->z==0 ) runtimeError("out of memory");
124 }
125}
126
127
128
129/* Safely quote an SQL identifier. Use the minimum amount of transformation
130** necessary to allow the string to be used with %s.
131**
132** Space to hold the returned string is obtained from sqlite3_malloc(). The
133** caller is responsible for ensuring this space is freed when no longer
134** needed.
135*/
136static char *safeId(const char *zId){
137 /* All SQLite keywords, in alphabetical order */
138 static const char *azKeywords[] = {
139 "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
140 "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
141 "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
142 "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
143 "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
144 "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
145 "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
146 "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
147 "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
148 "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
149 "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
150 "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
151 "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
152 "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
153 "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
154 "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
155 "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
156 "WITH", "WITHOUT",
157 };
158 int lwr, upr, mid, c, i, x;
drh06db66f2015-11-29 21:46:19 +0000159 if( zId[0]==0 ) return sqlite3_mprintf("\"\"");
drhd62c0f42015-04-09 13:34:29 +0000160 for(i=x=0; (c = zId[i])!=0; i++){
161 if( !isalpha(c) && c!='_' ){
162 if( i>0 && isdigit(c) ){
163 x++;
164 }else{
165 return sqlite3_mprintf("\"%w\"", zId);
166 }
167 }
168 }
169 if( x ) return sqlite3_mprintf("%s", zId);
170 lwr = 0;
171 upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1;
172 while( lwr<=upr ){
173 mid = (lwr+upr)/2;
174 c = sqlite3_stricmp(azKeywords[mid], zId);
175 if( c==0 ) return sqlite3_mprintf("\"%w\"", zId);
176 if( c<0 ){
177 lwr = mid+1;
178 }else{
179 upr = mid-1;
180 }
181 }
182 return sqlite3_mprintf("%s", zId);
183}
184
185/*
186** Prepare a new SQL statement. Print an error and abort if anything
187** goes wrong.
188*/
189static sqlite3_stmt *db_vprepare(const char *zFormat, va_list ap){
190 char *zSql;
191 int rc;
192 sqlite3_stmt *pStmt;
193
194 zSql = sqlite3_vmprintf(zFormat, ap);
195 if( zSql==0 ) runtimeError("out of memory");
196 rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt, 0);
197 if( rc ){
198 runtimeError("SQL statement error: %s\n\"%s\"", sqlite3_errmsg(g.db),
199 zSql);
200 }
201 sqlite3_free(zSql);
202 return pStmt;
203}
204static sqlite3_stmt *db_prepare(const char *zFormat, ...){
205 va_list ap;
206 sqlite3_stmt *pStmt;
207 va_start(ap, zFormat);
208 pStmt = db_vprepare(zFormat, ap);
209 va_end(ap);
210 return pStmt;
211}
212
213/*
214** Free a list of strings
215*/
216static void namelistFree(char **az){
217 if( az ){
218 int i;
219 for(i=0; az[i]; i++) sqlite3_free(az[i]);
220 sqlite3_free(az);
221 }
222}
223
224/*
225** Return a list of column names for the table zDb.zTab. Space to
drh39b355c2015-04-09 13:40:18 +0000226** hold the list is obtained from sqlite3_malloc() and should released
227** using namelistFree() when no longer needed.
drhd62c0f42015-04-09 13:34:29 +0000228**
drha37591c2015-04-09 18:14:03 +0000229** Primary key columns are listed first, followed by data columns.
230** The number of columns in the primary key is returned in *pnPkey.
drhd62c0f42015-04-09 13:34:29 +0000231**
drha37591c2015-04-09 18:14:03 +0000232** Normally, the "primary key" in the previous sentence is the true
233** primary key - the rowid or INTEGER PRIMARY KEY for ordinary tables
234** or the declared PRIMARY KEY for WITHOUT ROWID tables. However, if
235** the g.bSchemaPK flag is set, then the schema-defined PRIMARY KEY is
236** used in all cases. In that case, entries that have NULL values in
237** any of their primary key fields will be excluded from the analysis.
238**
239** If the primary key for a table is the rowid but rowid is inaccessible,
drhd62c0f42015-04-09 13:34:29 +0000240** then this routine returns a NULL pointer.
241**
242** Examples:
243** CREATE TABLE t1(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(c));
244** *pnPKey = 1;
drha37591c2015-04-09 18:14:03 +0000245** az = { "rowid", "a", "b", "c", 0 } // Normal case
246** az = { "c", "a", "b", 0 } // g.bSchemaPK==1
drhd62c0f42015-04-09 13:34:29 +0000247**
248** CREATE TABLE t2(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(b));
249** *pnPKey = 1;
250** az = { "b", "a", "c", 0 }
251**
252** CREATE TABLE t3(x,y,z,PRIMARY KEY(y,z));
drha37591c2015-04-09 18:14:03 +0000253** *pnPKey = 1 // Normal case
254** az = { "rowid", "x", "y", "z", 0 } // Normal case
255** *pnPKey = 2 // g.bSchemaPK==1
256** az = { "y", "x", "z", 0 } // g.bSchemaPK==1
drhd62c0f42015-04-09 13:34:29 +0000257**
258** CREATE TABLE t4(x,y,z,PRIMARY KEY(y,z)) WITHOUT ROWID;
259** *pnPKey = 2
260** az = { "y", "z", "x", 0 }
261**
262** CREATE TABLE t5(rowid,_rowid_,oid);
263** az = 0 // The rowid is not accessible
264*/
dan99461852015-07-30 20:26:16 +0000265static char **columnNames(
266 const char *zDb, /* Database ("main" or "aux") to query */
267 const char *zTab, /* Name of table to return details of */
268 int *pnPKey, /* OUT: Number of PK columns */
269 int *pbRowid /* OUT: True if PK is an implicit rowid */
270){
drha37591c2015-04-09 18:14:03 +0000271 char **az = 0; /* List of column names to be returned */
272 int naz = 0; /* Number of entries in az[] */
273 sqlite3_stmt *pStmt; /* SQL statement being run */
drhd62c0f42015-04-09 13:34:29 +0000274 char *zPkIdxName = 0; /* Name of the PRIMARY KEY index */
drha37591c2015-04-09 18:14:03 +0000275 int truePk = 0; /* PRAGMA table_info indentifies the PK to use */
drhd62c0f42015-04-09 13:34:29 +0000276 int nPK = 0; /* Number of PRIMARY KEY columns */
drha37591c2015-04-09 18:14:03 +0000277 int i, j; /* Loop counters */
drhd62c0f42015-04-09 13:34:29 +0000278
drha37591c2015-04-09 18:14:03 +0000279 if( g.bSchemaPK==0 ){
280 /* Normal case: Figure out what the true primary key is for the table.
281 ** * For WITHOUT ROWID tables, the true primary key is the same as
282 ** the schema PRIMARY KEY, which is guaranteed to be present.
283 ** * For rowid tables with an INTEGER PRIMARY KEY, the true primary
284 ** key is the INTEGER PRIMARY KEY.
285 ** * For all other rowid tables, the rowid is the true primary key.
286 */
287 pStmt = db_prepare("PRAGMA %s.index_list=%Q", zDb, zTab);
drhd62c0f42015-04-09 13:34:29 +0000288 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drha37591c2015-04-09 18:14:03 +0000289 if( sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,3),"pk")==0 ){
290 zPkIdxName = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
291 break;
292 }
drhd62c0f42015-04-09 13:34:29 +0000293 }
294 sqlite3_finalize(pStmt);
drha37591c2015-04-09 18:14:03 +0000295 if( zPkIdxName ){
296 int nKey = 0;
297 int nCol = 0;
298 truePk = 0;
299 pStmt = db_prepare("PRAGMA %s.index_xinfo=%Q", zDb, zPkIdxName);
300 while( SQLITE_ROW==sqlite3_step(pStmt) ){
301 nCol++;
302 if( sqlite3_column_int(pStmt,5) ){ nKey++; continue; }
303 if( sqlite3_column_int(pStmt,1)>=0 ) truePk = 1;
304 }
305 if( nCol==nKey ) truePk = 1;
306 if( truePk ){
307 nPK = nKey;
308 }else{
309 nPK = 1;
310 }
311 sqlite3_finalize(pStmt);
312 sqlite3_free(zPkIdxName);
313 }else{
314 truePk = 1;
315 nPK = 1;
316 }
317 pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
drhd62c0f42015-04-09 13:34:29 +0000318 }else{
drha37591c2015-04-09 18:14:03 +0000319 /* The g.bSchemaPK==1 case: Use whatever primary key is declared
320 ** in the schema. The "rowid" will still be used as the primary key
321 ** if the table definition does not contain a PRIMARY KEY.
322 */
323 nPK = 0;
324 pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
325 while( SQLITE_ROW==sqlite3_step(pStmt) ){
326 if( sqlite3_column_int(pStmt,5)>0 ) nPK++;
327 }
328 sqlite3_reset(pStmt);
329 if( nPK==0 ) nPK = 1;
drhd62c0f42015-04-09 13:34:29 +0000330 truePk = 1;
drhd62c0f42015-04-09 13:34:29 +0000331 }
332 *pnPKey = nPK;
333 naz = nPK;
334 az = sqlite3_malloc( sizeof(char*)*(nPK+1) );
335 if( az==0 ) runtimeError("out of memory");
336 memset(az, 0, sizeof(char*)*(nPK+1));
drhd62c0f42015-04-09 13:34:29 +0000337 while( SQLITE_ROW==sqlite3_step(pStmt) ){
338 int iPKey;
339 if( truePk && (iPKey = sqlite3_column_int(pStmt,5))>0 ){
340 az[iPKey-1] = safeId((char*)sqlite3_column_text(pStmt,1));
341 }else{
342 az = sqlite3_realloc(az, sizeof(char*)*(naz+2) );
343 if( az==0 ) runtimeError("out of memory");
344 az[naz++] = safeId((char*)sqlite3_column_text(pStmt,1));
345 }
346 }
347 sqlite3_finalize(pStmt);
348 if( az ) az[naz] = 0;
dan99461852015-07-30 20:26:16 +0000349
350 /* If it is non-NULL, set *pbRowid to indicate whether or not the PK of
351 ** this table is an implicit rowid (*pbRowid==1) or not (*pbRowid==0). */
352 if( pbRowid ) *pbRowid = (az[0]==0);
353
354 /* If this table has an implicit rowid for a PK, figure out how to refer
355 ** to it. There are three options - "rowid", "_rowid_" and "oid". Any
356 ** of these will work, unless the table has an explicit column of the
357 ** same name. */
drhd62c0f42015-04-09 13:34:29 +0000358 if( az[0]==0 ){
359 const char *azRowid[] = { "rowid", "_rowid_", "oid" };
360 for(i=0; i<sizeof(azRowid)/sizeof(azRowid[0]); i++){
361 for(j=1; j<naz; j++){
362 if( sqlite3_stricmp(az[j], azRowid[i])==0 ) break;
363 }
364 if( j>=naz ){
365 az[0] = sqlite3_mprintf("%s", azRowid[i]);
366 break;
367 }
368 }
369 if( az[0]==0 ){
370 for(i=1; i<naz; i++) sqlite3_free(az[i]);
371 sqlite3_free(az);
372 az = 0;
373 }
374 }
375 return az;
376}
377
378/*
379** Print the sqlite3_value X as an SQL literal.
380*/
drh8a1cd762015-04-14 19:01:08 +0000381static void printQuoted(FILE *out, sqlite3_value *X){
drhd62c0f42015-04-09 13:34:29 +0000382 switch( sqlite3_value_type(X) ){
383 case SQLITE_FLOAT: {
384 double r1;
385 char zBuf[50];
386 r1 = sqlite3_value_double(X);
387 sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
drh8a1cd762015-04-14 19:01:08 +0000388 fprintf(out, "%s", zBuf);
drhd62c0f42015-04-09 13:34:29 +0000389 break;
390 }
391 case SQLITE_INTEGER: {
drh8a1cd762015-04-14 19:01:08 +0000392 fprintf(out, "%lld", sqlite3_value_int64(X));
drhd62c0f42015-04-09 13:34:29 +0000393 break;
394 }
395 case SQLITE_BLOB: {
396 const unsigned char *zBlob = sqlite3_value_blob(X);
397 int nBlob = sqlite3_value_bytes(X);
398 if( zBlob ){
399 int i;
drh8a1cd762015-04-14 19:01:08 +0000400 fprintf(out, "x'");
drhd62c0f42015-04-09 13:34:29 +0000401 for(i=0; i<nBlob; i++){
drh8a1cd762015-04-14 19:01:08 +0000402 fprintf(out, "%02x", zBlob[i]);
drhd62c0f42015-04-09 13:34:29 +0000403 }
drh8a1cd762015-04-14 19:01:08 +0000404 fprintf(out, "'");
drhd62c0f42015-04-09 13:34:29 +0000405 }else{
drh8a1cd762015-04-14 19:01:08 +0000406 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000407 }
408 break;
409 }
410 case SQLITE_TEXT: {
411 const unsigned char *zArg = sqlite3_value_text(X);
412 int i, j;
413
414 if( zArg==0 ){
drh8a1cd762015-04-14 19:01:08 +0000415 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000416 }else{
drh8a1cd762015-04-14 19:01:08 +0000417 fprintf(out, "'");
drhd62c0f42015-04-09 13:34:29 +0000418 for(i=j=0; zArg[i]; i++){
419 if( zArg[i]=='\'' ){
drh8a1cd762015-04-14 19:01:08 +0000420 fprintf(out, "%.*s'", i-j+1, &zArg[j]);
drhd62c0f42015-04-09 13:34:29 +0000421 j = i+1;
422 }
423 }
drh8a1cd762015-04-14 19:01:08 +0000424 fprintf(out, "%s'", &zArg[j]);
drhd62c0f42015-04-09 13:34:29 +0000425 }
426 break;
427 }
428 case SQLITE_NULL: {
drh8a1cd762015-04-14 19:01:08 +0000429 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000430 break;
431 }
432 }
433}
434
435/*
436** Output SQL that will recreate the aux.zTab table.
437*/
drh8a1cd762015-04-14 19:01:08 +0000438static void dump_table(const char *zTab, FILE *out){
drhd62c0f42015-04-09 13:34:29 +0000439 char *zId = safeId(zTab); /* Name of the table */
440 char **az = 0; /* List of columns */
441 int nPk; /* Number of true primary key columns */
442 int nCol; /* Number of data columns */
443 int i; /* Loop counter */
444 sqlite3_stmt *pStmt; /* SQL statement */
445 const char *zSep; /* Separator string */
446 Str ins; /* Beginning of the INSERT statement */
447
448 pStmt = db_prepare("SELECT sql FROM aux.sqlite_master WHERE name=%Q", zTab);
449 if( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000450 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000451 }
452 sqlite3_finalize(pStmt);
453 if( !g.bSchemaOnly ){
dan99461852015-07-30 20:26:16 +0000454 az = columnNames("aux", zTab, &nPk, 0);
drhd62c0f42015-04-09 13:34:29 +0000455 strInit(&ins);
456 if( az==0 ){
457 pStmt = db_prepare("SELECT * FROM aux.%s", zId);
458 strPrintf(&ins,"INSERT INTO %s VALUES", zId);
459 }else{
460 Str sql;
461 strInit(&sql);
462 zSep = "SELECT";
463 for(i=0; az[i]; i++){
464 strPrintf(&sql, "%s %s", zSep, az[i]);
465 zSep = ",";
466 }
467 strPrintf(&sql," FROM aux.%s", zId);
468 zSep = " ORDER BY";
469 for(i=1; i<=nPk; i++){
470 strPrintf(&sql, "%s %d", zSep, i);
471 zSep = ",";
472 }
473 pStmt = db_prepare("%s", sql.z);
474 strFree(&sql);
475 strPrintf(&ins, "INSERT INTO %s", zId);
476 zSep = "(";
477 for(i=0; az[i]; i++){
478 strPrintf(&ins, "%s%s", zSep, az[i]);
479 zSep = ",";
480 }
481 strPrintf(&ins,") VALUES");
482 namelistFree(az);
483 }
484 nCol = sqlite3_column_count(pStmt);
485 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000486 fprintf(out, "%s",ins.z);
drhd62c0f42015-04-09 13:34:29 +0000487 zSep = "(";
488 for(i=0; i<nCol; i++){
drh8a1cd762015-04-14 19:01:08 +0000489 fprintf(out, "%s",zSep);
490 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000491 zSep = ",";
492 }
drh8a1cd762015-04-14 19:01:08 +0000493 fprintf(out, ");\n");
drhd62c0f42015-04-09 13:34:29 +0000494 }
495 sqlite3_finalize(pStmt);
496 strFree(&ins);
497 } /* endif !g.bSchemaOnly */
498 pStmt = db_prepare("SELECT sql FROM aux.sqlite_master"
499 " WHERE type='index' AND tbl_name=%Q AND sql IS NOT NULL",
500 zTab);
501 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000502 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000503 }
504 sqlite3_finalize(pStmt);
505}
506
507
508/*
509** Compute all differences for a single table.
510*/
drh8a1cd762015-04-14 19:01:08 +0000511static void diff_one_table(const char *zTab, FILE *out){
drhd62c0f42015-04-09 13:34:29 +0000512 char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
513 char **az = 0; /* Columns in main */
514 char **az2 = 0; /* Columns in aux */
515 int nPk; /* Primary key columns in main */
516 int nPk2; /* Primary key columns in aux */
drhb3f3d642015-04-25 18:39:21 +0000517 int n = 0; /* Number of columns in main */
drhd62c0f42015-04-09 13:34:29 +0000518 int n2; /* Number of columns in aux */
519 int nQ; /* Number of output columns in the diff query */
520 int i; /* Loop counter */
521 const char *zSep; /* Separator string */
522 Str sql; /* Comparison query */
523 sqlite3_stmt *pStmt; /* Query statement to do the diff */
524
525 strInit(&sql);
526 if( g.fDebug==DEBUG_COLUMN_NAMES ){
527 /* Simply run columnNames() on all tables of the origin
528 ** database and show the results. This is used for testing
529 ** and debugging of the columnNames() function.
530 */
dan99461852015-07-30 20:26:16 +0000531 az = columnNames("aux",zTab, &nPk, 0);
drhd62c0f42015-04-09 13:34:29 +0000532 if( az==0 ){
533 printf("Rowid not accessible for %s\n", zId);
534 }else{
535 printf("%s:", zId);
536 for(i=0; az[i]; i++){
537 printf(" %s", az[i]);
538 if( i+1==nPk ) printf(" *");
539 }
540 printf("\n");
541 }
542 goto end_diff_one_table;
543 }
544
545
546 if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
547 if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
548 /* Table missing from second database. */
drh8a1cd762015-04-14 19:01:08 +0000549 fprintf(out, "DROP TABLE %s;\n", zId);
drhd62c0f42015-04-09 13:34:29 +0000550 }
551 goto end_diff_one_table;
552 }
553
554 if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
555 /* Table missing from source */
drh8a1cd762015-04-14 19:01:08 +0000556 dump_table(zTab, out);
drhd62c0f42015-04-09 13:34:29 +0000557 goto end_diff_one_table;
558 }
559
dan99461852015-07-30 20:26:16 +0000560 az = columnNames("main", zTab, &nPk, 0);
561 az2 = columnNames("aux", zTab, &nPk2, 0);
drhd62c0f42015-04-09 13:34:29 +0000562 if( az && az2 ){
drhedd22602015-11-07 18:32:17 +0000563 for(n=0; az[n] && az2[n]; n++){
drhd62c0f42015-04-09 13:34:29 +0000564 if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
565 }
566 }
567 if( az==0
568 || az2==0
569 || nPk!=nPk2
570 || az[n]
571 ){
572 /* Schema mismatch */
drhedd22602015-11-07 18:32:17 +0000573 fprintf(out, "DROP TABLE %s; -- due to schema mismatch\n", zId);
drh8a1cd762015-04-14 19:01:08 +0000574 dump_table(zTab, out);
drhd62c0f42015-04-09 13:34:29 +0000575 goto end_diff_one_table;
576 }
577
578 /* Build the comparison query */
drhedd22602015-11-07 18:32:17 +0000579 for(n2=n; az2[n2]; n2++){
580 fprintf(out, "ALTER TABLE %s ADD COLUMN %s;\n", zId, safeId(az2[n2]));
581 }
drhd62c0f42015-04-09 13:34:29 +0000582 nQ = nPk2+1+2*(n2-nPk2);
583 if( n2>nPk2 ){
584 zSep = "SELECT ";
585 for(i=0; i<nPk; i++){
586 strPrintf(&sql, "%sB.%s", zSep, az[i]);
587 zSep = ", ";
588 }
589 strPrintf(&sql, ", 1%s -- changed row\n", nPk==n ? "" : ",");
590 while( az[i] ){
591 strPrintf(&sql, " A.%s IS NOT B.%s, B.%s%s\n",
drhedd22602015-11-07 18:32:17 +0000592 az[i], az2[i], az2[i], az2[i+1]==0 ? "" : ",");
593 i++;
594 }
595 while( az2[i] ){
596 strPrintf(&sql, " B.%s IS NOT NULL, B.%s%s\n",
597 az2[i], az2[i], az2[i+1]==0 ? "" : ",");
drhd62c0f42015-04-09 13:34:29 +0000598 i++;
599 }
600 strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId);
601 zSep = " WHERE";
602 for(i=0; i<nPk; i++){
603 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
604 zSep = " AND";
605 }
606 zSep = "\n AND (";
607 while( az[i] ){
608 strPrintf(&sql, "%sA.%s IS NOT B.%s%s\n",
drhedd22602015-11-07 18:32:17 +0000609 zSep, az[i], az2[i], az2[i+1]==0 ? ")" : "");
610 zSep = " OR ";
611 i++;
612 }
613 while( az2[i] ){
614 strPrintf(&sql, "%sB.%s IS NOT NULL%s\n",
615 zSep, az2[i], az2[i+1]==0 ? ")" : "");
drhd62c0f42015-04-09 13:34:29 +0000616 zSep = " OR ";
617 i++;
618 }
619 strPrintf(&sql, " UNION ALL\n");
620 }
621 zSep = "SELECT ";
622 for(i=0; i<nPk; i++){
623 strPrintf(&sql, "%sA.%s", zSep, az[i]);
624 zSep = ", ";
625 }
626 strPrintf(&sql, ", 2%s -- deleted row\n", nPk==n ? "" : ",");
drhedd22602015-11-07 18:32:17 +0000627 while( az2[i] ){
drhd62c0f42015-04-09 13:34:29 +0000628 strPrintf(&sql, " NULL, NULL%s\n", i==n2-1 ? "" : ",");
629 i++;
630 }
631 strPrintf(&sql, " FROM main.%s A\n", zId);
632 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B\n", zId);
633 zSep = " WHERE";
634 for(i=0; i<nPk; i++){
635 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
636 zSep = " AND";
637 }
638 strPrintf(&sql, ")\n");
639 zSep = " UNION ALL\nSELECT ";
640 for(i=0; i<nPk; i++){
641 strPrintf(&sql, "%sB.%s", zSep, az[i]);
642 zSep = ", ";
643 }
644 strPrintf(&sql, ", 3%s -- inserted row\n", nPk==n ? "" : ",");
645 while( az2[i] ){
drhedd22602015-11-07 18:32:17 +0000646 strPrintf(&sql, " 1, B.%s%s\n", az2[i], az2[i+1]==0 ? "" : ",");
drhd62c0f42015-04-09 13:34:29 +0000647 i++;
648 }
649 strPrintf(&sql, " FROM aux.%s B\n", zId);
650 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A\n", zId);
651 zSep = " WHERE";
652 for(i=0; i<nPk; i++){
653 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
654 zSep = " AND";
655 }
656 strPrintf(&sql, ")\n ORDER BY");
657 zSep = " ";
658 for(i=1; i<=nPk; i++){
659 strPrintf(&sql, "%s%d", zSep, i);
660 zSep = ", ";
661 }
662 strPrintf(&sql, ";\n");
663
664 if( g.fDebug & DEBUG_DIFF_SQL ){
665 printf("SQL for %s:\n%s\n", zId, sql.z);
666 goto end_diff_one_table;
667 }
668
669 /* Drop indexes that are missing in the destination */
670 pStmt = db_prepare(
671 "SELECT name FROM main.sqlite_master"
672 " WHERE type='index' AND tbl_name=%Q"
673 " AND sql IS NOT NULL"
674 " AND sql NOT IN (SELECT sql FROM aux.sqlite_master"
675 " WHERE type='index' AND tbl_name=%Q"
676 " AND sql IS NOT NULL)",
677 zTab, zTab);
678 while( SQLITE_ROW==sqlite3_step(pStmt) ){
679 char *z = safeId((const char*)sqlite3_column_text(pStmt,0));
drh8a1cd762015-04-14 19:01:08 +0000680 fprintf(out, "DROP INDEX %s;\n", z);
drhd62c0f42015-04-09 13:34:29 +0000681 sqlite3_free(z);
682 }
683 sqlite3_finalize(pStmt);
684
685 /* Run the query and output differences */
686 if( !g.bSchemaOnly ){
drh52254492016-07-08 02:14:24 +0000687 pStmt = db_prepare("%s", sql.z);
drhd62c0f42015-04-09 13:34:29 +0000688 while( SQLITE_ROW==sqlite3_step(pStmt) ){
689 int iType = sqlite3_column_int(pStmt, nPk);
690 if( iType==1 || iType==2 ){
691 if( iType==1 ){ /* Change the content of a row */
drh8a1cd762015-04-14 19:01:08 +0000692 fprintf(out, "UPDATE %s", zId);
drhd62c0f42015-04-09 13:34:29 +0000693 zSep = " SET";
694 for(i=nPk+1; i<nQ; i+=2){
695 if( sqlite3_column_int(pStmt,i)==0 ) continue;
drh8a1cd762015-04-14 19:01:08 +0000696 fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]);
drhd62c0f42015-04-09 13:34:29 +0000697 zSep = ",";
drh8a1cd762015-04-14 19:01:08 +0000698 printQuoted(out, sqlite3_column_value(pStmt,i+1));
drhd62c0f42015-04-09 13:34:29 +0000699 }
700 }else{ /* Delete a row */
drh8a1cd762015-04-14 19:01:08 +0000701 fprintf(out, "DELETE FROM %s", zId);
drhd62c0f42015-04-09 13:34:29 +0000702 }
703 zSep = " WHERE";
704 for(i=0; i<nPk; i++){
drh8a1cd762015-04-14 19:01:08 +0000705 fprintf(out, "%s %s=", zSep, az2[i]);
706 printQuoted(out, sqlite3_column_value(pStmt,i));
drh74504942015-11-09 12:47:04 +0000707 zSep = " AND";
drhd62c0f42015-04-09 13:34:29 +0000708 }
drh8a1cd762015-04-14 19:01:08 +0000709 fprintf(out, ";\n");
drhd62c0f42015-04-09 13:34:29 +0000710 }else{ /* Insert a row */
drh8a1cd762015-04-14 19:01:08 +0000711 fprintf(out, "INSERT INTO %s(%s", zId, az2[0]);
712 for(i=1; az2[i]; i++) fprintf(out, ",%s", az2[i]);
713 fprintf(out, ") VALUES");
drhd62c0f42015-04-09 13:34:29 +0000714 zSep = "(";
715 for(i=0; i<nPk2; i++){
drh8a1cd762015-04-14 19:01:08 +0000716 fprintf(out, "%s", zSep);
drhd62c0f42015-04-09 13:34:29 +0000717 zSep = ",";
drh8a1cd762015-04-14 19:01:08 +0000718 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000719 }
720 for(i=nPk2+2; i<nQ; i+=2){
drh8a1cd762015-04-14 19:01:08 +0000721 fprintf(out, ",");
722 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000723 }
drh8a1cd762015-04-14 19:01:08 +0000724 fprintf(out, ");\n");
drhd62c0f42015-04-09 13:34:29 +0000725 }
726 }
727 sqlite3_finalize(pStmt);
728 } /* endif !g.bSchemaOnly */
729
730 /* Create indexes that are missing in the source */
731 pStmt = db_prepare(
732 "SELECT sql FROM aux.sqlite_master"
733 " WHERE type='index' AND tbl_name=%Q"
734 " AND sql IS NOT NULL"
735 " AND sql NOT IN (SELECT sql FROM main.sqlite_master"
736 " WHERE type='index' AND tbl_name=%Q"
737 " AND sql IS NOT NULL)",
738 zTab, zTab);
739 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000740 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000741 }
742 sqlite3_finalize(pStmt);
743
744end_diff_one_table:
745 strFree(&sql);
746 sqlite3_free(zId);
747 namelistFree(az);
748 namelistFree(az2);
749 return;
750}
751
752/*
dan99461852015-07-30 20:26:16 +0000753** Check that table zTab exists and has the same schema in both the "main"
754** and "aux" databases currently opened by the global db handle. If they
755** do not, output an error message on stderr and exit(1). Otherwise, if
756** the schemas do match, return control to the caller.
757*/
758static void checkSchemasMatch(const char *zTab){
759 sqlite3_stmt *pStmt = db_prepare(
760 "SELECT A.sql=B.sql FROM main.sqlite_master A, aux.sqlite_master B"
761 " WHERE A.name=%Q AND B.name=%Q", zTab, zTab
762 );
763 if( SQLITE_ROW==sqlite3_step(pStmt) ){
764 if( sqlite3_column_int(pStmt,0)==0 ){
765 runtimeError("schema changes for table %s", safeId(zTab));
766 }
767 }else{
768 runtimeError("table %s missing from one or both databases", safeId(zTab));
769 }
770 sqlite3_finalize(pStmt);
771}
772
dana9ca8af2015-07-31 19:52:03 +0000773/**************************************************************************
774** The following code is copied from fossil. It is used to generate the
775** fossil delta blobs sometimes used in RBU update records.
776*/
777
778typedef unsigned short u16;
779typedef unsigned int u32;
780typedef unsigned char u8;
781
782/*
783** The width of a hash window in bytes. The algorithm only works if this
784** is a power of 2.
785*/
786#define NHASH 16
787
788/*
789** The current state of the rolling hash.
790**
791** z[] holds the values that have been hashed. z[] is a circular buffer.
792** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
793** the window.
794**
795** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted
796** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1.
797** (Each index for z[] should be module NHASH, of course. The %NHASH operator
798** is omitted in the prior expression for brevity.)
799*/
800typedef struct hash hash;
801struct hash {
802 u16 a, b; /* Hash values */
803 u16 i; /* Start of the hash window */
804 char z[NHASH]; /* The values that have been hashed */
805};
806
807/*
808** Initialize the rolling hash using the first NHASH characters of z[]
809*/
810static void hash_init(hash *pHash, const char *z){
811 u16 a, b, i;
812 a = b = 0;
813 for(i=0; i<NHASH; i++){
814 a += z[i];
815 b += (NHASH-i)*z[i];
816 pHash->z[i] = z[i];
817 }
818 pHash->a = a & 0xffff;
819 pHash->b = b & 0xffff;
820 pHash->i = 0;
821}
822
823/*
824** Advance the rolling hash by a single character "c"
825*/
826static void hash_next(hash *pHash, int c){
827 u16 old = pHash->z[pHash->i];
mistachkin1abbe282015-08-20 21:09:32 +0000828 pHash->z[pHash->i] = (char)c;
dana9ca8af2015-07-31 19:52:03 +0000829 pHash->i = (pHash->i+1)&(NHASH-1);
mistachkin1abbe282015-08-20 21:09:32 +0000830 pHash->a = pHash->a - old + (char)c;
dana9ca8af2015-07-31 19:52:03 +0000831 pHash->b = pHash->b - NHASH*old + pHash->a;
832}
833
834/*
835** Return a 32-bit hash value
836*/
837static u32 hash_32bit(hash *pHash){
838 return (pHash->a & 0xffff) | (((u32)(pHash->b & 0xffff))<<16);
839}
840
841/*
842** Write an base-64 integer into the given buffer.
843*/
844static void putInt(unsigned int v, char **pz){
845 static const char zDigits[] =
846 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
847 /* 123456789 123456789 123456789 123456789 123456789 123456789 123 */
848 int i, j;
849 char zBuf[20];
850 if( v==0 ){
851 *(*pz)++ = '0';
852 return;
853 }
854 for(i=0; v>0; i++, v>>=6){
855 zBuf[i] = zDigits[v&0x3f];
856 }
857 for(j=i-1; j>=0; j--){
858 *(*pz)++ = zBuf[j];
859 }
860}
861
862/*
dana9ca8af2015-07-31 19:52:03 +0000863** Return the number digits in the base-64 representation of a positive integer
864*/
865static int digit_count(int v){
866 unsigned int i, x;
mistachkin1abbe282015-08-20 21:09:32 +0000867 for(i=1, x=64; (unsigned int)v>=x; i++, x <<= 6){}
dana9ca8af2015-07-31 19:52:03 +0000868 return i;
869}
870
871/*
872** Compute a 32-bit checksum on the N-byte buffer. Return the result.
873*/
874static unsigned int checksum(const char *zIn, size_t N){
875 const unsigned char *z = (const unsigned char *)zIn;
876 unsigned sum0 = 0;
877 unsigned sum1 = 0;
878 unsigned sum2 = 0;
879 unsigned sum3 = 0;
880 while(N >= 16){
881 sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
882 sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
883 sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
884 sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
885 z += 16;
886 N -= 16;
887 }
888 while(N >= 4){
889 sum0 += z[0];
890 sum1 += z[1];
891 sum2 += z[2];
892 sum3 += z[3];
893 z += 4;
894 N -= 4;
895 }
896 sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
897 switch(N){
898 case 3: sum3 += (z[2] << 8);
899 case 2: sum3 += (z[1] << 16);
900 case 1: sum3 += (z[0] << 24);
901 default: ;
902 }
903 return sum3;
904}
905
906/*
907** Create a new delta.
908**
909** The delta is written into a preallocated buffer, zDelta, which
910** should be at least 60 bytes longer than the target file, zOut.
911** The delta string will be NUL-terminated, but it might also contain
912** embedded NUL characters if either the zSrc or zOut files are
913** binary. This function returns the length of the delta string
914** in bytes, excluding the final NUL terminator character.
915**
916** Output Format:
917**
918** The delta begins with a base64 number followed by a newline. This
919** number is the number of bytes in the TARGET file. Thus, given a
920** delta file z, a program can compute the size of the output file
921** simply by reading the first line and decoding the base-64 number
922** found there. The delta_output_size() routine does exactly this.
923**
924** After the initial size number, the delta consists of a series of
925** literal text segments and commands to copy from the SOURCE file.
926** A copy command looks like this:
927**
928** NNN@MMM,
929**
930** where NNN is the number of bytes to be copied and MMM is the offset
931** into the source file of the first byte (both base-64). If NNN is 0
932** it means copy the rest of the input file. Literal text is like this:
933**
934** NNN:TTTTT
935**
936** where NNN is the number of bytes of text (base-64) and TTTTT is the text.
937**
938** The last term is of the form
939**
940** NNN;
941**
942** In this case, NNN is a 32-bit bigendian checksum of the output file
943** that can be used to verify that the delta applied correctly. All
944** numbers are in base-64.
945**
946** Pure text files generate a pure text delta. Binary files generate a
947** delta that may contain some binary data.
948**
949** Algorithm:
950**
951** The encoder first builds a hash table to help it find matching
952** patterns in the source file. 16-byte chunks of the source file
953** sampled at evenly spaced intervals are used to populate the hash
954** table.
955**
956** Next we begin scanning the target file using a sliding 16-byte
957** window. The hash of the 16-byte window in the target is used to
958** search for a matching section in the source file. When a match
959** is found, a copy command is added to the delta. An effort is
960** made to extend the matching section to regions that come before
961** and after the 16-byte hash window. A copy command is only issued
962** if the result would use less space that just quoting the text
963** literally. Literal text is added to the delta for sections that
964** do not match or which can not be encoded efficiently using copy
965** commands.
966*/
967static int rbuDeltaCreate(
968 const char *zSrc, /* The source or pattern file */
969 unsigned int lenSrc, /* Length of the source file */
970 const char *zOut, /* The target file */
971 unsigned int lenOut, /* Length of the target file */
972 char *zDelta /* Write the delta into this buffer */
973){
mistachkin1abbe282015-08-20 21:09:32 +0000974 unsigned int i, base;
dana9ca8af2015-07-31 19:52:03 +0000975 char *zOrigDelta = zDelta;
976 hash h;
977 int nHash; /* Number of hash table entries */
978 int *landmark; /* Primary hash table */
979 int *collide; /* Collision chain */
980 int lastRead = -1; /* Last byte of zSrc read by a COPY command */
981
982 /* Add the target file size to the beginning of the delta
983 */
984 putInt(lenOut, &zDelta);
985 *(zDelta++) = '\n';
986
987 /* If the source file is very small, it means that we have no
988 ** chance of ever doing a copy command. Just output a single
989 ** literal segment for the entire target and exit.
990 */
991 if( lenSrc<=NHASH ){
992 putInt(lenOut, &zDelta);
993 *(zDelta++) = ':';
994 memcpy(zDelta, zOut, lenOut);
995 zDelta += lenOut;
996 putInt(checksum(zOut, lenOut), &zDelta);
997 *(zDelta++) = ';';
drh62e63bb2016-01-14 12:23:16 +0000998 return (int)(zDelta - zOrigDelta);
dana9ca8af2015-07-31 19:52:03 +0000999 }
1000
1001 /* Compute the hash table used to locate matching sections in the
1002 ** source file.
1003 */
1004 nHash = lenSrc/NHASH;
1005 collide = sqlite3_malloc( nHash*2*sizeof(int) );
1006 landmark = &collide[nHash];
1007 memset(landmark, -1, nHash*sizeof(int));
1008 memset(collide, -1, nHash*sizeof(int));
1009 for(i=0; i<lenSrc-NHASH; i+=NHASH){
1010 int hv;
1011 hash_init(&h, &zSrc[i]);
1012 hv = hash_32bit(&h) % nHash;
1013 collide[i/NHASH] = landmark[hv];
1014 landmark[hv] = i/NHASH;
1015 }
1016
1017 /* Begin scanning the target file and generating copy commands and
1018 ** literal sections of the delta.
1019 */
1020 base = 0; /* We have already generated everything before zOut[base] */
1021 while( base+NHASH<lenOut ){
1022 int iSrc, iBlock;
mistachkin1abbe282015-08-20 21:09:32 +00001023 int bestCnt, bestOfst=0, bestLitsz=0;
dana9ca8af2015-07-31 19:52:03 +00001024 hash_init(&h, &zOut[base]);
1025 i = 0; /* Trying to match a landmark against zOut[base+i] */
1026 bestCnt = 0;
1027 while( 1 ){
1028 int hv;
1029 int limit = 250;
1030
1031 hv = hash_32bit(&h) % nHash;
1032 iBlock = landmark[hv];
1033 while( iBlock>=0 && (limit--)>0 ){
1034 /*
1035 ** The hash window has identified a potential match against
1036 ** landmark block iBlock. But we need to investigate further.
1037 **
1038 ** Look for a region in zOut that matches zSrc. Anchor the search
1039 ** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to
1040 ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
1041 **
1042 ** Set cnt equal to the length of the match and set ofst so that
1043 ** zSrc[ofst] is the first element of the match. litsz is the number
1044 ** of characters between zOut[base] and the beginning of the match.
1045 ** sz will be the overhead (in bytes) needed to encode the copy
1046 ** command. Only generate copy command if the overhead of the
1047 ** copy command is less than the amount of literal text to be copied.
1048 */
1049 int cnt, ofst, litsz;
1050 int j, k, x, y;
1051 int sz;
1052
1053 /* Beginning at iSrc, match forwards as far as we can. j counts
1054 ** the number of characters that match */
1055 iSrc = iBlock*NHASH;
mistachkin1abbe282015-08-20 21:09:32 +00001056 for(
1057 j=0, x=iSrc, y=base+i;
1058 (unsigned int)x<lenSrc && (unsigned int)y<lenOut;
1059 j++, x++, y++
1060 ){
dana9ca8af2015-07-31 19:52:03 +00001061 if( zSrc[x]!=zOut[y] ) break;
1062 }
1063 j--;
1064
1065 /* Beginning at iSrc-1, match backwards as far as we can. k counts
1066 ** the number of characters that match */
mistachkin1abbe282015-08-20 21:09:32 +00001067 for(k=1; k<iSrc && (unsigned int)k<=i; k++){
dana9ca8af2015-07-31 19:52:03 +00001068 if( zSrc[iSrc-k]!=zOut[base+i-k] ) break;
1069 }
1070 k--;
1071
1072 /* Compute the offset and size of the matching region */
1073 ofst = iSrc-k;
1074 cnt = j+k+1;
1075 litsz = i-k; /* Number of bytes of literal text before the copy */
1076 /* sz will hold the number of bytes needed to encode the "insert"
1077 ** command and the copy command, not counting the "insert" text */
1078 sz = digit_count(i-k)+digit_count(cnt)+digit_count(ofst)+3;
1079 if( cnt>=sz && cnt>bestCnt ){
1080 /* Remember this match only if it is the best so far and it
1081 ** does not increase the file size */
1082 bestCnt = cnt;
1083 bestOfst = iSrc-k;
1084 bestLitsz = litsz;
1085 }
1086
1087 /* Check the next matching block */
1088 iBlock = collide[iBlock];
1089 }
1090
1091 /* We have a copy command that does not cause the delta to be larger
1092 ** than a literal insert. So add the copy command to the delta.
1093 */
1094 if( bestCnt>0 ){
1095 if( bestLitsz>0 ){
1096 /* Add an insert command before the copy */
1097 putInt(bestLitsz,&zDelta);
1098 *(zDelta++) = ':';
1099 memcpy(zDelta, &zOut[base], bestLitsz);
1100 zDelta += bestLitsz;
1101 base += bestLitsz;
1102 }
1103 base += bestCnt;
1104 putInt(bestCnt, &zDelta);
1105 *(zDelta++) = '@';
1106 putInt(bestOfst, &zDelta);
1107 *(zDelta++) = ',';
1108 if( bestOfst + bestCnt -1 > lastRead ){
1109 lastRead = bestOfst + bestCnt - 1;
1110 }
1111 bestCnt = 0;
1112 break;
1113 }
1114
1115 /* If we reach this point, it means no match is found so far */
1116 if( base+i+NHASH>=lenOut ){
1117 /* We have reached the end of the file and have not found any
1118 ** matches. Do an "insert" for everything that does not match */
1119 putInt(lenOut-base, &zDelta);
1120 *(zDelta++) = ':';
1121 memcpy(zDelta, &zOut[base], lenOut-base);
1122 zDelta += lenOut-base;
1123 base = lenOut;
1124 break;
1125 }
1126
1127 /* Advance the hash by one character. Keep looking for a match */
1128 hash_next(&h, zOut[base+i+NHASH]);
1129 i++;
1130 }
1131 }
1132 /* Output a final "insert" record to get all the text at the end of
1133 ** the file that does not match anything in the source file.
1134 */
1135 if( base<lenOut ){
1136 putInt(lenOut-base, &zDelta);
1137 *(zDelta++) = ':';
1138 memcpy(zDelta, &zOut[base], lenOut-base);
1139 zDelta += lenOut-base;
1140 }
1141 /* Output the final checksum record. */
1142 putInt(checksum(zOut, lenOut), &zDelta);
1143 *(zDelta++) = ';';
1144 sqlite3_free(collide);
drh62e63bb2016-01-14 12:23:16 +00001145 return (int)(zDelta - zOrigDelta);
dana9ca8af2015-07-31 19:52:03 +00001146}
1147
1148/*
1149** End of code copied from fossil.
1150**************************************************************************/
1151
dan99461852015-07-30 20:26:16 +00001152static void strPrintfArray(
1153 Str *pStr, /* String object to append to */
1154 const char *zSep, /* Separator string */
1155 const char *zFmt, /* Format for each entry */
1156 char **az, int n /* Array of strings & its size (or -1) */
1157){
1158 int i;
1159 for(i=0; az[i] && (i<n || n<0); i++){
1160 if( i!=0 ) strPrintf(pStr, "%s", zSep);
1161 strPrintf(pStr, zFmt, az[i], az[i], az[i]);
1162 }
1163}
1164
1165static void getRbudiffQuery(
1166 const char *zTab,
1167 char **azCol,
1168 int nPK,
1169 int bOtaRowid,
1170 Str *pSql
1171){
1172 int i;
1173
1174 /* First the newly inserted rows: **/
1175 strPrintf(pSql, "SELECT ");
1176 strPrintfArray(pSql, ", ", "%s", azCol, -1);
dana9ca8af2015-07-31 19:52:03 +00001177 strPrintf(pSql, ", 0, "); /* Set ota_control to 0 for an insert */
1178 strPrintfArray(pSql, ", ", "NULL", azCol, -1);
dan99461852015-07-30 20:26:16 +00001179 strPrintf(pSql, " FROM aux.%Q AS n WHERE NOT EXISTS (\n", zTab);
1180 strPrintf(pSql, " SELECT 1 FROM ", zTab);
1181 strPrintf(pSql, " main.%Q AS o WHERE ", zTab);
dane5a0cfa2016-09-01 14:03:28 +00001182 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
1183 strPrintf(pSql, "\n) AND ");
1184 strPrintfArray(pSql, " AND ", "(n.%Q IS NOT NULL)", azCol, nPK);
dan99461852015-07-30 20:26:16 +00001185
1186 /* Deleted rows: */
1187 strPrintf(pSql, "\nUNION ALL\nSELECT ");
1188 strPrintfArray(pSql, ", ", "%s", azCol, nPK);
dandd688e72015-07-31 15:13:29 +00001189 if( azCol[nPK] ){
1190 strPrintf(pSql, ", ");
1191 strPrintfArray(pSql, ", ", "NULL", &azCol[nPK], -1);
1192 }
dana9ca8af2015-07-31 19:52:03 +00001193 strPrintf(pSql, ", 1, "); /* Set ota_control to 1 for a delete */
1194 strPrintfArray(pSql, ", ", "NULL", azCol, -1);
dan99461852015-07-30 20:26:16 +00001195 strPrintf(pSql, " FROM main.%Q AS n WHERE NOT EXISTS (\n", zTab);
1196 strPrintf(pSql, " SELECT 1 FROM ", zTab);
1197 strPrintf(pSql, " aux.%Q AS o WHERE ", zTab);
dane5a0cfa2016-09-01 14:03:28 +00001198 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
1199 strPrintf(pSql, "\n) AND ");
1200 strPrintfArray(pSql, " AND ", "(n.%Q IS NOT NULL)", azCol, nPK);
dan99461852015-07-30 20:26:16 +00001201
dandd688e72015-07-31 15:13:29 +00001202 /* Updated rows. If all table columns are part of the primary key, there
1203 ** can be no updates. In this case this part of the compound SELECT can
1204 ** be omitted altogether. */
1205 if( azCol[nPK] ){
1206 strPrintf(pSql, "\nUNION ALL\nSELECT ");
1207 strPrintfArray(pSql, ", ", "n.%s", azCol, nPK);
dan99461852015-07-30 20:26:16 +00001208 strPrintf(pSql, ",\n");
dandd688e72015-07-31 15:13:29 +00001209 strPrintfArray(pSql, " ,\n",
1210 " CASE WHEN n.%s IS o.%s THEN NULL ELSE n.%s END", &azCol[nPK], -1
1211 );
dan99461852015-07-30 20:26:16 +00001212
dandd688e72015-07-31 15:13:29 +00001213 if( bOtaRowid==0 ){
1214 strPrintf(pSql, ", '");
1215 strPrintfArray(pSql, "", ".", azCol, nPK);
1216 strPrintf(pSql, "' ||\n");
1217 }else{
1218 strPrintf(pSql, ",\n");
1219 }
1220 strPrintfArray(pSql, " ||\n",
1221 " CASE WHEN n.%s IS o.%s THEN '.' ELSE 'x' END", &azCol[nPK], -1
1222 );
dana9ca8af2015-07-31 19:52:03 +00001223 strPrintf(pSql, "\nAS ota_control, ");
1224 strPrintfArray(pSql, ", ", "NULL", azCol, nPK);
1225 strPrintf(pSql, ",\n");
1226 strPrintfArray(pSql, " ,\n",
1227 " CASE WHEN n.%s IS o.%s THEN NULL ELSE o.%s END", &azCol[nPK], -1
1228 );
dandd688e72015-07-31 15:13:29 +00001229
1230 strPrintf(pSql, "\nFROM main.%Q AS o, aux.%Q AS n\nWHERE ", zTab, zTab);
dane5a0cfa2016-09-01 14:03:28 +00001231 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
dandd688e72015-07-31 15:13:29 +00001232 strPrintf(pSql, " AND ota_control LIKE '%%x%%'");
1233 }
dan99461852015-07-30 20:26:16 +00001234
1235 /* Now add an ORDER BY clause to sort everything by PK. */
1236 strPrintf(pSql, "\nORDER BY ");
1237 for(i=1; i<=nPK; i++) strPrintf(pSql, "%s%d", ((i>1)?", ":""), i);
1238}
1239
1240static void rbudiff_one_table(const char *zTab, FILE *out){
1241 int bOtaRowid; /* True to use an ota_rowid column */
1242 int nPK; /* Number of primary key columns in table */
1243 char **azCol; /* NULL terminated array of col names */
1244 int i;
1245 int nCol;
1246 Str ct = {0, 0, 0}; /* The "CREATE TABLE data_xxx" statement */
1247 Str sql = {0, 0, 0}; /* Query to find differences */
1248 Str insert = {0, 0, 0}; /* First part of output INSERT statement */
1249 sqlite3_stmt *pStmt = 0;
danfebfe022016-03-19 16:21:26 +00001250 int nRow = 0; /* Total rows in data_xxx table */
dan99461852015-07-30 20:26:16 +00001251
1252 /* --rbu mode must use real primary keys. */
1253 g.bSchemaPK = 1;
1254
1255 /* Check that the schemas of the two tables match. Exit early otherwise. */
1256 checkSchemasMatch(zTab);
1257
1258 /* Grab the column names and PK details for the table(s). If no usable PK
1259 ** columns are found, bail out early. */
1260 azCol = columnNames("main", zTab, &nPK, &bOtaRowid);
1261 if( azCol==0 ){
1262 runtimeError("table %s has no usable PK columns", zTab);
1263 }
dana9ca8af2015-07-31 19:52:03 +00001264 for(nCol=0; azCol[nCol]; nCol++);
dan99461852015-07-30 20:26:16 +00001265
1266 /* Build and output the CREATE TABLE statement for the data_xxx table */
1267 strPrintf(&ct, "CREATE TABLE IF NOT EXISTS 'data_%q'(", zTab);
1268 if( bOtaRowid ) strPrintf(&ct, "rbu_rowid, ");
1269 strPrintfArray(&ct, ", ", "%s", &azCol[bOtaRowid], -1);
1270 strPrintf(&ct, ", rbu_control);");
1271
dan99461852015-07-30 20:26:16 +00001272 /* Get the SQL for the query to retrieve data from the two databases */
1273 getRbudiffQuery(zTab, azCol, nPK, bOtaRowid, &sql);
1274
1275 /* Build the first part of the INSERT statement output for each row
1276 ** in the data_xxx table. */
1277 strPrintf(&insert, "INSERT INTO 'data_%q' (", zTab);
1278 if( bOtaRowid ) strPrintf(&insert, "rbu_rowid, ");
1279 strPrintfArray(&insert, ", ", "%s", &azCol[bOtaRowid], -1);
1280 strPrintf(&insert, ", rbu_control) VALUES(");
1281
1282 pStmt = db_prepare("%s", sql.z);
dana9ca8af2015-07-31 19:52:03 +00001283
dan99461852015-07-30 20:26:16 +00001284 while( sqlite3_step(pStmt)==SQLITE_ROW ){
dana9ca8af2015-07-31 19:52:03 +00001285
1286 /* If this is the first row output, print out the CREATE TABLE
1287 ** statement first. And then set ct.z to NULL so that it is not
1288 ** printed again. */
dan99461852015-07-30 20:26:16 +00001289 if( ct.z ){
1290 fprintf(out, "%s\n", ct.z);
1291 strFree(&ct);
1292 }
1293
dana9ca8af2015-07-31 19:52:03 +00001294 /* Output the first part of the INSERT statement */
dan99461852015-07-30 20:26:16 +00001295 fprintf(out, "%s", insert.z);
danfebfe022016-03-19 16:21:26 +00001296 nRow++;
dana9ca8af2015-07-31 19:52:03 +00001297
1298 if( sqlite3_column_type(pStmt, nCol)==SQLITE_INTEGER ){
1299 for(i=0; i<=nCol; i++){
1300 if( i>0 ) fprintf(out, ", ");
1301 printQuoted(out, sqlite3_column_value(pStmt, i));
1302 }
1303 }else{
1304 char *zOtaControl;
1305 int nOtaControl = sqlite3_column_bytes(pStmt, nCol);
1306
dan6ff46272016-08-11 09:55:55 +00001307 zOtaControl = (char*)sqlite3_malloc(nOtaControl+1);
dana9ca8af2015-07-31 19:52:03 +00001308 memcpy(zOtaControl, sqlite3_column_text(pStmt, nCol), nOtaControl+1);
1309
1310 for(i=0; i<nCol; i++){
1311 int bDone = 0;
1312 if( i>=nPK
1313 && sqlite3_column_type(pStmt, i)==SQLITE_BLOB
1314 && sqlite3_column_type(pStmt, nCol+1+i)==SQLITE_BLOB
1315 ){
1316 const char *aSrc = sqlite3_column_blob(pStmt, nCol+1+i);
1317 int nSrc = sqlite3_column_bytes(pStmt, nCol+1+i);
1318 const char *aFinal = sqlite3_column_blob(pStmt, i);
1319 int nFinal = sqlite3_column_bytes(pStmt, i);
1320 char *aDelta;
1321 int nDelta;
1322
1323 aDelta = sqlite3_malloc(nFinal + 60);
1324 nDelta = rbuDeltaCreate(aSrc, nSrc, aFinal, nFinal, aDelta);
1325 if( nDelta<nFinal ){
1326 int j;
1327 fprintf(out, "x'");
1328 for(j=0; j<nDelta; j++) fprintf(out, "%02x", (u8)aDelta[j]);
1329 fprintf(out, "'");
1330 zOtaControl[i-bOtaRowid] = 'f';
1331 bDone = 1;
1332 }
1333 sqlite3_free(aDelta);
1334 }
1335
1336 if( bDone==0 ){
1337 printQuoted(out, sqlite3_column_value(pStmt, i));
1338 }
1339 fprintf(out, ", ");
1340 }
1341 fprintf(out, "'%s'", zOtaControl);
1342 sqlite3_free(zOtaControl);
dan99461852015-07-30 20:26:16 +00001343 }
dana9ca8af2015-07-31 19:52:03 +00001344
1345 /* And the closing bracket of the insert statement */
dan99461852015-07-30 20:26:16 +00001346 fprintf(out, ");\n");
1347 }
1348
1349 sqlite3_finalize(pStmt);
danfebfe022016-03-19 16:21:26 +00001350 if( nRow>0 ){
1351 Str cnt = {0, 0, 0};
1352 strPrintf(&cnt, "INSERT INTO rbu_count VALUES('data_%q', %d);", zTab, nRow);
1353 fprintf(out, "%s\n", cnt.z);
1354 strFree(&cnt);
1355 }
dan99461852015-07-30 20:26:16 +00001356
1357 strFree(&ct);
1358 strFree(&sql);
1359 strFree(&insert);
1360}
1361
1362/*
drh8a1cd762015-04-14 19:01:08 +00001363** Display a summary of differences between two versions of the same
1364** table table.
1365**
1366** * Number of rows changed
1367** * Number of rows added
1368** * Number of rows deleted
1369** * Number of identical rows
1370*/
1371static void summarize_one_table(const char *zTab, FILE *out){
1372 char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
1373 char **az = 0; /* Columns in main */
1374 char **az2 = 0; /* Columns in aux */
1375 int nPk; /* Primary key columns in main */
1376 int nPk2; /* Primary key columns in aux */
drhb3f3d642015-04-25 18:39:21 +00001377 int n = 0; /* Number of columns in main */
drh8a1cd762015-04-14 19:01:08 +00001378 int n2; /* Number of columns in aux */
1379 int i; /* Loop counter */
1380 const char *zSep; /* Separator string */
1381 Str sql; /* Comparison query */
1382 sqlite3_stmt *pStmt; /* Query statement to do the diff */
1383 sqlite3_int64 nUpdate; /* Number of updated rows */
1384 sqlite3_int64 nUnchanged; /* Number of unmodified rows */
1385 sqlite3_int64 nDelete; /* Number of deleted rows */
1386 sqlite3_int64 nInsert; /* Number of inserted rows */
1387
1388 strInit(&sql);
1389 if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
1390 if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
1391 /* Table missing from second database. */
1392 fprintf(out, "%s: missing from second database\n", zTab);
1393 }
1394 goto end_summarize_one_table;
1395 }
1396
1397 if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
1398 /* Table missing from source */
1399 fprintf(out, "%s: missing from first database\n", zTab);
1400 goto end_summarize_one_table;
1401 }
1402
dan99461852015-07-30 20:26:16 +00001403 az = columnNames("main", zTab, &nPk, 0);
1404 az2 = columnNames("aux", zTab, &nPk2, 0);
drh8a1cd762015-04-14 19:01:08 +00001405 if( az && az2 ){
1406 for(n=0; az[n]; n++){
1407 if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
1408 }
1409 }
1410 if( az==0
1411 || az2==0
1412 || nPk!=nPk2
1413 || az[n]
1414 ){
1415 /* Schema mismatch */
1416 fprintf(out, "%s: incompatible schema\n", zTab);
1417 goto end_summarize_one_table;
1418 }
1419
1420 /* Build the comparison query */
1421 for(n2=n; az[n2]; n2++){}
1422 strPrintf(&sql, "SELECT 1, count(*)");
1423 if( n2==nPk2 ){
1424 strPrintf(&sql, ", 0\n");
1425 }else{
1426 zSep = ", sum(";
1427 for(i=nPk; az[i]; i++){
1428 strPrintf(&sql, "%sA.%s IS NOT B.%s", zSep, az[i], az[i]);
1429 zSep = " OR ";
1430 }
1431 strPrintf(&sql, ")\n");
1432 }
1433 strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId);
1434 zSep = " WHERE";
1435 for(i=0; i<nPk; i++){
1436 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
1437 zSep = " AND";
1438 }
1439 strPrintf(&sql, " UNION ALL\n");
1440 strPrintf(&sql, "SELECT 2, count(*), 0\n");
1441 strPrintf(&sql, " FROM main.%s A\n", zId);
1442 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B ", zId);
1443 zSep = "WHERE";
1444 for(i=0; i<nPk; i++){
1445 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
1446 zSep = " AND";
1447 }
1448 strPrintf(&sql, ")\n");
1449 strPrintf(&sql, " UNION ALL\n");
1450 strPrintf(&sql, "SELECT 3, count(*), 0\n");
1451 strPrintf(&sql, " FROM aux.%s B\n", zId);
1452 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A ", zId);
1453 zSep = "WHERE";
1454 for(i=0; i<nPk; i++){
1455 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
1456 zSep = " AND";
1457 }
1458 strPrintf(&sql, ")\n ORDER BY 1;\n");
1459
1460 if( (g.fDebug & DEBUG_DIFF_SQL)!=0 ){
1461 printf("SQL for %s:\n%s\n", zId, sql.z);
1462 goto end_summarize_one_table;
1463 }
1464
1465 /* Run the query and output difference summary */
drh52254492016-07-08 02:14:24 +00001466 pStmt = db_prepare("%s", sql.z);
drh8a1cd762015-04-14 19:01:08 +00001467 nUpdate = 0;
1468 nInsert = 0;
1469 nDelete = 0;
1470 nUnchanged = 0;
1471 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1472 switch( sqlite3_column_int(pStmt,0) ){
1473 case 1:
1474 nUpdate = sqlite3_column_int64(pStmt,2);
1475 nUnchanged = sqlite3_column_int64(pStmt,1) - nUpdate;
1476 break;
1477 case 2:
1478 nDelete = sqlite3_column_int64(pStmt,1);
1479 break;
1480 case 3:
1481 nInsert = sqlite3_column_int64(pStmt,1);
1482 break;
1483 }
1484 }
1485 sqlite3_finalize(pStmt);
1486 fprintf(out, "%s: %lld changes, %lld inserts, %lld deletes, %lld unchanged\n",
1487 zTab, nUpdate, nInsert, nDelete, nUnchanged);
1488
1489end_summarize_one_table:
1490 strFree(&sql);
1491 sqlite3_free(zId);
1492 namelistFree(az);
1493 namelistFree(az2);
1494 return;
1495}
1496
1497/*
drh697e5db2015-04-11 12:07:40 +00001498** Write a 64-bit signed integer as a varint onto out
1499*/
1500static void putsVarint(FILE *out, sqlite3_uint64 v){
1501 int i, n;
drh6e42ce42015-04-11 13:48:01 +00001502 unsigned char p[12];
drh697e5db2015-04-11 12:07:40 +00001503 if( v & (((sqlite3_uint64)0xff000000)<<32) ){
1504 p[8] = (unsigned char)v;
1505 v >>= 8;
1506 for(i=7; i>=0; i--){
1507 p[i] = (unsigned char)((v & 0x7f) | 0x80);
1508 v >>= 7;
1509 }
1510 fwrite(p, 8, 1, out);
1511 }else{
1512 n = 9;
1513 do{
1514 p[n--] = (unsigned char)((v & 0x7f) | 0x80);
1515 v >>= 7;
1516 }while( v!=0 );
drh6e42ce42015-04-11 13:48:01 +00001517 p[9] &= 0x7f;
1518 fwrite(p+n+1, 9-n, 1, out);
1519 }
1520}
1521
1522/*
1523** Write an SQLite value onto out.
1524*/
1525static void putValue(FILE *out, sqlite3_value *pVal){
1526 int iDType = sqlite3_value_type(pVal);
1527 sqlite3_int64 iX;
1528 double rX;
1529 sqlite3_uint64 uX;
1530 int j;
1531
1532 putc(iDType, out);
1533 switch( iDType ){
1534 case SQLITE_INTEGER:
1535 iX = sqlite3_value_int64(pVal);
1536 memcpy(&uX, &iX, 8);
1537 for(j=56; j>=0; j-=8) putc((uX>>j)&0xff, out);
1538 break;
1539 case SQLITE_FLOAT:
drh33aa4db2015-05-04 15:04:47 +00001540 rX = sqlite3_value_double(pVal);
drh6e42ce42015-04-11 13:48:01 +00001541 memcpy(&uX, &rX, 8);
1542 for(j=56; j>=0; j-=8) putc((uX>>j)&0xff, out);
1543 break;
1544 case SQLITE_TEXT:
1545 iX = sqlite3_value_bytes(pVal);
1546 putsVarint(out, (sqlite3_uint64)iX);
drh33aa4db2015-05-04 15:04:47 +00001547 fwrite(sqlite3_value_text(pVal),1,(size_t)iX,out);
drh6e42ce42015-04-11 13:48:01 +00001548 break;
1549 case SQLITE_BLOB:
1550 iX = sqlite3_value_bytes(pVal);
1551 putsVarint(out, (sqlite3_uint64)iX);
drh33aa4db2015-05-04 15:04:47 +00001552 fwrite(sqlite3_value_blob(pVal),1,(size_t)iX,out);
drh6e42ce42015-04-11 13:48:01 +00001553 break;
1554 case SQLITE_NULL:
1555 break;
drh697e5db2015-04-11 12:07:40 +00001556 }
1557}
1558
1559/*
drh83e63dc2015-04-10 19:41:18 +00001560** Generate a CHANGESET for all differences from main.zTab to aux.zTab.
1561*/
1562static void changeset_one_table(const char *zTab, FILE *out){
1563 sqlite3_stmt *pStmt; /* SQL statment */
1564 char *zId = safeId(zTab); /* Escaped name of the table */
1565 char **azCol = 0; /* List of escaped column names */
1566 int nCol = 0; /* Number of columns */
1567 int *aiFlg = 0; /* 0 if column is not part of PK */
1568 int *aiPk = 0; /* Column numbers for each PK column */
1569 int nPk = 0; /* Number of PRIMARY KEY columns */
1570 Str sql; /* SQL for the diff query */
drh6e42ce42015-04-11 13:48:01 +00001571 int i, k; /* Loop counters */
drh83e63dc2015-04-10 19:41:18 +00001572 const char *zSep; /* List separator */
1573
dan99461852015-07-30 20:26:16 +00001574 /* Check that the schemas of the two tables match. Exit early otherwise. */
1575 checkSchemasMatch(zTab);
1576
drh83e63dc2015-04-10 19:41:18 +00001577 pStmt = db_prepare("PRAGMA main.table_info=%Q", zTab);
1578 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1579 nCol++;
1580 azCol = sqlite3_realloc(azCol, sizeof(char*)*nCol);
1581 if( azCol==0 ) runtimeError("out of memory");
1582 aiFlg = sqlite3_realloc(aiFlg, sizeof(int)*nCol);
1583 if( aiFlg==0 ) runtimeError("out of memory");
1584 azCol[nCol-1] = safeId((const char*)sqlite3_column_text(pStmt,1));
1585 aiFlg[nCol-1] = i = sqlite3_column_int(pStmt,5);
1586 if( i>0 ){
1587 if( i>nPk ){
1588 nPk = i;
1589 aiPk = sqlite3_realloc(aiPk, sizeof(int)*nPk);
1590 if( aiPk==0 ) runtimeError("out of memory");
1591 }
1592 aiPk[i-1] = nCol-1;
1593 }
1594 }
1595 sqlite3_finalize(pStmt);
1596 if( nPk==0 ) goto end_changeset_one_table;
1597 strInit(&sql);
1598 if( nCol>nPk ){
drh697e5db2015-04-11 12:07:40 +00001599 strPrintf(&sql, "SELECT %d", SQLITE_UPDATE);
drh6e42ce42015-04-11 13:48:01 +00001600 for(i=0; i<nCol; i++){
1601 if( aiFlg[i] ){
1602 strPrintf(&sql, ",\n A.%s", azCol[i]);
1603 }else{
1604 strPrintf(&sql, ",\n A.%s IS NOT B.%s, A.%s, B.%s",
1605 azCol[i], azCol[i], azCol[i], azCol[i]);
1606 }
1607 }
drh83e63dc2015-04-10 19:41:18 +00001608 strPrintf(&sql,"\n FROM main.%s A, aux.%s B\n", zId, zId);
1609 zSep = " WHERE";
1610 for(i=0; i<nPk; i++){
1611 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1612 zSep = " AND";
1613 }
1614 zSep = "\n AND (";
1615 for(i=0; i<nCol; i++){
1616 if( aiFlg[i] ) continue;
1617 strPrintf(&sql, "%sA.%s IS NOT B.%s", zSep, azCol[i], azCol[i]);
1618 zSep = " OR\n ";
1619 }
1620 strPrintf(&sql,")\n UNION ALL\n");
1621 }
drh697e5db2015-04-11 12:07:40 +00001622 strPrintf(&sql, "SELECT %d", SQLITE_DELETE);
drh6e42ce42015-04-11 13:48:01 +00001623 for(i=0; i<nCol; i++){
1624 if( aiFlg[i] ){
1625 strPrintf(&sql, ",\n A.%s", azCol[i]);
1626 }else{
1627 strPrintf(&sql, ",\n 1, A.%s, NULL", azCol[i]);
1628 }
1629 }
1630 strPrintf(&sql, "\n FROM main.%s A\n", zId);
drh83e63dc2015-04-10 19:41:18 +00001631 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B\n", zId);
1632 zSep = " WHERE";
1633 for(i=0; i<nPk; i++){
1634 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1635 zSep = " AND";
1636 }
1637 strPrintf(&sql, ")\n UNION ALL\n");
drh697e5db2015-04-11 12:07:40 +00001638 strPrintf(&sql, "SELECT %d", SQLITE_INSERT);
drh6e42ce42015-04-11 13:48:01 +00001639 for(i=0; i<nCol; i++){
1640 if( aiFlg[i] ){
1641 strPrintf(&sql, ",\n B.%s", azCol[i]);
1642 }else{
1643 strPrintf(&sql, ",\n 1, NULL, B.%s", azCol[i]);
1644 }
1645 }
1646 strPrintf(&sql, "\n FROM aux.%s B\n", zId);
drh83e63dc2015-04-10 19:41:18 +00001647 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A\n", zId);
1648 zSep = " WHERE";
1649 for(i=0; i<nPk; i++){
1650 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1651 zSep = " AND";
1652 }
1653 strPrintf(&sql, ")\n");
1654 strPrintf(&sql, " ORDER BY");
1655 zSep = " ";
1656 for(i=0; i<nPk; i++){
drh6e42ce42015-04-11 13:48:01 +00001657 strPrintf(&sql, "%s %d", zSep, aiPk[i]+2);
drh83e63dc2015-04-10 19:41:18 +00001658 zSep = ",";
1659 }
1660 strPrintf(&sql, ";\n");
1661
drh697e5db2015-04-11 12:07:40 +00001662 if( g.fDebug & DEBUG_DIFF_SQL ){
1663 printf("SQL for %s:\n%s\n", zId, sql.z);
1664 goto end_changeset_one_table;
1665 }
1666
1667 putc('T', out);
1668 putsVarint(out, (sqlite3_uint64)nCol);
1669 for(i=0; i<nCol; i++) putc(aiFlg[i]!=0, out);
1670 fwrite(zTab, 1, strlen(zTab), out);
1671 putc(0, out);
1672
1673 pStmt = db_prepare("%s", sql.z);
1674 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1675 int iType = sqlite3_column_int(pStmt,0);
drh697e5db2015-04-11 12:07:40 +00001676 putc(iType, out);
1677 putc(0, out);
drh6e42ce42015-04-11 13:48:01 +00001678 switch( sqlite3_column_int(pStmt,0) ){
1679 case SQLITE_UPDATE: {
1680 for(k=1, i=0; i<nCol; i++){
1681 if( aiFlg[i] ){
1682 putValue(out, sqlite3_column_value(pStmt,k));
1683 k++;
1684 }else if( sqlite3_column_int(pStmt,k) ){
1685 putValue(out, sqlite3_column_value(pStmt,k+1));
1686 k += 3;
1687 }else{
1688 putc(0, out);
1689 k += 3;
1690 }
1691 }
1692 for(k=1, i=0; i<nCol; i++){
1693 if( aiFlg[i] ){
1694 putc(0, out);
1695 k++;
1696 }else if( sqlite3_column_int(pStmt,k) ){
1697 putValue(out, sqlite3_column_value(pStmt,k+2));
1698 k += 3;
1699 }else{
1700 putc(0, out);
1701 k += 3;
1702 }
1703 }
1704 break;
1705 }
1706 case SQLITE_INSERT: {
1707 for(k=1, i=0; i<nCol; i++){
1708 if( aiFlg[i] ){
1709 putValue(out, sqlite3_column_value(pStmt,k));
1710 k++;
1711 }else{
1712 putValue(out, sqlite3_column_value(pStmt,k+2));
1713 k += 3;
1714 }
1715 }
1716 break;
1717 }
1718 case SQLITE_DELETE: {
1719 for(k=1, i=0; i<nCol; i++){
1720 if( aiFlg[i] ){
1721 putValue(out, sqlite3_column_value(pStmt,k));
1722 k++;
1723 }else{
1724 putValue(out, sqlite3_column_value(pStmt,k+1));
1725 k += 3;
1726 }
1727 }
1728 break;
drh697e5db2015-04-11 12:07:40 +00001729 }
1730 }
1731 }
1732 sqlite3_finalize(pStmt);
drh83e63dc2015-04-10 19:41:18 +00001733
1734end_changeset_one_table:
1735 while( nCol>0 ) sqlite3_free(azCol[--nCol]);
1736 sqlite3_free(azCol);
1737 sqlite3_free(aiPk);
1738 sqlite3_free(zId);
1739}
1740
1741/*
dan9c987a82016-06-21 10:34:41 +00001742** Extract the next SQL keyword or quoted string from buffer zIn and copy it
1743** (or a prefix of it if it will not fit) into buffer zBuf, size nBuf bytes.
1744** Return a pointer to the character within zIn immediately following
1745** the token or quoted string just extracted.
1746*/
1747const char *gobble_token(const char *zIn, char *zBuf, int nBuf){
1748 const char *p = zIn;
1749 char *pOut = zBuf;
1750 char *pEnd = &pOut[nBuf-1];
1751 char q = 0; /* quote character, if any */
1752
1753 if( p==0 ) return 0;
1754 while( *p==' ' ) p++;
1755 switch( *p ){
1756 case '"': q = '"'; break;
1757 case '\'': q = '\''; break;
1758 case '`': q = '`'; break;
1759 case '[': q = ']'; break;
1760 }
1761
1762 if( q ){
1763 p++;
1764 while( *p && pOut<pEnd ){
1765 if( *p==q ){
1766 p++;
1767 if( *p!=q ) break;
1768 }
1769 if( pOut<pEnd ) *pOut++ = *p;
1770 p++;
1771 }
1772 }else{
1773 while( *p && *p!=' ' && *p!='(' ){
1774 if( pOut<pEnd ) *pOut++ = *p;
1775 p++;
1776 }
1777 }
1778
1779 *pOut = '\0';
1780 return p;
1781}
1782
1783/*
1784** This function is the implementation of SQL scalar function "module_name":
1785**
1786** module_name(SQL)
1787**
1788** The only argument should be an SQL statement of the type that may appear
1789** in the sqlite_master table. If the statement is a "CREATE VIRTUAL TABLE"
1790** statement, then the value returned is the name of the module that it
1791** uses. Otherwise, if the statement is not a CVT, NULL is returned.
1792*/
1793static void module_name_func(
1794 sqlite3_context *pCtx,
1795 int nVal, sqlite3_value **apVal
1796){
1797 const char *zSql;
1798 char zToken[32];
1799
1800 assert( nVal==1 );
1801 zSql = (const char*)sqlite3_value_text(apVal[0]);
1802
1803 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1804 if( zSql==0 || sqlite3_stricmp(zToken, "create") ) return;
1805 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1806 if( zSql==0 || sqlite3_stricmp(zToken, "virtual") ) return;
1807 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1808 if( zSql==0 || sqlite3_stricmp(zToken, "table") ) return;
1809 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1810 if( zSql==0 ) return;
1811 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1812 if( zSql==0 || sqlite3_stricmp(zToken, "using") ) return;
1813 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1814
1815 sqlite3_result_text(pCtx, zToken, -1, SQLITE_TRANSIENT);
1816}
1817
1818/*
1819** Return the text of an SQL statement that itself returns the list of
1820** tables to process within the database.
1821*/
1822const char *all_tables_sql(){
1823 if( g.bHandleVtab ){
1824 int rc;
1825
1826 rc = sqlite3_exec(g.db,
dan12ca5ac2016-07-22 10:09:26 +00001827 "CREATE TEMP TABLE tblmap(module COLLATE nocase, postfix);"
dan9c987a82016-06-21 10:34:41 +00001828 "INSERT INTO temp.tblmap VALUES"
1829 "('fts3', '_content'), ('fts3', '_segments'), ('fts3', '_segdir'),"
1830
1831 "('fts4', '_content'), ('fts4', '_segments'), ('fts4', '_segdir'),"
1832 "('fts4', '_docsize'), ('fts4', '_stat'),"
1833
1834 "('fts5', '_data'), ('fts5', '_idx'), ('fts5', '_content'),"
1835 "('fts5', '_docsize'), ('fts5', '_config'),"
1836
1837 "('rtree', '_node'), ('rtree', '_rowid'), ('rtree', '_parent');"
1838 , 0, 0, 0
1839 );
1840 assert( rc==SQLITE_OK );
1841
1842 rc = sqlite3_create_function(
1843 g.db, "module_name", 1, SQLITE_UTF8, 0, module_name_func, 0, 0
1844 );
1845 assert( rc==SQLITE_OK );
1846
1847 return
1848 "SELECT name FROM main.sqlite_master\n"
1849 " WHERE type='table' AND (\n"
1850 " module_name(sql) IS NULL OR \n"
1851 " module_name(sql) IN (SELECT module FROM temp.tblmap)\n"
1852 " ) AND name NOT IN (\n"
1853 " SELECT a.name || b.postfix \n"
1854 "FROM main.sqlite_master AS a, temp.tblmap AS b \n"
1855 "WHERE module_name(a.sql) = b.module\n"
1856 " )\n"
1857 "UNION \n"
1858 "SELECT name FROM aux.sqlite_master\n"
1859 " WHERE type='table' AND (\n"
1860 " module_name(sql) IS NULL OR \n"
1861 " module_name(sql) IN (SELECT module FROM temp.tblmap)\n"
1862 " ) AND name NOT IN (\n"
1863 " SELECT a.name || b.postfix \n"
1864 "FROM aux.sqlite_master AS a, temp.tblmap AS b \n"
1865 "WHERE module_name(a.sql) = b.module\n"
1866 " )\n"
1867 " ORDER BY name";
1868 }else{
1869 return
1870 "SELECT name FROM main.sqlite_master\n"
1871 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1872 " UNION\n"
1873 "SELECT name FROM aux.sqlite_master\n"
1874 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1875 " ORDER BY name";
1876 }
1877}
1878
1879/*
drhd62c0f42015-04-09 13:34:29 +00001880** Print sketchy documentation for this utility program
1881*/
1882static void showHelp(void){
1883 printf("Usage: %s [options] DB1 DB2\n", g.zArgv0);
1884 printf(
1885"Output SQL text that would transform DB1 into DB2.\n"
1886"Options:\n"
drh83e63dc2015-04-10 19:41:18 +00001887" --changeset FILE Write a CHANGESET into FILE\n"
drh9a9219f2015-05-04 13:25:56 +00001888" -L|--lib LIBRARY Load an SQLite extension library\n"
drha37591c2015-04-09 18:14:03 +00001889" --primarykey Use schema-defined PRIMARY KEYs\n"
dan99461852015-07-30 20:26:16 +00001890" --rbu Output SQL to create/populate RBU table(s)\n"
drhd62c0f42015-04-09 13:34:29 +00001891" --schema Show only differences in the schema\n"
drh8a1cd762015-04-14 19:01:08 +00001892" --summary Show only a summary of the differences\n"
drhd62c0f42015-04-09 13:34:29 +00001893" --table TAB Show only differences in table TAB\n"
drh05d4ebf2015-11-13 13:15:42 +00001894" --transaction Show SQL output inside a transaction\n"
dan9c987a82016-06-21 10:34:41 +00001895" --vtab Handle fts3, fts4, fts5 and rtree tables\n"
drhd62c0f42015-04-09 13:34:29 +00001896 );
1897}
1898
1899int main(int argc, char **argv){
1900 const char *zDb1 = 0;
1901 const char *zDb2 = 0;
1902 int i;
1903 int rc;
1904 char *zErrMsg = 0;
1905 char *zSql;
1906 sqlite3_stmt *pStmt;
1907 char *zTab = 0;
drh8a1cd762015-04-14 19:01:08 +00001908 FILE *out = stdout;
1909 void (*xDiff)(const char*,FILE*) = diff_one_table;
drh9493caf2016-03-17 23:16:37 +00001910#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh9a9219f2015-05-04 13:25:56 +00001911 int nExt = 0;
drh33aa4db2015-05-04 15:04:47 +00001912 char **azExt = 0;
drh9493caf2016-03-17 23:16:37 +00001913#endif
drh05d4ebf2015-11-13 13:15:42 +00001914 int useTransaction = 0;
1915 int neverUseTransaction = 0;
drhd62c0f42015-04-09 13:34:29 +00001916
1917 g.zArgv0 = argv[0];
drhaa62e482015-05-12 00:46:40 +00001918 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
drhd62c0f42015-04-09 13:34:29 +00001919 for(i=1; i<argc; i++){
1920 const char *z = argv[i];
1921 if( z[0]=='-' ){
1922 z++;
1923 if( z[0]=='-' ) z++;
drh83e63dc2015-04-10 19:41:18 +00001924 if( strcmp(z,"changeset")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001925 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drh83e63dc2015-04-10 19:41:18 +00001926 out = fopen(argv[++i], "wb");
1927 if( out==0 ) cmdlineError("cannot open: %s", argv[i]);
drh8a1cd762015-04-14 19:01:08 +00001928 xDiff = changeset_one_table;
drh05d4ebf2015-11-13 13:15:42 +00001929 neverUseTransaction = 1;
drh83e63dc2015-04-10 19:41:18 +00001930 }else
drhd62c0f42015-04-09 13:34:29 +00001931 if( strcmp(z,"debug")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001932 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drhd62c0f42015-04-09 13:34:29 +00001933 g.fDebug = strtol(argv[++i], 0, 0);
1934 }else
1935 if( strcmp(z,"help")==0 ){
1936 showHelp();
1937 return 0;
1938 }else
drh6582ae52015-05-12 12:24:50 +00001939#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh9a9219f2015-05-04 13:25:56 +00001940 if( strcmp(z,"lib")==0 || strcmp(z,"L")==0 ){
1941 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
1942 azExt = realloc(azExt, sizeof(azExt[0])*(nExt+1));
1943 if( azExt==0 ) cmdlineError("out of memory");
1944 azExt[nExt++] = argv[++i];
1945 }else
drh6582ae52015-05-12 12:24:50 +00001946#endif
drha37591c2015-04-09 18:14:03 +00001947 if( strcmp(z,"primarykey")==0 ){
1948 g.bSchemaPK = 1;
1949 }else
dan99461852015-07-30 20:26:16 +00001950 if( strcmp(z,"rbu")==0 ){
1951 xDiff = rbudiff_one_table;
1952 }else
drhd62c0f42015-04-09 13:34:29 +00001953 if( strcmp(z,"schema")==0 ){
1954 g.bSchemaOnly = 1;
1955 }else
drh8a1cd762015-04-14 19:01:08 +00001956 if( strcmp(z,"summary")==0 ){
1957 xDiff = summarize_one_table;
1958 }else
drhd62c0f42015-04-09 13:34:29 +00001959 if( strcmp(z,"table")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001960 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drhd62c0f42015-04-09 13:34:29 +00001961 zTab = argv[++i];
1962 }else
drh05d4ebf2015-11-13 13:15:42 +00001963 if( strcmp(z,"transaction")==0 ){
1964 useTransaction = 1;
1965 }else
dan9c987a82016-06-21 10:34:41 +00001966 if( strcmp(z,"vtab")==0 ){
1967 g.bHandleVtab = 1;
1968 }else
drhd62c0f42015-04-09 13:34:29 +00001969 {
1970 cmdlineError("unknown option: %s", argv[i]);
1971 }
1972 }else if( zDb1==0 ){
1973 zDb1 = argv[i];
1974 }else if( zDb2==0 ){
1975 zDb2 = argv[i];
1976 }else{
1977 cmdlineError("unknown argument: %s", argv[i]);
1978 }
1979 }
1980 if( zDb2==0 ){
1981 cmdlineError("two database arguments required");
1982 }
1983 rc = sqlite3_open(zDb1, &g.db);
1984 if( rc ){
1985 cmdlineError("cannot open database file \"%s\"", zDb1);
1986 }
1987 rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_master", 0, 0, &zErrMsg);
1988 if( rc || zErrMsg ){
1989 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1);
1990 }
drh6582ae52015-05-12 12:24:50 +00001991#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh9a9219f2015-05-04 13:25:56 +00001992 sqlite3_enable_load_extension(g.db, 1);
1993 for(i=0; i<nExt; i++){
1994 rc = sqlite3_load_extension(g.db, azExt[i], 0, &zErrMsg);
1995 if( rc || zErrMsg ){
1996 cmdlineError("error loading %s: %s", azExt[i], zErrMsg);
1997 }
1998 }
1999 free(azExt);
drh9493caf2016-03-17 23:16:37 +00002000#endif
drhd62c0f42015-04-09 13:34:29 +00002001 zSql = sqlite3_mprintf("ATTACH %Q as aux;", zDb2);
2002 rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
2003 if( rc || zErrMsg ){
2004 cmdlineError("cannot attach database \"%s\"", zDb2);
2005 }
2006 rc = sqlite3_exec(g.db, "SELECT * FROM aux.sqlite_master", 0, 0, &zErrMsg);
2007 if( rc || zErrMsg ){
2008 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb2);
2009 }
2010
drh05d4ebf2015-11-13 13:15:42 +00002011 if( neverUseTransaction ) useTransaction = 0;
danfebfe022016-03-19 16:21:26 +00002012 if( useTransaction ) fprintf(out, "BEGIN TRANSACTION;\n");
2013 if( xDiff==rbudiff_one_table ){
2014 fprintf(out, "CREATE TABLE IF NOT EXISTS rbu_count"
2015 "(tbl TEXT PRIMARY KEY COLLATE NOCASE, cnt INTEGER) "
2016 "WITHOUT ROWID;\n"
2017 );
2018 }
drhd62c0f42015-04-09 13:34:29 +00002019 if( zTab ){
drh8a1cd762015-04-14 19:01:08 +00002020 xDiff(zTab, out);
drhd62c0f42015-04-09 13:34:29 +00002021 }else{
2022 /* Handle tables one by one */
drh52254492016-07-08 02:14:24 +00002023 pStmt = db_prepare("%s", all_tables_sql() );
drhd62c0f42015-04-09 13:34:29 +00002024 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +00002025 xDiff((const char*)sqlite3_column_text(pStmt,0), out);
drhd62c0f42015-04-09 13:34:29 +00002026 }
2027 sqlite3_finalize(pStmt);
2028 }
drh05d4ebf2015-11-13 13:15:42 +00002029 if( useTransaction ) printf("COMMIT;\n");
drhd62c0f42015-04-09 13:34:29 +00002030
2031 /* TBD: Handle trigger differences */
2032 /* TBD: Handle view differences */
2033 sqlite3_close(g.db);
2034 return 0;
2035}