blob: 67f3197bbfeb75a04a75fa43a84a9b59ae9642d5 [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{
dan12c56aa2016-09-12 14:23:51 +0000406 /* Could be an OOM, could be a zero-byte blob */
407 fprintf(out, "X''");
drhd62c0f42015-04-09 13:34:29 +0000408 }
409 break;
410 }
411 case SQLITE_TEXT: {
412 const unsigned char *zArg = sqlite3_value_text(X);
413 int i, j;
414
415 if( zArg==0 ){
drh8a1cd762015-04-14 19:01:08 +0000416 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000417 }else{
drh8a1cd762015-04-14 19:01:08 +0000418 fprintf(out, "'");
drhd62c0f42015-04-09 13:34:29 +0000419 for(i=j=0; zArg[i]; i++){
420 if( zArg[i]=='\'' ){
drh8a1cd762015-04-14 19:01:08 +0000421 fprintf(out, "%.*s'", i-j+1, &zArg[j]);
drhd62c0f42015-04-09 13:34:29 +0000422 j = i+1;
423 }
424 }
drh8a1cd762015-04-14 19:01:08 +0000425 fprintf(out, "%s'", &zArg[j]);
drhd62c0f42015-04-09 13:34:29 +0000426 }
427 break;
428 }
429 case SQLITE_NULL: {
drh8a1cd762015-04-14 19:01:08 +0000430 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000431 break;
432 }
433 }
434}
435
436/*
437** Output SQL that will recreate the aux.zTab table.
438*/
drh8a1cd762015-04-14 19:01:08 +0000439static void dump_table(const char *zTab, FILE *out){
drhd62c0f42015-04-09 13:34:29 +0000440 char *zId = safeId(zTab); /* Name of the table */
441 char **az = 0; /* List of columns */
442 int nPk; /* Number of true primary key columns */
443 int nCol; /* Number of data columns */
444 int i; /* Loop counter */
445 sqlite3_stmt *pStmt; /* SQL statement */
446 const char *zSep; /* Separator string */
447 Str ins; /* Beginning of the INSERT statement */
448
449 pStmt = db_prepare("SELECT sql FROM aux.sqlite_master WHERE name=%Q", zTab);
450 if( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000451 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000452 }
453 sqlite3_finalize(pStmt);
454 if( !g.bSchemaOnly ){
dan99461852015-07-30 20:26:16 +0000455 az = columnNames("aux", zTab, &nPk, 0);
drhd62c0f42015-04-09 13:34:29 +0000456 strInit(&ins);
457 if( az==0 ){
458 pStmt = db_prepare("SELECT * FROM aux.%s", zId);
459 strPrintf(&ins,"INSERT INTO %s VALUES", zId);
460 }else{
461 Str sql;
462 strInit(&sql);
463 zSep = "SELECT";
464 for(i=0; az[i]; i++){
465 strPrintf(&sql, "%s %s", zSep, az[i]);
466 zSep = ",";
467 }
468 strPrintf(&sql," FROM aux.%s", zId);
469 zSep = " ORDER BY";
470 for(i=1; i<=nPk; i++){
471 strPrintf(&sql, "%s %d", zSep, i);
472 zSep = ",";
473 }
474 pStmt = db_prepare("%s", sql.z);
475 strFree(&sql);
476 strPrintf(&ins, "INSERT INTO %s", zId);
477 zSep = "(";
478 for(i=0; az[i]; i++){
479 strPrintf(&ins, "%s%s", zSep, az[i]);
480 zSep = ",";
481 }
482 strPrintf(&ins,") VALUES");
483 namelistFree(az);
484 }
485 nCol = sqlite3_column_count(pStmt);
486 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000487 fprintf(out, "%s",ins.z);
drhd62c0f42015-04-09 13:34:29 +0000488 zSep = "(";
489 for(i=0; i<nCol; i++){
drh8a1cd762015-04-14 19:01:08 +0000490 fprintf(out, "%s",zSep);
491 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000492 zSep = ",";
493 }
drh8a1cd762015-04-14 19:01:08 +0000494 fprintf(out, ");\n");
drhd62c0f42015-04-09 13:34:29 +0000495 }
496 sqlite3_finalize(pStmt);
497 strFree(&ins);
498 } /* endif !g.bSchemaOnly */
499 pStmt = db_prepare("SELECT sql FROM aux.sqlite_master"
500 " WHERE type='index' AND tbl_name=%Q AND sql IS NOT NULL",
501 zTab);
502 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000503 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000504 }
505 sqlite3_finalize(pStmt);
506}
507
508
509/*
510** Compute all differences for a single table.
511*/
drh8a1cd762015-04-14 19:01:08 +0000512static void diff_one_table(const char *zTab, FILE *out){
drhd62c0f42015-04-09 13:34:29 +0000513 char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
514 char **az = 0; /* Columns in main */
515 char **az2 = 0; /* Columns in aux */
516 int nPk; /* Primary key columns in main */
517 int nPk2; /* Primary key columns in aux */
drhb3f3d642015-04-25 18:39:21 +0000518 int n = 0; /* Number of columns in main */
drhd62c0f42015-04-09 13:34:29 +0000519 int n2; /* Number of columns in aux */
520 int nQ; /* Number of output columns in the diff query */
521 int i; /* Loop counter */
522 const char *zSep; /* Separator string */
523 Str sql; /* Comparison query */
524 sqlite3_stmt *pStmt; /* Query statement to do the diff */
525
526 strInit(&sql);
527 if( g.fDebug==DEBUG_COLUMN_NAMES ){
528 /* Simply run columnNames() on all tables of the origin
529 ** database and show the results. This is used for testing
530 ** and debugging of the columnNames() function.
531 */
dan99461852015-07-30 20:26:16 +0000532 az = columnNames("aux",zTab, &nPk, 0);
drhd62c0f42015-04-09 13:34:29 +0000533 if( az==0 ){
534 printf("Rowid not accessible for %s\n", zId);
535 }else{
536 printf("%s:", zId);
537 for(i=0; az[i]; i++){
538 printf(" %s", az[i]);
539 if( i+1==nPk ) printf(" *");
540 }
541 printf("\n");
542 }
543 goto end_diff_one_table;
544 }
545
546
547 if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
548 if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
549 /* Table missing from second database. */
drh8a1cd762015-04-14 19:01:08 +0000550 fprintf(out, "DROP TABLE %s;\n", zId);
drhd62c0f42015-04-09 13:34:29 +0000551 }
552 goto end_diff_one_table;
553 }
554
555 if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
556 /* Table missing from source */
drh8a1cd762015-04-14 19:01:08 +0000557 dump_table(zTab, out);
drhd62c0f42015-04-09 13:34:29 +0000558 goto end_diff_one_table;
559 }
560
dan99461852015-07-30 20:26:16 +0000561 az = columnNames("main", zTab, &nPk, 0);
562 az2 = columnNames("aux", zTab, &nPk2, 0);
drhd62c0f42015-04-09 13:34:29 +0000563 if( az && az2 ){
drhedd22602015-11-07 18:32:17 +0000564 for(n=0; az[n] && az2[n]; n++){
drhd62c0f42015-04-09 13:34:29 +0000565 if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
566 }
567 }
568 if( az==0
569 || az2==0
570 || nPk!=nPk2
571 || az[n]
572 ){
573 /* Schema mismatch */
drhedd22602015-11-07 18:32:17 +0000574 fprintf(out, "DROP TABLE %s; -- due to schema mismatch\n", zId);
drh8a1cd762015-04-14 19:01:08 +0000575 dump_table(zTab, out);
drhd62c0f42015-04-09 13:34:29 +0000576 goto end_diff_one_table;
577 }
578
579 /* Build the comparison query */
drhedd22602015-11-07 18:32:17 +0000580 for(n2=n; az2[n2]; n2++){
581 fprintf(out, "ALTER TABLE %s ADD COLUMN %s;\n", zId, safeId(az2[n2]));
582 }
drhd62c0f42015-04-09 13:34:29 +0000583 nQ = nPk2+1+2*(n2-nPk2);
584 if( n2>nPk2 ){
585 zSep = "SELECT ";
586 for(i=0; i<nPk; i++){
587 strPrintf(&sql, "%sB.%s", zSep, az[i]);
588 zSep = ", ";
589 }
590 strPrintf(&sql, ", 1%s -- changed row\n", nPk==n ? "" : ",");
591 while( az[i] ){
592 strPrintf(&sql, " A.%s IS NOT B.%s, B.%s%s\n",
drhedd22602015-11-07 18:32:17 +0000593 az[i], az2[i], az2[i], az2[i+1]==0 ? "" : ",");
594 i++;
595 }
596 while( az2[i] ){
597 strPrintf(&sql, " B.%s IS NOT NULL, B.%s%s\n",
598 az2[i], az2[i], az2[i+1]==0 ? "" : ",");
drhd62c0f42015-04-09 13:34:29 +0000599 i++;
600 }
601 strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId);
602 zSep = " WHERE";
603 for(i=0; i<nPk; i++){
604 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
605 zSep = " AND";
606 }
607 zSep = "\n AND (";
608 while( az[i] ){
609 strPrintf(&sql, "%sA.%s IS NOT B.%s%s\n",
drhedd22602015-11-07 18:32:17 +0000610 zSep, az[i], az2[i], az2[i+1]==0 ? ")" : "");
611 zSep = " OR ";
612 i++;
613 }
614 while( az2[i] ){
615 strPrintf(&sql, "%sB.%s IS NOT NULL%s\n",
616 zSep, az2[i], az2[i+1]==0 ? ")" : "");
drhd62c0f42015-04-09 13:34:29 +0000617 zSep = " OR ";
618 i++;
619 }
620 strPrintf(&sql, " UNION ALL\n");
621 }
622 zSep = "SELECT ";
623 for(i=0; i<nPk; i++){
624 strPrintf(&sql, "%sA.%s", zSep, az[i]);
625 zSep = ", ";
626 }
627 strPrintf(&sql, ", 2%s -- deleted row\n", nPk==n ? "" : ",");
drhedd22602015-11-07 18:32:17 +0000628 while( az2[i] ){
drhd62c0f42015-04-09 13:34:29 +0000629 strPrintf(&sql, " NULL, NULL%s\n", i==n2-1 ? "" : ",");
630 i++;
631 }
632 strPrintf(&sql, " FROM main.%s A\n", zId);
633 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B\n", zId);
634 zSep = " WHERE";
635 for(i=0; i<nPk; i++){
636 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
637 zSep = " AND";
638 }
639 strPrintf(&sql, ")\n");
640 zSep = " UNION ALL\nSELECT ";
641 for(i=0; i<nPk; i++){
642 strPrintf(&sql, "%sB.%s", zSep, az[i]);
643 zSep = ", ";
644 }
645 strPrintf(&sql, ", 3%s -- inserted row\n", nPk==n ? "" : ",");
646 while( az2[i] ){
drhedd22602015-11-07 18:32:17 +0000647 strPrintf(&sql, " 1, B.%s%s\n", az2[i], az2[i+1]==0 ? "" : ",");
drhd62c0f42015-04-09 13:34:29 +0000648 i++;
649 }
650 strPrintf(&sql, " FROM aux.%s B\n", zId);
651 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A\n", zId);
652 zSep = " WHERE";
653 for(i=0; i<nPk; i++){
654 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
655 zSep = " AND";
656 }
657 strPrintf(&sql, ")\n ORDER BY");
658 zSep = " ";
659 for(i=1; i<=nPk; i++){
660 strPrintf(&sql, "%s%d", zSep, i);
661 zSep = ", ";
662 }
663 strPrintf(&sql, ";\n");
664
665 if( g.fDebug & DEBUG_DIFF_SQL ){
666 printf("SQL for %s:\n%s\n", zId, sql.z);
667 goto end_diff_one_table;
668 }
669
670 /* Drop indexes that are missing in the destination */
671 pStmt = db_prepare(
672 "SELECT name FROM main.sqlite_master"
673 " WHERE type='index' AND tbl_name=%Q"
674 " AND sql IS NOT NULL"
675 " AND sql NOT IN (SELECT sql FROM aux.sqlite_master"
676 " WHERE type='index' AND tbl_name=%Q"
677 " AND sql IS NOT NULL)",
678 zTab, zTab);
679 while( SQLITE_ROW==sqlite3_step(pStmt) ){
680 char *z = safeId((const char*)sqlite3_column_text(pStmt,0));
drh8a1cd762015-04-14 19:01:08 +0000681 fprintf(out, "DROP INDEX %s;\n", z);
drhd62c0f42015-04-09 13:34:29 +0000682 sqlite3_free(z);
683 }
684 sqlite3_finalize(pStmt);
685
686 /* Run the query and output differences */
687 if( !g.bSchemaOnly ){
drh52254492016-07-08 02:14:24 +0000688 pStmt = db_prepare("%s", sql.z);
drhd62c0f42015-04-09 13:34:29 +0000689 while( SQLITE_ROW==sqlite3_step(pStmt) ){
690 int iType = sqlite3_column_int(pStmt, nPk);
691 if( iType==1 || iType==2 ){
692 if( iType==1 ){ /* Change the content of a row */
drh8a1cd762015-04-14 19:01:08 +0000693 fprintf(out, "UPDATE %s", zId);
drhd62c0f42015-04-09 13:34:29 +0000694 zSep = " SET";
695 for(i=nPk+1; i<nQ; i+=2){
696 if( sqlite3_column_int(pStmt,i)==0 ) continue;
drh8a1cd762015-04-14 19:01:08 +0000697 fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]);
drhd62c0f42015-04-09 13:34:29 +0000698 zSep = ",";
drh8a1cd762015-04-14 19:01:08 +0000699 printQuoted(out, sqlite3_column_value(pStmt,i+1));
drhd62c0f42015-04-09 13:34:29 +0000700 }
701 }else{ /* Delete a row */
drh8a1cd762015-04-14 19:01:08 +0000702 fprintf(out, "DELETE FROM %s", zId);
drhd62c0f42015-04-09 13:34:29 +0000703 }
704 zSep = " WHERE";
705 for(i=0; i<nPk; i++){
drh8a1cd762015-04-14 19:01:08 +0000706 fprintf(out, "%s %s=", zSep, az2[i]);
707 printQuoted(out, sqlite3_column_value(pStmt,i));
drh74504942015-11-09 12:47:04 +0000708 zSep = " AND";
drhd62c0f42015-04-09 13:34:29 +0000709 }
drh8a1cd762015-04-14 19:01:08 +0000710 fprintf(out, ";\n");
drhd62c0f42015-04-09 13:34:29 +0000711 }else{ /* Insert a row */
drh8a1cd762015-04-14 19:01:08 +0000712 fprintf(out, "INSERT INTO %s(%s", zId, az2[0]);
713 for(i=1; az2[i]; i++) fprintf(out, ",%s", az2[i]);
714 fprintf(out, ") VALUES");
drhd62c0f42015-04-09 13:34:29 +0000715 zSep = "(";
716 for(i=0; i<nPk2; i++){
drh8a1cd762015-04-14 19:01:08 +0000717 fprintf(out, "%s", zSep);
drhd62c0f42015-04-09 13:34:29 +0000718 zSep = ",";
drh8a1cd762015-04-14 19:01:08 +0000719 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000720 }
721 for(i=nPk2+2; i<nQ; i+=2){
drh8a1cd762015-04-14 19:01:08 +0000722 fprintf(out, ",");
723 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000724 }
drh8a1cd762015-04-14 19:01:08 +0000725 fprintf(out, ");\n");
drhd62c0f42015-04-09 13:34:29 +0000726 }
727 }
728 sqlite3_finalize(pStmt);
729 } /* endif !g.bSchemaOnly */
730
731 /* Create indexes that are missing in the source */
732 pStmt = db_prepare(
733 "SELECT sql FROM aux.sqlite_master"
734 " WHERE type='index' AND tbl_name=%Q"
735 " AND sql IS NOT NULL"
736 " AND sql NOT IN (SELECT sql FROM main.sqlite_master"
737 " WHERE type='index' AND tbl_name=%Q"
738 " AND sql IS NOT NULL)",
739 zTab, zTab);
740 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000741 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000742 }
743 sqlite3_finalize(pStmt);
744
745end_diff_one_table:
746 strFree(&sql);
747 sqlite3_free(zId);
748 namelistFree(az);
749 namelistFree(az2);
750 return;
751}
752
753/*
dan99461852015-07-30 20:26:16 +0000754** Check that table zTab exists and has the same schema in both the "main"
755** and "aux" databases currently opened by the global db handle. If they
756** do not, output an error message on stderr and exit(1). Otherwise, if
757** the schemas do match, return control to the caller.
758*/
759static void checkSchemasMatch(const char *zTab){
760 sqlite3_stmt *pStmt = db_prepare(
761 "SELECT A.sql=B.sql FROM main.sqlite_master A, aux.sqlite_master B"
762 " WHERE A.name=%Q AND B.name=%Q", zTab, zTab
763 );
764 if( SQLITE_ROW==sqlite3_step(pStmt) ){
765 if( sqlite3_column_int(pStmt,0)==0 ){
766 runtimeError("schema changes for table %s", safeId(zTab));
767 }
768 }else{
769 runtimeError("table %s missing from one or both databases", safeId(zTab));
770 }
771 sqlite3_finalize(pStmt);
772}
773
dana9ca8af2015-07-31 19:52:03 +0000774/**************************************************************************
775** The following code is copied from fossil. It is used to generate the
776** fossil delta blobs sometimes used in RBU update records.
777*/
778
779typedef unsigned short u16;
780typedef unsigned int u32;
781typedef unsigned char u8;
782
783/*
784** The width of a hash window in bytes. The algorithm only works if this
785** is a power of 2.
786*/
787#define NHASH 16
788
789/*
790** The current state of the rolling hash.
791**
792** z[] holds the values that have been hashed. z[] is a circular buffer.
793** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
794** the window.
795**
796** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted
797** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1.
798** (Each index for z[] should be module NHASH, of course. The %NHASH operator
799** is omitted in the prior expression for brevity.)
800*/
801typedef struct hash hash;
802struct hash {
803 u16 a, b; /* Hash values */
804 u16 i; /* Start of the hash window */
805 char z[NHASH]; /* The values that have been hashed */
806};
807
808/*
809** Initialize the rolling hash using the first NHASH characters of z[]
810*/
811static void hash_init(hash *pHash, const char *z){
812 u16 a, b, i;
813 a = b = 0;
814 for(i=0; i<NHASH; i++){
815 a += z[i];
816 b += (NHASH-i)*z[i];
817 pHash->z[i] = z[i];
818 }
819 pHash->a = a & 0xffff;
820 pHash->b = b & 0xffff;
821 pHash->i = 0;
822}
823
824/*
825** Advance the rolling hash by a single character "c"
826*/
827static void hash_next(hash *pHash, int c){
828 u16 old = pHash->z[pHash->i];
mistachkin1abbe282015-08-20 21:09:32 +0000829 pHash->z[pHash->i] = (char)c;
dana9ca8af2015-07-31 19:52:03 +0000830 pHash->i = (pHash->i+1)&(NHASH-1);
mistachkin1abbe282015-08-20 21:09:32 +0000831 pHash->a = pHash->a - old + (char)c;
dana9ca8af2015-07-31 19:52:03 +0000832 pHash->b = pHash->b - NHASH*old + pHash->a;
833}
834
835/*
836** Return a 32-bit hash value
837*/
838static u32 hash_32bit(hash *pHash){
839 return (pHash->a & 0xffff) | (((u32)(pHash->b & 0xffff))<<16);
840}
841
842/*
843** Write an base-64 integer into the given buffer.
844*/
845static void putInt(unsigned int v, char **pz){
846 static const char zDigits[] =
847 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
848 /* 123456789 123456789 123456789 123456789 123456789 123456789 123 */
849 int i, j;
850 char zBuf[20];
851 if( v==0 ){
852 *(*pz)++ = '0';
853 return;
854 }
855 for(i=0; v>0; i++, v>>=6){
856 zBuf[i] = zDigits[v&0x3f];
857 }
858 for(j=i-1; j>=0; j--){
859 *(*pz)++ = zBuf[j];
860 }
861}
862
863/*
dana9ca8af2015-07-31 19:52:03 +0000864** Return the number digits in the base-64 representation of a positive integer
865*/
866static int digit_count(int v){
867 unsigned int i, x;
mistachkin1abbe282015-08-20 21:09:32 +0000868 for(i=1, x=64; (unsigned int)v>=x; i++, x <<= 6){}
dana9ca8af2015-07-31 19:52:03 +0000869 return i;
870}
871
872/*
873** Compute a 32-bit checksum on the N-byte buffer. Return the result.
874*/
875static unsigned int checksum(const char *zIn, size_t N){
876 const unsigned char *z = (const unsigned char *)zIn;
877 unsigned sum0 = 0;
878 unsigned sum1 = 0;
879 unsigned sum2 = 0;
880 unsigned sum3 = 0;
881 while(N >= 16){
882 sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
883 sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
884 sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
885 sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
886 z += 16;
887 N -= 16;
888 }
889 while(N >= 4){
890 sum0 += z[0];
891 sum1 += z[1];
892 sum2 += z[2];
893 sum3 += z[3];
894 z += 4;
895 N -= 4;
896 }
897 sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
898 switch(N){
899 case 3: sum3 += (z[2] << 8);
900 case 2: sum3 += (z[1] << 16);
901 case 1: sum3 += (z[0] << 24);
902 default: ;
903 }
904 return sum3;
905}
906
907/*
908** Create a new delta.
909**
910** The delta is written into a preallocated buffer, zDelta, which
911** should be at least 60 bytes longer than the target file, zOut.
912** The delta string will be NUL-terminated, but it might also contain
913** embedded NUL characters if either the zSrc or zOut files are
914** binary. This function returns the length of the delta string
915** in bytes, excluding the final NUL terminator character.
916**
917** Output Format:
918**
919** The delta begins with a base64 number followed by a newline. This
920** number is the number of bytes in the TARGET file. Thus, given a
921** delta file z, a program can compute the size of the output file
922** simply by reading the first line and decoding the base-64 number
923** found there. The delta_output_size() routine does exactly this.
924**
925** After the initial size number, the delta consists of a series of
926** literal text segments and commands to copy from the SOURCE file.
927** A copy command looks like this:
928**
929** NNN@MMM,
930**
931** where NNN is the number of bytes to be copied and MMM is the offset
932** into the source file of the first byte (both base-64). If NNN is 0
933** it means copy the rest of the input file. Literal text is like this:
934**
935** NNN:TTTTT
936**
937** where NNN is the number of bytes of text (base-64) and TTTTT is the text.
938**
939** The last term is of the form
940**
941** NNN;
942**
943** In this case, NNN is a 32-bit bigendian checksum of the output file
944** that can be used to verify that the delta applied correctly. All
945** numbers are in base-64.
946**
947** Pure text files generate a pure text delta. Binary files generate a
948** delta that may contain some binary data.
949**
950** Algorithm:
951**
952** The encoder first builds a hash table to help it find matching
953** patterns in the source file. 16-byte chunks of the source file
954** sampled at evenly spaced intervals are used to populate the hash
955** table.
956**
957** Next we begin scanning the target file using a sliding 16-byte
958** window. The hash of the 16-byte window in the target is used to
959** search for a matching section in the source file. When a match
960** is found, a copy command is added to the delta. An effort is
961** made to extend the matching section to regions that come before
962** and after the 16-byte hash window. A copy command is only issued
963** if the result would use less space that just quoting the text
964** literally. Literal text is added to the delta for sections that
965** do not match or which can not be encoded efficiently using copy
966** commands.
967*/
968static int rbuDeltaCreate(
969 const char *zSrc, /* The source or pattern file */
970 unsigned int lenSrc, /* Length of the source file */
971 const char *zOut, /* The target file */
972 unsigned int lenOut, /* Length of the target file */
973 char *zDelta /* Write the delta into this buffer */
974){
mistachkin1abbe282015-08-20 21:09:32 +0000975 unsigned int i, base;
dana9ca8af2015-07-31 19:52:03 +0000976 char *zOrigDelta = zDelta;
977 hash h;
978 int nHash; /* Number of hash table entries */
979 int *landmark; /* Primary hash table */
980 int *collide; /* Collision chain */
981 int lastRead = -1; /* Last byte of zSrc read by a COPY command */
982
983 /* Add the target file size to the beginning of the delta
984 */
985 putInt(lenOut, &zDelta);
986 *(zDelta++) = '\n';
987
988 /* If the source file is very small, it means that we have no
989 ** chance of ever doing a copy command. Just output a single
990 ** literal segment for the entire target and exit.
991 */
992 if( lenSrc<=NHASH ){
993 putInt(lenOut, &zDelta);
994 *(zDelta++) = ':';
995 memcpy(zDelta, zOut, lenOut);
996 zDelta += lenOut;
997 putInt(checksum(zOut, lenOut), &zDelta);
998 *(zDelta++) = ';';
drh62e63bb2016-01-14 12:23:16 +0000999 return (int)(zDelta - zOrigDelta);
dana9ca8af2015-07-31 19:52:03 +00001000 }
1001
1002 /* Compute the hash table used to locate matching sections in the
1003 ** source file.
1004 */
1005 nHash = lenSrc/NHASH;
1006 collide = sqlite3_malloc( nHash*2*sizeof(int) );
1007 landmark = &collide[nHash];
1008 memset(landmark, -1, nHash*sizeof(int));
1009 memset(collide, -1, nHash*sizeof(int));
1010 for(i=0; i<lenSrc-NHASH; i+=NHASH){
1011 int hv;
1012 hash_init(&h, &zSrc[i]);
1013 hv = hash_32bit(&h) % nHash;
1014 collide[i/NHASH] = landmark[hv];
1015 landmark[hv] = i/NHASH;
1016 }
1017
1018 /* Begin scanning the target file and generating copy commands and
1019 ** literal sections of the delta.
1020 */
1021 base = 0; /* We have already generated everything before zOut[base] */
1022 while( base+NHASH<lenOut ){
1023 int iSrc, iBlock;
mistachkin1abbe282015-08-20 21:09:32 +00001024 int bestCnt, bestOfst=0, bestLitsz=0;
dana9ca8af2015-07-31 19:52:03 +00001025 hash_init(&h, &zOut[base]);
1026 i = 0; /* Trying to match a landmark against zOut[base+i] */
1027 bestCnt = 0;
1028 while( 1 ){
1029 int hv;
1030 int limit = 250;
1031
1032 hv = hash_32bit(&h) % nHash;
1033 iBlock = landmark[hv];
1034 while( iBlock>=0 && (limit--)>0 ){
1035 /*
1036 ** The hash window has identified a potential match against
1037 ** landmark block iBlock. But we need to investigate further.
1038 **
1039 ** Look for a region in zOut that matches zSrc. Anchor the search
1040 ** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to
1041 ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
1042 **
1043 ** Set cnt equal to the length of the match and set ofst so that
1044 ** zSrc[ofst] is the first element of the match. litsz is the number
1045 ** of characters between zOut[base] and the beginning of the match.
1046 ** sz will be the overhead (in bytes) needed to encode the copy
1047 ** command. Only generate copy command if the overhead of the
1048 ** copy command is less than the amount of literal text to be copied.
1049 */
1050 int cnt, ofst, litsz;
1051 int j, k, x, y;
1052 int sz;
1053
1054 /* Beginning at iSrc, match forwards as far as we can. j counts
1055 ** the number of characters that match */
1056 iSrc = iBlock*NHASH;
mistachkin1abbe282015-08-20 21:09:32 +00001057 for(
1058 j=0, x=iSrc, y=base+i;
1059 (unsigned int)x<lenSrc && (unsigned int)y<lenOut;
1060 j++, x++, y++
1061 ){
dana9ca8af2015-07-31 19:52:03 +00001062 if( zSrc[x]!=zOut[y] ) break;
1063 }
1064 j--;
1065
1066 /* Beginning at iSrc-1, match backwards as far as we can. k counts
1067 ** the number of characters that match */
mistachkin1abbe282015-08-20 21:09:32 +00001068 for(k=1; k<iSrc && (unsigned int)k<=i; k++){
dana9ca8af2015-07-31 19:52:03 +00001069 if( zSrc[iSrc-k]!=zOut[base+i-k] ) break;
1070 }
1071 k--;
1072
1073 /* Compute the offset and size of the matching region */
1074 ofst = iSrc-k;
1075 cnt = j+k+1;
1076 litsz = i-k; /* Number of bytes of literal text before the copy */
1077 /* sz will hold the number of bytes needed to encode the "insert"
1078 ** command and the copy command, not counting the "insert" text */
1079 sz = digit_count(i-k)+digit_count(cnt)+digit_count(ofst)+3;
1080 if( cnt>=sz && cnt>bestCnt ){
1081 /* Remember this match only if it is the best so far and it
1082 ** does not increase the file size */
1083 bestCnt = cnt;
1084 bestOfst = iSrc-k;
1085 bestLitsz = litsz;
1086 }
1087
1088 /* Check the next matching block */
1089 iBlock = collide[iBlock];
1090 }
1091
1092 /* We have a copy command that does not cause the delta to be larger
1093 ** than a literal insert. So add the copy command to the delta.
1094 */
1095 if( bestCnt>0 ){
1096 if( bestLitsz>0 ){
1097 /* Add an insert command before the copy */
1098 putInt(bestLitsz,&zDelta);
1099 *(zDelta++) = ':';
1100 memcpy(zDelta, &zOut[base], bestLitsz);
1101 zDelta += bestLitsz;
1102 base += bestLitsz;
1103 }
1104 base += bestCnt;
1105 putInt(bestCnt, &zDelta);
1106 *(zDelta++) = '@';
1107 putInt(bestOfst, &zDelta);
1108 *(zDelta++) = ',';
1109 if( bestOfst + bestCnt -1 > lastRead ){
1110 lastRead = bestOfst + bestCnt - 1;
1111 }
1112 bestCnt = 0;
1113 break;
1114 }
1115
1116 /* If we reach this point, it means no match is found so far */
1117 if( base+i+NHASH>=lenOut ){
1118 /* We have reached the end of the file and have not found any
1119 ** matches. Do an "insert" for everything that does not match */
1120 putInt(lenOut-base, &zDelta);
1121 *(zDelta++) = ':';
1122 memcpy(zDelta, &zOut[base], lenOut-base);
1123 zDelta += lenOut-base;
1124 base = lenOut;
1125 break;
1126 }
1127
1128 /* Advance the hash by one character. Keep looking for a match */
1129 hash_next(&h, zOut[base+i+NHASH]);
1130 i++;
1131 }
1132 }
1133 /* Output a final "insert" record to get all the text at the end of
1134 ** the file that does not match anything in the source file.
1135 */
1136 if( base<lenOut ){
1137 putInt(lenOut-base, &zDelta);
1138 *(zDelta++) = ':';
1139 memcpy(zDelta, &zOut[base], lenOut-base);
1140 zDelta += lenOut-base;
1141 }
1142 /* Output the final checksum record. */
1143 putInt(checksum(zOut, lenOut), &zDelta);
1144 *(zDelta++) = ';';
1145 sqlite3_free(collide);
drh62e63bb2016-01-14 12:23:16 +00001146 return (int)(zDelta - zOrigDelta);
dana9ca8af2015-07-31 19:52:03 +00001147}
1148
1149/*
1150** End of code copied from fossil.
1151**************************************************************************/
1152
dan99461852015-07-30 20:26:16 +00001153static void strPrintfArray(
1154 Str *pStr, /* String object to append to */
1155 const char *zSep, /* Separator string */
1156 const char *zFmt, /* Format for each entry */
1157 char **az, int n /* Array of strings & its size (or -1) */
1158){
1159 int i;
1160 for(i=0; az[i] && (i<n || n<0); i++){
1161 if( i!=0 ) strPrintf(pStr, "%s", zSep);
1162 strPrintf(pStr, zFmt, az[i], az[i], az[i]);
1163 }
1164}
1165
1166static void getRbudiffQuery(
1167 const char *zTab,
1168 char **azCol,
1169 int nPK,
1170 int bOtaRowid,
1171 Str *pSql
1172){
1173 int i;
1174
1175 /* First the newly inserted rows: **/
1176 strPrintf(pSql, "SELECT ");
1177 strPrintfArray(pSql, ", ", "%s", azCol, -1);
dana9ca8af2015-07-31 19:52:03 +00001178 strPrintf(pSql, ", 0, "); /* Set ota_control to 0 for an insert */
1179 strPrintfArray(pSql, ", ", "NULL", azCol, -1);
dan99461852015-07-30 20:26:16 +00001180 strPrintf(pSql, " FROM aux.%Q AS n WHERE NOT EXISTS (\n", zTab);
1181 strPrintf(pSql, " SELECT 1 FROM ", zTab);
1182 strPrintf(pSql, " main.%Q AS o WHERE ", zTab);
dane5a0cfa2016-09-01 14:03:28 +00001183 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
1184 strPrintf(pSql, "\n) AND ");
1185 strPrintfArray(pSql, " AND ", "(n.%Q IS NOT NULL)", azCol, nPK);
dan99461852015-07-30 20:26:16 +00001186
1187 /* Deleted rows: */
1188 strPrintf(pSql, "\nUNION ALL\nSELECT ");
1189 strPrintfArray(pSql, ", ", "%s", azCol, nPK);
dandd688e72015-07-31 15:13:29 +00001190 if( azCol[nPK] ){
1191 strPrintf(pSql, ", ");
1192 strPrintfArray(pSql, ", ", "NULL", &azCol[nPK], -1);
1193 }
dana9ca8af2015-07-31 19:52:03 +00001194 strPrintf(pSql, ", 1, "); /* Set ota_control to 1 for a delete */
1195 strPrintfArray(pSql, ", ", "NULL", azCol, -1);
dan99461852015-07-30 20:26:16 +00001196 strPrintf(pSql, " FROM main.%Q AS n WHERE NOT EXISTS (\n", zTab);
1197 strPrintf(pSql, " SELECT 1 FROM ", zTab);
1198 strPrintf(pSql, " aux.%Q AS o WHERE ", zTab);
dane5a0cfa2016-09-01 14:03:28 +00001199 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
1200 strPrintf(pSql, "\n) AND ");
1201 strPrintfArray(pSql, " AND ", "(n.%Q IS NOT NULL)", azCol, nPK);
dan99461852015-07-30 20:26:16 +00001202
dandd688e72015-07-31 15:13:29 +00001203 /* Updated rows. If all table columns are part of the primary key, there
1204 ** can be no updates. In this case this part of the compound SELECT can
1205 ** be omitted altogether. */
1206 if( azCol[nPK] ){
1207 strPrintf(pSql, "\nUNION ALL\nSELECT ");
1208 strPrintfArray(pSql, ", ", "n.%s", azCol, nPK);
dan99461852015-07-30 20:26:16 +00001209 strPrintf(pSql, ",\n");
dandd688e72015-07-31 15:13:29 +00001210 strPrintfArray(pSql, " ,\n",
1211 " CASE WHEN n.%s IS o.%s THEN NULL ELSE n.%s END", &azCol[nPK], -1
1212 );
dan99461852015-07-30 20:26:16 +00001213
dandd688e72015-07-31 15:13:29 +00001214 if( bOtaRowid==0 ){
1215 strPrintf(pSql, ", '");
1216 strPrintfArray(pSql, "", ".", azCol, nPK);
1217 strPrintf(pSql, "' ||\n");
1218 }else{
1219 strPrintf(pSql, ",\n");
1220 }
1221 strPrintfArray(pSql, " ||\n",
1222 " CASE WHEN n.%s IS o.%s THEN '.' ELSE 'x' END", &azCol[nPK], -1
1223 );
dana9ca8af2015-07-31 19:52:03 +00001224 strPrintf(pSql, "\nAS ota_control, ");
1225 strPrintfArray(pSql, ", ", "NULL", azCol, nPK);
1226 strPrintf(pSql, ",\n");
1227 strPrintfArray(pSql, " ,\n",
1228 " CASE WHEN n.%s IS o.%s THEN NULL ELSE o.%s END", &azCol[nPK], -1
1229 );
dandd688e72015-07-31 15:13:29 +00001230
1231 strPrintf(pSql, "\nFROM main.%Q AS o, aux.%Q AS n\nWHERE ", zTab, zTab);
dane5a0cfa2016-09-01 14:03:28 +00001232 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
dandd688e72015-07-31 15:13:29 +00001233 strPrintf(pSql, " AND ota_control LIKE '%%x%%'");
1234 }
dan99461852015-07-30 20:26:16 +00001235
1236 /* Now add an ORDER BY clause to sort everything by PK. */
1237 strPrintf(pSql, "\nORDER BY ");
1238 for(i=1; i<=nPK; i++) strPrintf(pSql, "%s%d", ((i>1)?", ":""), i);
1239}
1240
1241static void rbudiff_one_table(const char *zTab, FILE *out){
1242 int bOtaRowid; /* True to use an ota_rowid column */
1243 int nPK; /* Number of primary key columns in table */
1244 char **azCol; /* NULL terminated array of col names */
1245 int i;
1246 int nCol;
1247 Str ct = {0, 0, 0}; /* The "CREATE TABLE data_xxx" statement */
1248 Str sql = {0, 0, 0}; /* Query to find differences */
1249 Str insert = {0, 0, 0}; /* First part of output INSERT statement */
1250 sqlite3_stmt *pStmt = 0;
danfebfe022016-03-19 16:21:26 +00001251 int nRow = 0; /* Total rows in data_xxx table */
dan99461852015-07-30 20:26:16 +00001252
1253 /* --rbu mode must use real primary keys. */
1254 g.bSchemaPK = 1;
1255
1256 /* Check that the schemas of the two tables match. Exit early otherwise. */
1257 checkSchemasMatch(zTab);
1258
1259 /* Grab the column names and PK details for the table(s). If no usable PK
1260 ** columns are found, bail out early. */
1261 azCol = columnNames("main", zTab, &nPK, &bOtaRowid);
1262 if( azCol==0 ){
1263 runtimeError("table %s has no usable PK columns", zTab);
1264 }
dana9ca8af2015-07-31 19:52:03 +00001265 for(nCol=0; azCol[nCol]; nCol++);
dan99461852015-07-30 20:26:16 +00001266
1267 /* Build and output the CREATE TABLE statement for the data_xxx table */
1268 strPrintf(&ct, "CREATE TABLE IF NOT EXISTS 'data_%q'(", zTab);
1269 if( bOtaRowid ) strPrintf(&ct, "rbu_rowid, ");
1270 strPrintfArray(&ct, ", ", "%s", &azCol[bOtaRowid], -1);
1271 strPrintf(&ct, ", rbu_control);");
1272
dan99461852015-07-30 20:26:16 +00001273 /* Get the SQL for the query to retrieve data from the two databases */
1274 getRbudiffQuery(zTab, azCol, nPK, bOtaRowid, &sql);
1275
1276 /* Build the first part of the INSERT statement output for each row
1277 ** in the data_xxx table. */
1278 strPrintf(&insert, "INSERT INTO 'data_%q' (", zTab);
1279 if( bOtaRowid ) strPrintf(&insert, "rbu_rowid, ");
1280 strPrintfArray(&insert, ", ", "%s", &azCol[bOtaRowid], -1);
1281 strPrintf(&insert, ", rbu_control) VALUES(");
1282
1283 pStmt = db_prepare("%s", sql.z);
dana9ca8af2015-07-31 19:52:03 +00001284
dan99461852015-07-30 20:26:16 +00001285 while( sqlite3_step(pStmt)==SQLITE_ROW ){
dana9ca8af2015-07-31 19:52:03 +00001286
1287 /* If this is the first row output, print out the CREATE TABLE
1288 ** statement first. And then set ct.z to NULL so that it is not
1289 ** printed again. */
dan99461852015-07-30 20:26:16 +00001290 if( ct.z ){
1291 fprintf(out, "%s\n", ct.z);
1292 strFree(&ct);
1293 }
1294
dana9ca8af2015-07-31 19:52:03 +00001295 /* Output the first part of the INSERT statement */
dan99461852015-07-30 20:26:16 +00001296 fprintf(out, "%s", insert.z);
danfebfe022016-03-19 16:21:26 +00001297 nRow++;
dana9ca8af2015-07-31 19:52:03 +00001298
1299 if( sqlite3_column_type(pStmt, nCol)==SQLITE_INTEGER ){
1300 for(i=0; i<=nCol; i++){
1301 if( i>0 ) fprintf(out, ", ");
1302 printQuoted(out, sqlite3_column_value(pStmt, i));
1303 }
1304 }else{
1305 char *zOtaControl;
1306 int nOtaControl = sqlite3_column_bytes(pStmt, nCol);
1307
dan6ff46272016-08-11 09:55:55 +00001308 zOtaControl = (char*)sqlite3_malloc(nOtaControl+1);
dana9ca8af2015-07-31 19:52:03 +00001309 memcpy(zOtaControl, sqlite3_column_text(pStmt, nCol), nOtaControl+1);
1310
1311 for(i=0; i<nCol; i++){
1312 int bDone = 0;
1313 if( i>=nPK
1314 && sqlite3_column_type(pStmt, i)==SQLITE_BLOB
1315 && sqlite3_column_type(pStmt, nCol+1+i)==SQLITE_BLOB
1316 ){
1317 const char *aSrc = sqlite3_column_blob(pStmt, nCol+1+i);
1318 int nSrc = sqlite3_column_bytes(pStmt, nCol+1+i);
1319 const char *aFinal = sqlite3_column_blob(pStmt, i);
1320 int nFinal = sqlite3_column_bytes(pStmt, i);
1321 char *aDelta;
1322 int nDelta;
1323
1324 aDelta = sqlite3_malloc(nFinal + 60);
1325 nDelta = rbuDeltaCreate(aSrc, nSrc, aFinal, nFinal, aDelta);
1326 if( nDelta<nFinal ){
1327 int j;
1328 fprintf(out, "x'");
1329 for(j=0; j<nDelta; j++) fprintf(out, "%02x", (u8)aDelta[j]);
1330 fprintf(out, "'");
1331 zOtaControl[i-bOtaRowid] = 'f';
1332 bDone = 1;
1333 }
1334 sqlite3_free(aDelta);
1335 }
1336
1337 if( bDone==0 ){
1338 printQuoted(out, sqlite3_column_value(pStmt, i));
1339 }
1340 fprintf(out, ", ");
1341 }
1342 fprintf(out, "'%s'", zOtaControl);
1343 sqlite3_free(zOtaControl);
dan99461852015-07-30 20:26:16 +00001344 }
dana9ca8af2015-07-31 19:52:03 +00001345
1346 /* And the closing bracket of the insert statement */
dan99461852015-07-30 20:26:16 +00001347 fprintf(out, ");\n");
1348 }
1349
1350 sqlite3_finalize(pStmt);
danfebfe022016-03-19 16:21:26 +00001351 if( nRow>0 ){
1352 Str cnt = {0, 0, 0};
1353 strPrintf(&cnt, "INSERT INTO rbu_count VALUES('data_%q', %d);", zTab, nRow);
1354 fprintf(out, "%s\n", cnt.z);
1355 strFree(&cnt);
1356 }
dan99461852015-07-30 20:26:16 +00001357
1358 strFree(&ct);
1359 strFree(&sql);
1360 strFree(&insert);
1361}
1362
1363/*
drh8a1cd762015-04-14 19:01:08 +00001364** Display a summary of differences between two versions of the same
1365** table table.
1366**
1367** * Number of rows changed
1368** * Number of rows added
1369** * Number of rows deleted
1370** * Number of identical rows
1371*/
1372static void summarize_one_table(const char *zTab, FILE *out){
1373 char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
1374 char **az = 0; /* Columns in main */
1375 char **az2 = 0; /* Columns in aux */
1376 int nPk; /* Primary key columns in main */
1377 int nPk2; /* Primary key columns in aux */
drhb3f3d642015-04-25 18:39:21 +00001378 int n = 0; /* Number of columns in main */
drh8a1cd762015-04-14 19:01:08 +00001379 int n2; /* Number of columns in aux */
1380 int i; /* Loop counter */
1381 const char *zSep; /* Separator string */
1382 Str sql; /* Comparison query */
1383 sqlite3_stmt *pStmt; /* Query statement to do the diff */
1384 sqlite3_int64 nUpdate; /* Number of updated rows */
1385 sqlite3_int64 nUnchanged; /* Number of unmodified rows */
1386 sqlite3_int64 nDelete; /* Number of deleted rows */
1387 sqlite3_int64 nInsert; /* Number of inserted rows */
1388
1389 strInit(&sql);
1390 if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
1391 if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
1392 /* Table missing from second database. */
1393 fprintf(out, "%s: missing from second database\n", zTab);
1394 }
1395 goto end_summarize_one_table;
1396 }
1397
1398 if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
1399 /* Table missing from source */
1400 fprintf(out, "%s: missing from first database\n", zTab);
1401 goto end_summarize_one_table;
1402 }
1403
dan99461852015-07-30 20:26:16 +00001404 az = columnNames("main", zTab, &nPk, 0);
1405 az2 = columnNames("aux", zTab, &nPk2, 0);
drh8a1cd762015-04-14 19:01:08 +00001406 if( az && az2 ){
1407 for(n=0; az[n]; n++){
1408 if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
1409 }
1410 }
1411 if( az==0
1412 || az2==0
1413 || nPk!=nPk2
1414 || az[n]
1415 ){
1416 /* Schema mismatch */
1417 fprintf(out, "%s: incompatible schema\n", zTab);
1418 goto end_summarize_one_table;
1419 }
1420
1421 /* Build the comparison query */
1422 for(n2=n; az[n2]; n2++){}
1423 strPrintf(&sql, "SELECT 1, count(*)");
1424 if( n2==nPk2 ){
1425 strPrintf(&sql, ", 0\n");
1426 }else{
1427 zSep = ", sum(";
1428 for(i=nPk; az[i]; i++){
1429 strPrintf(&sql, "%sA.%s IS NOT B.%s", zSep, az[i], az[i]);
1430 zSep = " OR ";
1431 }
1432 strPrintf(&sql, ")\n");
1433 }
1434 strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId);
1435 zSep = " WHERE";
1436 for(i=0; i<nPk; i++){
1437 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
1438 zSep = " AND";
1439 }
1440 strPrintf(&sql, " UNION ALL\n");
1441 strPrintf(&sql, "SELECT 2, count(*), 0\n");
1442 strPrintf(&sql, " FROM main.%s A\n", zId);
1443 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B ", zId);
1444 zSep = "WHERE";
1445 for(i=0; i<nPk; i++){
1446 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
1447 zSep = " AND";
1448 }
1449 strPrintf(&sql, ")\n");
1450 strPrintf(&sql, " UNION ALL\n");
1451 strPrintf(&sql, "SELECT 3, count(*), 0\n");
1452 strPrintf(&sql, " FROM aux.%s B\n", zId);
1453 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A ", zId);
1454 zSep = "WHERE";
1455 for(i=0; i<nPk; i++){
1456 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
1457 zSep = " AND";
1458 }
1459 strPrintf(&sql, ")\n ORDER BY 1;\n");
1460
1461 if( (g.fDebug & DEBUG_DIFF_SQL)!=0 ){
1462 printf("SQL for %s:\n%s\n", zId, sql.z);
1463 goto end_summarize_one_table;
1464 }
1465
1466 /* Run the query and output difference summary */
drh52254492016-07-08 02:14:24 +00001467 pStmt = db_prepare("%s", sql.z);
drh8a1cd762015-04-14 19:01:08 +00001468 nUpdate = 0;
1469 nInsert = 0;
1470 nDelete = 0;
1471 nUnchanged = 0;
1472 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1473 switch( sqlite3_column_int(pStmt,0) ){
1474 case 1:
1475 nUpdate = sqlite3_column_int64(pStmt,2);
1476 nUnchanged = sqlite3_column_int64(pStmt,1) - nUpdate;
1477 break;
1478 case 2:
1479 nDelete = sqlite3_column_int64(pStmt,1);
1480 break;
1481 case 3:
1482 nInsert = sqlite3_column_int64(pStmt,1);
1483 break;
1484 }
1485 }
1486 sqlite3_finalize(pStmt);
1487 fprintf(out, "%s: %lld changes, %lld inserts, %lld deletes, %lld unchanged\n",
1488 zTab, nUpdate, nInsert, nDelete, nUnchanged);
1489
1490end_summarize_one_table:
1491 strFree(&sql);
1492 sqlite3_free(zId);
1493 namelistFree(az);
1494 namelistFree(az2);
1495 return;
1496}
1497
1498/*
drh697e5db2015-04-11 12:07:40 +00001499** Write a 64-bit signed integer as a varint onto out
1500*/
1501static void putsVarint(FILE *out, sqlite3_uint64 v){
1502 int i, n;
drh6e42ce42015-04-11 13:48:01 +00001503 unsigned char p[12];
drh697e5db2015-04-11 12:07:40 +00001504 if( v & (((sqlite3_uint64)0xff000000)<<32) ){
1505 p[8] = (unsigned char)v;
1506 v >>= 8;
1507 for(i=7; i>=0; i--){
1508 p[i] = (unsigned char)((v & 0x7f) | 0x80);
1509 v >>= 7;
1510 }
1511 fwrite(p, 8, 1, out);
1512 }else{
1513 n = 9;
1514 do{
1515 p[n--] = (unsigned char)((v & 0x7f) | 0x80);
1516 v >>= 7;
1517 }while( v!=0 );
drh6e42ce42015-04-11 13:48:01 +00001518 p[9] &= 0x7f;
1519 fwrite(p+n+1, 9-n, 1, out);
1520 }
1521}
1522
1523/*
1524** Write an SQLite value onto out.
1525*/
1526static void putValue(FILE *out, sqlite3_value *pVal){
1527 int iDType = sqlite3_value_type(pVal);
1528 sqlite3_int64 iX;
1529 double rX;
1530 sqlite3_uint64 uX;
1531 int j;
1532
1533 putc(iDType, out);
1534 switch( iDType ){
1535 case SQLITE_INTEGER:
1536 iX = sqlite3_value_int64(pVal);
1537 memcpy(&uX, &iX, 8);
1538 for(j=56; j>=0; j-=8) putc((uX>>j)&0xff, out);
1539 break;
1540 case SQLITE_FLOAT:
drh33aa4db2015-05-04 15:04:47 +00001541 rX = sqlite3_value_double(pVal);
drh6e42ce42015-04-11 13:48:01 +00001542 memcpy(&uX, &rX, 8);
1543 for(j=56; j>=0; j-=8) putc((uX>>j)&0xff, out);
1544 break;
1545 case SQLITE_TEXT:
1546 iX = sqlite3_value_bytes(pVal);
1547 putsVarint(out, (sqlite3_uint64)iX);
drh33aa4db2015-05-04 15:04:47 +00001548 fwrite(sqlite3_value_text(pVal),1,(size_t)iX,out);
drh6e42ce42015-04-11 13:48:01 +00001549 break;
1550 case SQLITE_BLOB:
1551 iX = sqlite3_value_bytes(pVal);
1552 putsVarint(out, (sqlite3_uint64)iX);
drh33aa4db2015-05-04 15:04:47 +00001553 fwrite(sqlite3_value_blob(pVal),1,(size_t)iX,out);
drh6e42ce42015-04-11 13:48:01 +00001554 break;
1555 case SQLITE_NULL:
1556 break;
drh697e5db2015-04-11 12:07:40 +00001557 }
1558}
1559
1560/*
drh83e63dc2015-04-10 19:41:18 +00001561** Generate a CHANGESET for all differences from main.zTab to aux.zTab.
1562*/
1563static void changeset_one_table(const char *zTab, FILE *out){
1564 sqlite3_stmt *pStmt; /* SQL statment */
1565 char *zId = safeId(zTab); /* Escaped name of the table */
1566 char **azCol = 0; /* List of escaped column names */
1567 int nCol = 0; /* Number of columns */
1568 int *aiFlg = 0; /* 0 if column is not part of PK */
1569 int *aiPk = 0; /* Column numbers for each PK column */
1570 int nPk = 0; /* Number of PRIMARY KEY columns */
1571 Str sql; /* SQL for the diff query */
drh6e42ce42015-04-11 13:48:01 +00001572 int i, k; /* Loop counters */
drh83e63dc2015-04-10 19:41:18 +00001573 const char *zSep; /* List separator */
1574
dan99461852015-07-30 20:26:16 +00001575 /* Check that the schemas of the two tables match. Exit early otherwise. */
1576 checkSchemasMatch(zTab);
1577
drh83e63dc2015-04-10 19:41:18 +00001578 pStmt = db_prepare("PRAGMA main.table_info=%Q", zTab);
1579 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1580 nCol++;
1581 azCol = sqlite3_realloc(azCol, sizeof(char*)*nCol);
1582 if( azCol==0 ) runtimeError("out of memory");
1583 aiFlg = sqlite3_realloc(aiFlg, sizeof(int)*nCol);
1584 if( aiFlg==0 ) runtimeError("out of memory");
1585 azCol[nCol-1] = safeId((const char*)sqlite3_column_text(pStmt,1));
1586 aiFlg[nCol-1] = i = sqlite3_column_int(pStmt,5);
1587 if( i>0 ){
1588 if( i>nPk ){
1589 nPk = i;
1590 aiPk = sqlite3_realloc(aiPk, sizeof(int)*nPk);
1591 if( aiPk==0 ) runtimeError("out of memory");
1592 }
1593 aiPk[i-1] = nCol-1;
1594 }
1595 }
1596 sqlite3_finalize(pStmt);
1597 if( nPk==0 ) goto end_changeset_one_table;
1598 strInit(&sql);
1599 if( nCol>nPk ){
drh697e5db2015-04-11 12:07:40 +00001600 strPrintf(&sql, "SELECT %d", SQLITE_UPDATE);
drh6e42ce42015-04-11 13:48:01 +00001601 for(i=0; i<nCol; i++){
1602 if( aiFlg[i] ){
1603 strPrintf(&sql, ",\n A.%s", azCol[i]);
1604 }else{
1605 strPrintf(&sql, ",\n A.%s IS NOT B.%s, A.%s, B.%s",
1606 azCol[i], azCol[i], azCol[i], azCol[i]);
1607 }
1608 }
drh83e63dc2015-04-10 19:41:18 +00001609 strPrintf(&sql,"\n FROM main.%s A, aux.%s B\n", zId, zId);
1610 zSep = " WHERE";
1611 for(i=0; i<nPk; i++){
1612 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1613 zSep = " AND";
1614 }
1615 zSep = "\n AND (";
1616 for(i=0; i<nCol; i++){
1617 if( aiFlg[i] ) continue;
1618 strPrintf(&sql, "%sA.%s IS NOT B.%s", zSep, azCol[i], azCol[i]);
1619 zSep = " OR\n ";
1620 }
1621 strPrintf(&sql,")\n UNION ALL\n");
1622 }
drh697e5db2015-04-11 12:07:40 +00001623 strPrintf(&sql, "SELECT %d", SQLITE_DELETE);
drh6e42ce42015-04-11 13:48:01 +00001624 for(i=0; i<nCol; i++){
1625 if( aiFlg[i] ){
1626 strPrintf(&sql, ",\n A.%s", azCol[i]);
1627 }else{
1628 strPrintf(&sql, ",\n 1, A.%s, NULL", azCol[i]);
1629 }
1630 }
1631 strPrintf(&sql, "\n FROM main.%s A\n", zId);
drh83e63dc2015-04-10 19:41:18 +00001632 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B\n", zId);
1633 zSep = " WHERE";
1634 for(i=0; i<nPk; i++){
1635 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1636 zSep = " AND";
1637 }
1638 strPrintf(&sql, ")\n UNION ALL\n");
drh697e5db2015-04-11 12:07:40 +00001639 strPrintf(&sql, "SELECT %d", SQLITE_INSERT);
drh6e42ce42015-04-11 13:48:01 +00001640 for(i=0; i<nCol; i++){
1641 if( aiFlg[i] ){
1642 strPrintf(&sql, ",\n B.%s", azCol[i]);
1643 }else{
1644 strPrintf(&sql, ",\n 1, NULL, B.%s", azCol[i]);
1645 }
1646 }
1647 strPrintf(&sql, "\n FROM aux.%s B\n", zId);
drh83e63dc2015-04-10 19:41:18 +00001648 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A\n", zId);
1649 zSep = " WHERE";
1650 for(i=0; i<nPk; i++){
1651 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1652 zSep = " AND";
1653 }
1654 strPrintf(&sql, ")\n");
1655 strPrintf(&sql, " ORDER BY");
1656 zSep = " ";
1657 for(i=0; i<nPk; i++){
drh6e42ce42015-04-11 13:48:01 +00001658 strPrintf(&sql, "%s %d", zSep, aiPk[i]+2);
drh83e63dc2015-04-10 19:41:18 +00001659 zSep = ",";
1660 }
1661 strPrintf(&sql, ";\n");
1662
drh697e5db2015-04-11 12:07:40 +00001663 if( g.fDebug & DEBUG_DIFF_SQL ){
1664 printf("SQL for %s:\n%s\n", zId, sql.z);
1665 goto end_changeset_one_table;
1666 }
1667
1668 putc('T', out);
1669 putsVarint(out, (sqlite3_uint64)nCol);
1670 for(i=0; i<nCol; i++) putc(aiFlg[i]!=0, out);
1671 fwrite(zTab, 1, strlen(zTab), out);
1672 putc(0, out);
1673
1674 pStmt = db_prepare("%s", sql.z);
1675 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1676 int iType = sqlite3_column_int(pStmt,0);
drh697e5db2015-04-11 12:07:40 +00001677 putc(iType, out);
1678 putc(0, out);
drh6e42ce42015-04-11 13:48:01 +00001679 switch( sqlite3_column_int(pStmt,0) ){
1680 case SQLITE_UPDATE: {
1681 for(k=1, i=0; i<nCol; i++){
1682 if( aiFlg[i] ){
1683 putValue(out, sqlite3_column_value(pStmt,k));
1684 k++;
1685 }else if( sqlite3_column_int(pStmt,k) ){
1686 putValue(out, sqlite3_column_value(pStmt,k+1));
1687 k += 3;
1688 }else{
1689 putc(0, out);
1690 k += 3;
1691 }
1692 }
1693 for(k=1, i=0; i<nCol; i++){
1694 if( aiFlg[i] ){
1695 putc(0, out);
1696 k++;
1697 }else if( sqlite3_column_int(pStmt,k) ){
1698 putValue(out, sqlite3_column_value(pStmt,k+2));
1699 k += 3;
1700 }else{
1701 putc(0, out);
1702 k += 3;
1703 }
1704 }
1705 break;
1706 }
1707 case SQLITE_INSERT: {
1708 for(k=1, i=0; i<nCol; i++){
1709 if( aiFlg[i] ){
1710 putValue(out, sqlite3_column_value(pStmt,k));
1711 k++;
1712 }else{
1713 putValue(out, sqlite3_column_value(pStmt,k+2));
1714 k += 3;
1715 }
1716 }
1717 break;
1718 }
1719 case SQLITE_DELETE: {
1720 for(k=1, i=0; i<nCol; i++){
1721 if( aiFlg[i] ){
1722 putValue(out, sqlite3_column_value(pStmt,k));
1723 k++;
1724 }else{
1725 putValue(out, sqlite3_column_value(pStmt,k+1));
1726 k += 3;
1727 }
1728 }
1729 break;
drh697e5db2015-04-11 12:07:40 +00001730 }
1731 }
1732 }
1733 sqlite3_finalize(pStmt);
drh83e63dc2015-04-10 19:41:18 +00001734
1735end_changeset_one_table:
1736 while( nCol>0 ) sqlite3_free(azCol[--nCol]);
1737 sqlite3_free(azCol);
1738 sqlite3_free(aiPk);
1739 sqlite3_free(zId);
1740}
1741
1742/*
dan9c987a82016-06-21 10:34:41 +00001743** Extract the next SQL keyword or quoted string from buffer zIn and copy it
1744** (or a prefix of it if it will not fit) into buffer zBuf, size nBuf bytes.
1745** Return a pointer to the character within zIn immediately following
1746** the token or quoted string just extracted.
1747*/
1748const char *gobble_token(const char *zIn, char *zBuf, int nBuf){
1749 const char *p = zIn;
1750 char *pOut = zBuf;
1751 char *pEnd = &pOut[nBuf-1];
1752 char q = 0; /* quote character, if any */
1753
1754 if( p==0 ) return 0;
1755 while( *p==' ' ) p++;
1756 switch( *p ){
1757 case '"': q = '"'; break;
1758 case '\'': q = '\''; break;
1759 case '`': q = '`'; break;
1760 case '[': q = ']'; break;
1761 }
1762
1763 if( q ){
1764 p++;
1765 while( *p && pOut<pEnd ){
1766 if( *p==q ){
1767 p++;
1768 if( *p!=q ) break;
1769 }
1770 if( pOut<pEnd ) *pOut++ = *p;
1771 p++;
1772 }
1773 }else{
1774 while( *p && *p!=' ' && *p!='(' ){
1775 if( pOut<pEnd ) *pOut++ = *p;
1776 p++;
1777 }
1778 }
1779
1780 *pOut = '\0';
1781 return p;
1782}
1783
1784/*
1785** This function is the implementation of SQL scalar function "module_name":
1786**
1787** module_name(SQL)
1788**
1789** The only argument should be an SQL statement of the type that may appear
1790** in the sqlite_master table. If the statement is a "CREATE VIRTUAL TABLE"
1791** statement, then the value returned is the name of the module that it
1792** uses. Otherwise, if the statement is not a CVT, NULL is returned.
1793*/
1794static void module_name_func(
1795 sqlite3_context *pCtx,
1796 int nVal, sqlite3_value **apVal
1797){
1798 const char *zSql;
1799 char zToken[32];
1800
1801 assert( nVal==1 );
1802 zSql = (const char*)sqlite3_value_text(apVal[0]);
1803
1804 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1805 if( zSql==0 || sqlite3_stricmp(zToken, "create") ) return;
1806 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1807 if( zSql==0 || sqlite3_stricmp(zToken, "virtual") ) return;
1808 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1809 if( zSql==0 || sqlite3_stricmp(zToken, "table") ) return;
1810 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1811 if( zSql==0 ) return;
1812 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1813 if( zSql==0 || sqlite3_stricmp(zToken, "using") ) return;
1814 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1815
1816 sqlite3_result_text(pCtx, zToken, -1, SQLITE_TRANSIENT);
1817}
1818
1819/*
1820** Return the text of an SQL statement that itself returns the list of
1821** tables to process within the database.
1822*/
1823const char *all_tables_sql(){
1824 if( g.bHandleVtab ){
1825 int rc;
1826
1827 rc = sqlite3_exec(g.db,
dan12ca5ac2016-07-22 10:09:26 +00001828 "CREATE TEMP TABLE tblmap(module COLLATE nocase, postfix);"
dan9c987a82016-06-21 10:34:41 +00001829 "INSERT INTO temp.tblmap VALUES"
1830 "('fts3', '_content'), ('fts3', '_segments'), ('fts3', '_segdir'),"
1831
1832 "('fts4', '_content'), ('fts4', '_segments'), ('fts4', '_segdir'),"
1833 "('fts4', '_docsize'), ('fts4', '_stat'),"
1834
1835 "('fts5', '_data'), ('fts5', '_idx'), ('fts5', '_content'),"
1836 "('fts5', '_docsize'), ('fts5', '_config'),"
1837
1838 "('rtree', '_node'), ('rtree', '_rowid'), ('rtree', '_parent');"
1839 , 0, 0, 0
1840 );
1841 assert( rc==SQLITE_OK );
1842
1843 rc = sqlite3_create_function(
1844 g.db, "module_name", 1, SQLITE_UTF8, 0, module_name_func, 0, 0
1845 );
1846 assert( rc==SQLITE_OK );
1847
1848 return
1849 "SELECT name FROM main.sqlite_master\n"
1850 " WHERE type='table' AND (\n"
1851 " module_name(sql) IS NULL OR \n"
1852 " module_name(sql) IN (SELECT module FROM temp.tblmap)\n"
1853 " ) AND name NOT IN (\n"
1854 " SELECT a.name || b.postfix \n"
1855 "FROM main.sqlite_master AS a, temp.tblmap AS b \n"
1856 "WHERE module_name(a.sql) = b.module\n"
1857 " )\n"
1858 "UNION \n"
1859 "SELECT name FROM aux.sqlite_master\n"
1860 " WHERE type='table' AND (\n"
1861 " module_name(sql) IS NULL OR \n"
1862 " module_name(sql) IN (SELECT module FROM temp.tblmap)\n"
1863 " ) AND name NOT IN (\n"
1864 " SELECT a.name || b.postfix \n"
1865 "FROM aux.sqlite_master AS a, temp.tblmap AS b \n"
1866 "WHERE module_name(a.sql) = b.module\n"
1867 " )\n"
1868 " ORDER BY name";
1869 }else{
1870 return
1871 "SELECT name FROM main.sqlite_master\n"
1872 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1873 " UNION\n"
1874 "SELECT name FROM aux.sqlite_master\n"
1875 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1876 " ORDER BY name";
1877 }
1878}
1879
1880/*
drhd62c0f42015-04-09 13:34:29 +00001881** Print sketchy documentation for this utility program
1882*/
1883static void showHelp(void){
1884 printf("Usage: %s [options] DB1 DB2\n", g.zArgv0);
1885 printf(
1886"Output SQL text that would transform DB1 into DB2.\n"
1887"Options:\n"
drh83e63dc2015-04-10 19:41:18 +00001888" --changeset FILE Write a CHANGESET into FILE\n"
drh9a9219f2015-05-04 13:25:56 +00001889" -L|--lib LIBRARY Load an SQLite extension library\n"
drha37591c2015-04-09 18:14:03 +00001890" --primarykey Use schema-defined PRIMARY KEYs\n"
dan99461852015-07-30 20:26:16 +00001891" --rbu Output SQL to create/populate RBU table(s)\n"
drhd62c0f42015-04-09 13:34:29 +00001892" --schema Show only differences in the schema\n"
drh8a1cd762015-04-14 19:01:08 +00001893" --summary Show only a summary of the differences\n"
drhd62c0f42015-04-09 13:34:29 +00001894" --table TAB Show only differences in table TAB\n"
drh05d4ebf2015-11-13 13:15:42 +00001895" --transaction Show SQL output inside a transaction\n"
dan9c987a82016-06-21 10:34:41 +00001896" --vtab Handle fts3, fts4, fts5 and rtree tables\n"
drhd62c0f42015-04-09 13:34:29 +00001897 );
1898}
1899
1900int main(int argc, char **argv){
1901 const char *zDb1 = 0;
1902 const char *zDb2 = 0;
1903 int i;
1904 int rc;
1905 char *zErrMsg = 0;
1906 char *zSql;
1907 sqlite3_stmt *pStmt;
1908 char *zTab = 0;
drh8a1cd762015-04-14 19:01:08 +00001909 FILE *out = stdout;
1910 void (*xDiff)(const char*,FILE*) = diff_one_table;
drh9493caf2016-03-17 23:16:37 +00001911#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh9a9219f2015-05-04 13:25:56 +00001912 int nExt = 0;
drh33aa4db2015-05-04 15:04:47 +00001913 char **azExt = 0;
drh9493caf2016-03-17 23:16:37 +00001914#endif
drh05d4ebf2015-11-13 13:15:42 +00001915 int useTransaction = 0;
1916 int neverUseTransaction = 0;
drhd62c0f42015-04-09 13:34:29 +00001917
1918 g.zArgv0 = argv[0];
drhaa62e482015-05-12 00:46:40 +00001919 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
drhd62c0f42015-04-09 13:34:29 +00001920 for(i=1; i<argc; i++){
1921 const char *z = argv[i];
1922 if( z[0]=='-' ){
1923 z++;
1924 if( z[0]=='-' ) z++;
drh83e63dc2015-04-10 19:41:18 +00001925 if( strcmp(z,"changeset")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001926 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drh83e63dc2015-04-10 19:41:18 +00001927 out = fopen(argv[++i], "wb");
1928 if( out==0 ) cmdlineError("cannot open: %s", argv[i]);
drh8a1cd762015-04-14 19:01:08 +00001929 xDiff = changeset_one_table;
drh05d4ebf2015-11-13 13:15:42 +00001930 neverUseTransaction = 1;
drh83e63dc2015-04-10 19:41:18 +00001931 }else
drhd62c0f42015-04-09 13:34:29 +00001932 if( strcmp(z,"debug")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001933 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drhd62c0f42015-04-09 13:34:29 +00001934 g.fDebug = strtol(argv[++i], 0, 0);
1935 }else
1936 if( strcmp(z,"help")==0 ){
1937 showHelp();
1938 return 0;
1939 }else
drh6582ae52015-05-12 12:24:50 +00001940#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh9a9219f2015-05-04 13:25:56 +00001941 if( strcmp(z,"lib")==0 || strcmp(z,"L")==0 ){
1942 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
1943 azExt = realloc(azExt, sizeof(azExt[0])*(nExt+1));
1944 if( azExt==0 ) cmdlineError("out of memory");
1945 azExt[nExt++] = argv[++i];
1946 }else
drh6582ae52015-05-12 12:24:50 +00001947#endif
drha37591c2015-04-09 18:14:03 +00001948 if( strcmp(z,"primarykey")==0 ){
1949 g.bSchemaPK = 1;
1950 }else
dan99461852015-07-30 20:26:16 +00001951 if( strcmp(z,"rbu")==0 ){
1952 xDiff = rbudiff_one_table;
1953 }else
drhd62c0f42015-04-09 13:34:29 +00001954 if( strcmp(z,"schema")==0 ){
1955 g.bSchemaOnly = 1;
1956 }else
drh8a1cd762015-04-14 19:01:08 +00001957 if( strcmp(z,"summary")==0 ){
1958 xDiff = summarize_one_table;
1959 }else
drhd62c0f42015-04-09 13:34:29 +00001960 if( strcmp(z,"table")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001961 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drhd62c0f42015-04-09 13:34:29 +00001962 zTab = argv[++i];
1963 }else
drh05d4ebf2015-11-13 13:15:42 +00001964 if( strcmp(z,"transaction")==0 ){
1965 useTransaction = 1;
1966 }else
dan9c987a82016-06-21 10:34:41 +00001967 if( strcmp(z,"vtab")==0 ){
1968 g.bHandleVtab = 1;
1969 }else
drhd62c0f42015-04-09 13:34:29 +00001970 {
1971 cmdlineError("unknown option: %s", argv[i]);
1972 }
1973 }else if( zDb1==0 ){
1974 zDb1 = argv[i];
1975 }else if( zDb2==0 ){
1976 zDb2 = argv[i];
1977 }else{
1978 cmdlineError("unknown argument: %s", argv[i]);
1979 }
1980 }
1981 if( zDb2==0 ){
1982 cmdlineError("two database arguments required");
1983 }
1984 rc = sqlite3_open(zDb1, &g.db);
1985 if( rc ){
1986 cmdlineError("cannot open database file \"%s\"", zDb1);
1987 }
1988 rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_master", 0, 0, &zErrMsg);
1989 if( rc || zErrMsg ){
1990 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1);
1991 }
drh6582ae52015-05-12 12:24:50 +00001992#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh9a9219f2015-05-04 13:25:56 +00001993 sqlite3_enable_load_extension(g.db, 1);
1994 for(i=0; i<nExt; i++){
1995 rc = sqlite3_load_extension(g.db, azExt[i], 0, &zErrMsg);
1996 if( rc || zErrMsg ){
1997 cmdlineError("error loading %s: %s", azExt[i], zErrMsg);
1998 }
1999 }
2000 free(azExt);
drh9493caf2016-03-17 23:16:37 +00002001#endif
drhd62c0f42015-04-09 13:34:29 +00002002 zSql = sqlite3_mprintf("ATTACH %Q as aux;", zDb2);
2003 rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
2004 if( rc || zErrMsg ){
2005 cmdlineError("cannot attach database \"%s\"", zDb2);
2006 }
2007 rc = sqlite3_exec(g.db, "SELECT * FROM aux.sqlite_master", 0, 0, &zErrMsg);
2008 if( rc || zErrMsg ){
2009 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb2);
2010 }
2011
drh05d4ebf2015-11-13 13:15:42 +00002012 if( neverUseTransaction ) useTransaction = 0;
danfebfe022016-03-19 16:21:26 +00002013 if( useTransaction ) fprintf(out, "BEGIN TRANSACTION;\n");
2014 if( xDiff==rbudiff_one_table ){
2015 fprintf(out, "CREATE TABLE IF NOT EXISTS rbu_count"
2016 "(tbl TEXT PRIMARY KEY COLLATE NOCASE, cnt INTEGER) "
2017 "WITHOUT ROWID;\n"
2018 );
2019 }
drhd62c0f42015-04-09 13:34:29 +00002020 if( zTab ){
drh8a1cd762015-04-14 19:01:08 +00002021 xDiff(zTab, out);
drhd62c0f42015-04-09 13:34:29 +00002022 }else{
2023 /* Handle tables one by one */
drh52254492016-07-08 02:14:24 +00002024 pStmt = db_prepare("%s", all_tables_sql() );
drhd62c0f42015-04-09 13:34:29 +00002025 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +00002026 xDiff((const char*)sqlite3_column_text(pStmt,0), out);
drhd62c0f42015-04-09 13:34:29 +00002027 }
2028 sqlite3_finalize(pStmt);
2029 }
drh05d4ebf2015-11-13 13:15:42 +00002030 if( useTransaction ) printf("COMMIT;\n");
drhd62c0f42015-04-09 13:34:29 +00002031
2032 /* TBD: Handle trigger differences */
2033 /* TBD: Handle view differences */
2034 sqlite3_close(g.db);
2035 return 0;
2036}