blob: c7b59400dfd45a17968c69c61ff4474a9ceefa1e [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**
13** This is a utility problem that computes the differences in content
14** between two SQLite databases.
15*/
16#include <stdio.h>
17#include <stdlib.h>
18#include <stdarg.h>
19#include <ctype.h>
20#include <string.h>
21#include "sqlite3.h"
22
23/*
24** All global variables are gathered into the "g" singleton.
25*/
26struct GlobalVars {
27 const char *zArgv0; /* Name of program */
28 int bSchemaOnly; /* Only show schema differences */
drha37591c2015-04-09 18:14:03 +000029 int bSchemaPK; /* Use the schema-defined PK, not the true PK */
drhd62c0f42015-04-09 13:34:29 +000030 unsigned fDebug; /* Debug flags */
31 sqlite3 *db; /* The database connection */
32} g;
33
34/*
35** Allowed values for g.fDebug
36*/
37#define DEBUG_COLUMN_NAMES 0x000001
38#define DEBUG_DIFF_SQL 0x000002
39
40/*
41** Dynamic string object
42*/
43typedef struct Str Str;
44struct Str {
45 char *z; /* Text of the string */
46 int nAlloc; /* Bytes allocated in z[] */
47 int nUsed; /* Bytes actually used in z[] */
48};
49
50/*
51** Initialize a Str object
52*/
53static void strInit(Str *p){
54 p->z = 0;
55 p->nAlloc = 0;
56 p->nUsed = 0;
57}
58
59/*
60** Print an error resulting from faulting command-line arguments and
61** abort the program.
62*/
63static void cmdlineError(const char *zFormat, ...){
64 va_list ap;
65 fprintf(stderr, "%s: ", g.zArgv0);
66 va_start(ap, zFormat);
67 vfprintf(stderr, zFormat, ap);
68 va_end(ap);
69 fprintf(stderr, "\n\"%s --help\" for more help\n", g.zArgv0);
70 exit(1);
71}
72
73/*
74** Print an error message for an error that occurs at runtime, then
75** abort the program.
76*/
77static void runtimeError(const char *zFormat, ...){
78 va_list ap;
79 fprintf(stderr, "%s: ", g.zArgv0);
80 va_start(ap, zFormat);
81 vfprintf(stderr, zFormat, ap);
82 va_end(ap);
83 fprintf(stderr, "\n");
84 exit(1);
85}
86
87/*
88** Free all memory held by a Str object
89*/
90static void strFree(Str *p){
91 sqlite3_free(p->z);
92 strInit(p);
93}
94
95/*
96** Add formatted text to the end of a Str object
97*/
98static void strPrintf(Str *p, const char *zFormat, ...){
99 int nNew;
100 for(;;){
101 if( p->z ){
102 va_list ap;
103 va_start(ap, zFormat);
104 sqlite3_vsnprintf(p->nAlloc-p->nUsed, p->z+p->nUsed, zFormat, ap);
105 va_end(ap);
106 nNew = (int)strlen(p->z + p->nUsed);
107 }else{
108 nNew = p->nAlloc;
109 }
110 if( p->nUsed+nNew < p->nAlloc-1 ){
111 p->nUsed += nNew;
112 break;
113 }
114 p->nAlloc = p->nAlloc*2 + 1000;
115 p->z = sqlite3_realloc(p->z, p->nAlloc);
116 if( p->z==0 ) runtimeError("out of memory");
117 }
118}
119
120
121
122/* Safely quote an SQL identifier. Use the minimum amount of transformation
123** necessary to allow the string to be used with %s.
124**
125** Space to hold the returned string is obtained from sqlite3_malloc(). The
126** caller is responsible for ensuring this space is freed when no longer
127** needed.
128*/
129static char *safeId(const char *zId){
130 /* All SQLite keywords, in alphabetical order */
131 static const char *azKeywords[] = {
132 "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
133 "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
134 "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
135 "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
136 "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
137 "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
138 "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
139 "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
140 "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
141 "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
142 "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
143 "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
144 "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
145 "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
146 "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
147 "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
148 "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
149 "WITH", "WITHOUT",
150 };
151 int lwr, upr, mid, c, i, x;
152 for(i=x=0; (c = zId[i])!=0; i++){
153 if( !isalpha(c) && c!='_' ){
154 if( i>0 && isdigit(c) ){
155 x++;
156 }else{
157 return sqlite3_mprintf("\"%w\"", zId);
158 }
159 }
160 }
161 if( x ) return sqlite3_mprintf("%s", zId);
162 lwr = 0;
163 upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1;
164 while( lwr<=upr ){
165 mid = (lwr+upr)/2;
166 c = sqlite3_stricmp(azKeywords[mid], zId);
167 if( c==0 ) return sqlite3_mprintf("\"%w\"", zId);
168 if( c<0 ){
169 lwr = mid+1;
170 }else{
171 upr = mid-1;
172 }
173 }
174 return sqlite3_mprintf("%s", zId);
175}
176
177/*
178** Prepare a new SQL statement. Print an error and abort if anything
179** goes wrong.
180*/
181static sqlite3_stmt *db_vprepare(const char *zFormat, va_list ap){
182 char *zSql;
183 int rc;
184 sqlite3_stmt *pStmt;
185
186 zSql = sqlite3_vmprintf(zFormat, ap);
187 if( zSql==0 ) runtimeError("out of memory");
188 rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt, 0);
189 if( rc ){
190 runtimeError("SQL statement error: %s\n\"%s\"", sqlite3_errmsg(g.db),
191 zSql);
192 }
193 sqlite3_free(zSql);
194 return pStmt;
195}
196static sqlite3_stmt *db_prepare(const char *zFormat, ...){
197 va_list ap;
198 sqlite3_stmt *pStmt;
199 va_start(ap, zFormat);
200 pStmt = db_vprepare(zFormat, ap);
201 va_end(ap);
202 return pStmt;
203}
204
205/*
206** Free a list of strings
207*/
208static void namelistFree(char **az){
209 if( az ){
210 int i;
211 for(i=0; az[i]; i++) sqlite3_free(az[i]);
212 sqlite3_free(az);
213 }
214}
215
216/*
217** Return a list of column names for the table zDb.zTab. Space to
drh39b355c2015-04-09 13:40:18 +0000218** hold the list is obtained from sqlite3_malloc() and should released
219** using namelistFree() when no longer needed.
drhd62c0f42015-04-09 13:34:29 +0000220**
drha37591c2015-04-09 18:14:03 +0000221** Primary key columns are listed first, followed by data columns.
222** The number of columns in the primary key is returned in *pnPkey.
drhd62c0f42015-04-09 13:34:29 +0000223**
drha37591c2015-04-09 18:14:03 +0000224** Normally, the "primary key" in the previous sentence is the true
225** primary key - the rowid or INTEGER PRIMARY KEY for ordinary tables
226** or the declared PRIMARY KEY for WITHOUT ROWID tables. However, if
227** the g.bSchemaPK flag is set, then the schema-defined PRIMARY KEY is
228** used in all cases. In that case, entries that have NULL values in
229** any of their primary key fields will be excluded from the analysis.
230**
231** If the primary key for a table is the rowid but rowid is inaccessible,
drhd62c0f42015-04-09 13:34:29 +0000232** then this routine returns a NULL pointer.
233**
234** Examples:
235** CREATE TABLE t1(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(c));
236** *pnPKey = 1;
drha37591c2015-04-09 18:14:03 +0000237** az = { "rowid", "a", "b", "c", 0 } // Normal case
238** az = { "c", "a", "b", 0 } // g.bSchemaPK==1
drhd62c0f42015-04-09 13:34:29 +0000239**
240** CREATE TABLE t2(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(b));
241** *pnPKey = 1;
242** az = { "b", "a", "c", 0 }
243**
244** CREATE TABLE t3(x,y,z,PRIMARY KEY(y,z));
drha37591c2015-04-09 18:14:03 +0000245** *pnPKey = 1 // Normal case
246** az = { "rowid", "x", "y", "z", 0 } // Normal case
247** *pnPKey = 2 // g.bSchemaPK==1
248** az = { "y", "x", "z", 0 } // g.bSchemaPK==1
drhd62c0f42015-04-09 13:34:29 +0000249**
250** CREATE TABLE t4(x,y,z,PRIMARY KEY(y,z)) WITHOUT ROWID;
251** *pnPKey = 2
252** az = { "y", "z", "x", 0 }
253**
254** CREATE TABLE t5(rowid,_rowid_,oid);
255** az = 0 // The rowid is not accessible
256*/
257static char **columnNames(const char *zDb, const char *zTab, int *pnPKey){
drha37591c2015-04-09 18:14:03 +0000258 char **az = 0; /* List of column names to be returned */
259 int naz = 0; /* Number of entries in az[] */
260 sqlite3_stmt *pStmt; /* SQL statement being run */
drhd62c0f42015-04-09 13:34:29 +0000261 char *zPkIdxName = 0; /* Name of the PRIMARY KEY index */
drha37591c2015-04-09 18:14:03 +0000262 int truePk = 0; /* PRAGMA table_info indentifies the PK to use */
drhd62c0f42015-04-09 13:34:29 +0000263 int nPK = 0; /* Number of PRIMARY KEY columns */
drha37591c2015-04-09 18:14:03 +0000264 int i, j; /* Loop counters */
drhd62c0f42015-04-09 13:34:29 +0000265
drha37591c2015-04-09 18:14:03 +0000266 if( g.bSchemaPK==0 ){
267 /* Normal case: Figure out what the true primary key is for the table.
268 ** * For WITHOUT ROWID tables, the true primary key is the same as
269 ** the schema PRIMARY KEY, which is guaranteed to be present.
270 ** * For rowid tables with an INTEGER PRIMARY KEY, the true primary
271 ** key is the INTEGER PRIMARY KEY.
272 ** * For all other rowid tables, the rowid is the true primary key.
273 */
274 pStmt = db_prepare("PRAGMA %s.index_list=%Q", zDb, zTab);
drhd62c0f42015-04-09 13:34:29 +0000275 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drha37591c2015-04-09 18:14:03 +0000276 if( sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,3),"pk")==0 ){
277 zPkIdxName = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
278 break;
279 }
drhd62c0f42015-04-09 13:34:29 +0000280 }
281 sqlite3_finalize(pStmt);
drha37591c2015-04-09 18:14:03 +0000282 if( zPkIdxName ){
283 int nKey = 0;
284 int nCol = 0;
285 truePk = 0;
286 pStmt = db_prepare("PRAGMA %s.index_xinfo=%Q", zDb, zPkIdxName);
287 while( SQLITE_ROW==sqlite3_step(pStmt) ){
288 nCol++;
289 if( sqlite3_column_int(pStmt,5) ){ nKey++; continue; }
290 if( sqlite3_column_int(pStmt,1)>=0 ) truePk = 1;
291 }
292 if( nCol==nKey ) truePk = 1;
293 if( truePk ){
294 nPK = nKey;
295 }else{
296 nPK = 1;
297 }
298 sqlite3_finalize(pStmt);
299 sqlite3_free(zPkIdxName);
300 }else{
301 truePk = 1;
302 nPK = 1;
303 }
304 pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
drhd62c0f42015-04-09 13:34:29 +0000305 }else{
drha37591c2015-04-09 18:14:03 +0000306 /* The g.bSchemaPK==1 case: Use whatever primary key is declared
307 ** in the schema. The "rowid" will still be used as the primary key
308 ** if the table definition does not contain a PRIMARY KEY.
309 */
310 nPK = 0;
311 pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
312 while( SQLITE_ROW==sqlite3_step(pStmt) ){
313 if( sqlite3_column_int(pStmt,5)>0 ) nPK++;
314 }
315 sqlite3_reset(pStmt);
316 if( nPK==0 ) nPK = 1;
drhd62c0f42015-04-09 13:34:29 +0000317 truePk = 1;
drhd62c0f42015-04-09 13:34:29 +0000318 }
319 *pnPKey = nPK;
320 naz = nPK;
321 az = sqlite3_malloc( sizeof(char*)*(nPK+1) );
322 if( az==0 ) runtimeError("out of memory");
323 memset(az, 0, sizeof(char*)*(nPK+1));
drhd62c0f42015-04-09 13:34:29 +0000324 while( SQLITE_ROW==sqlite3_step(pStmt) ){
325 int iPKey;
326 if( truePk && (iPKey = sqlite3_column_int(pStmt,5))>0 ){
327 az[iPKey-1] = safeId((char*)sqlite3_column_text(pStmt,1));
328 }else{
329 az = sqlite3_realloc(az, sizeof(char*)*(naz+2) );
330 if( az==0 ) runtimeError("out of memory");
331 az[naz++] = safeId((char*)sqlite3_column_text(pStmt,1));
332 }
333 }
334 sqlite3_finalize(pStmt);
335 if( az ) az[naz] = 0;
336 if( az[0]==0 ){
337 const char *azRowid[] = { "rowid", "_rowid_", "oid" };
338 for(i=0; i<sizeof(azRowid)/sizeof(azRowid[0]); i++){
339 for(j=1; j<naz; j++){
340 if( sqlite3_stricmp(az[j], azRowid[i])==0 ) break;
341 }
342 if( j>=naz ){
343 az[0] = sqlite3_mprintf("%s", azRowid[i]);
344 break;
345 }
346 }
347 if( az[0]==0 ){
348 for(i=1; i<naz; i++) sqlite3_free(az[i]);
349 sqlite3_free(az);
350 az = 0;
351 }
352 }
353 return az;
354}
355
356/*
357** Print the sqlite3_value X as an SQL literal.
358*/
drh8a1cd762015-04-14 19:01:08 +0000359static void printQuoted(FILE *out, sqlite3_value *X){
drhd62c0f42015-04-09 13:34:29 +0000360 switch( sqlite3_value_type(X) ){
361 case SQLITE_FLOAT: {
362 double r1;
363 char zBuf[50];
364 r1 = sqlite3_value_double(X);
365 sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
drh8a1cd762015-04-14 19:01:08 +0000366 fprintf(out, "%s", zBuf);
drhd62c0f42015-04-09 13:34:29 +0000367 break;
368 }
369 case SQLITE_INTEGER: {
drh8a1cd762015-04-14 19:01:08 +0000370 fprintf(out, "%lld", sqlite3_value_int64(X));
drhd62c0f42015-04-09 13:34:29 +0000371 break;
372 }
373 case SQLITE_BLOB: {
374 const unsigned char *zBlob = sqlite3_value_blob(X);
375 int nBlob = sqlite3_value_bytes(X);
376 if( zBlob ){
377 int i;
drh8a1cd762015-04-14 19:01:08 +0000378 fprintf(out, "x'");
drhd62c0f42015-04-09 13:34:29 +0000379 for(i=0; i<nBlob; i++){
drh8a1cd762015-04-14 19:01:08 +0000380 fprintf(out, "%02x", zBlob[i]);
drhd62c0f42015-04-09 13:34:29 +0000381 }
drh8a1cd762015-04-14 19:01:08 +0000382 fprintf(out, "'");
drhd62c0f42015-04-09 13:34:29 +0000383 }else{
drh8a1cd762015-04-14 19:01:08 +0000384 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000385 }
386 break;
387 }
388 case SQLITE_TEXT: {
389 const unsigned char *zArg = sqlite3_value_text(X);
390 int i, j;
391
392 if( zArg==0 ){
drh8a1cd762015-04-14 19:01:08 +0000393 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000394 }else{
drh8a1cd762015-04-14 19:01:08 +0000395 fprintf(out, "'");
drhd62c0f42015-04-09 13:34:29 +0000396 for(i=j=0; zArg[i]; i++){
397 if( zArg[i]=='\'' ){
drh8a1cd762015-04-14 19:01:08 +0000398 fprintf(out, "%.*s'", i-j+1, &zArg[j]);
drhd62c0f42015-04-09 13:34:29 +0000399 j = i+1;
400 }
401 }
drh8a1cd762015-04-14 19:01:08 +0000402 fprintf(out, "%s'", &zArg[j]);
drhd62c0f42015-04-09 13:34:29 +0000403 }
404 break;
405 }
406 case SQLITE_NULL: {
drh8a1cd762015-04-14 19:01:08 +0000407 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000408 break;
409 }
410 }
411}
412
413/*
414** Output SQL that will recreate the aux.zTab table.
415*/
drh8a1cd762015-04-14 19:01:08 +0000416static void dump_table(const char *zTab, FILE *out){
drhd62c0f42015-04-09 13:34:29 +0000417 char *zId = safeId(zTab); /* Name of the table */
418 char **az = 0; /* List of columns */
419 int nPk; /* Number of true primary key columns */
420 int nCol; /* Number of data columns */
421 int i; /* Loop counter */
422 sqlite3_stmt *pStmt; /* SQL statement */
423 const char *zSep; /* Separator string */
424 Str ins; /* Beginning of the INSERT statement */
425
426 pStmt = db_prepare("SELECT sql FROM aux.sqlite_master WHERE name=%Q", zTab);
427 if( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000428 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000429 }
430 sqlite3_finalize(pStmt);
431 if( !g.bSchemaOnly ){
432 az = columnNames("aux", zTab, &nPk);
433 strInit(&ins);
434 if( az==0 ){
435 pStmt = db_prepare("SELECT * FROM aux.%s", zId);
436 strPrintf(&ins,"INSERT INTO %s VALUES", zId);
437 }else{
438 Str sql;
439 strInit(&sql);
440 zSep = "SELECT";
441 for(i=0; az[i]; i++){
442 strPrintf(&sql, "%s %s", zSep, az[i]);
443 zSep = ",";
444 }
445 strPrintf(&sql," FROM aux.%s", zId);
446 zSep = " ORDER BY";
447 for(i=1; i<=nPk; i++){
448 strPrintf(&sql, "%s %d", zSep, i);
449 zSep = ",";
450 }
451 pStmt = db_prepare("%s", sql.z);
452 strFree(&sql);
453 strPrintf(&ins, "INSERT INTO %s", zId);
454 zSep = "(";
455 for(i=0; az[i]; i++){
456 strPrintf(&ins, "%s%s", zSep, az[i]);
457 zSep = ",";
458 }
459 strPrintf(&ins,") VALUES");
460 namelistFree(az);
461 }
462 nCol = sqlite3_column_count(pStmt);
463 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000464 fprintf(out, "%s",ins.z);
drhd62c0f42015-04-09 13:34:29 +0000465 zSep = "(";
466 for(i=0; i<nCol; i++){
drh8a1cd762015-04-14 19:01:08 +0000467 fprintf(out, "%s",zSep);
468 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000469 zSep = ",";
470 }
drh8a1cd762015-04-14 19:01:08 +0000471 fprintf(out, ");\n");
drhd62c0f42015-04-09 13:34:29 +0000472 }
473 sqlite3_finalize(pStmt);
474 strFree(&ins);
475 } /* endif !g.bSchemaOnly */
476 pStmt = db_prepare("SELECT sql FROM aux.sqlite_master"
477 " WHERE type='index' AND tbl_name=%Q AND sql IS NOT NULL",
478 zTab);
479 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000480 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000481 }
482 sqlite3_finalize(pStmt);
483}
484
485
486/*
487** Compute all differences for a single table.
488*/
drh8a1cd762015-04-14 19:01:08 +0000489static void diff_one_table(const char *zTab, FILE *out){
drhd62c0f42015-04-09 13:34:29 +0000490 char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
491 char **az = 0; /* Columns in main */
492 char **az2 = 0; /* Columns in aux */
493 int nPk; /* Primary key columns in main */
494 int nPk2; /* Primary key columns in aux */
495 int n; /* Number of columns in main */
496 int n2; /* Number of columns in aux */
497 int nQ; /* Number of output columns in the diff query */
498 int i; /* Loop counter */
499 const char *zSep; /* Separator string */
500 Str sql; /* Comparison query */
501 sqlite3_stmt *pStmt; /* Query statement to do the diff */
502
503 strInit(&sql);
504 if( g.fDebug==DEBUG_COLUMN_NAMES ){
505 /* Simply run columnNames() on all tables of the origin
506 ** database and show the results. This is used for testing
507 ** and debugging of the columnNames() function.
508 */
509 az = columnNames("aux",zTab, &nPk);
510 if( az==0 ){
511 printf("Rowid not accessible for %s\n", zId);
512 }else{
513 printf("%s:", zId);
514 for(i=0; az[i]; i++){
515 printf(" %s", az[i]);
516 if( i+1==nPk ) printf(" *");
517 }
518 printf("\n");
519 }
520 goto end_diff_one_table;
521 }
522
523
524 if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
525 if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
526 /* Table missing from second database. */
drh8a1cd762015-04-14 19:01:08 +0000527 fprintf(out, "DROP TABLE %s;\n", zId);
drhd62c0f42015-04-09 13:34:29 +0000528 }
529 goto end_diff_one_table;
530 }
531
532 if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
533 /* Table missing from source */
drh8a1cd762015-04-14 19:01:08 +0000534 dump_table(zTab, out);
drhd62c0f42015-04-09 13:34:29 +0000535 goto end_diff_one_table;
536 }
537
538 az = columnNames("main", zTab, &nPk);
539 az2 = columnNames("aux", zTab, &nPk2);
540 if( az && az2 ){
541 for(n=0; az[n]; n++){
542 if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
543 }
544 }
545 if( az==0
546 || az2==0
547 || nPk!=nPk2
548 || az[n]
549 ){
550 /* Schema mismatch */
drh8a1cd762015-04-14 19:01:08 +0000551 fprintf(out, "DROP TABLE %s;\n", zId);
552 dump_table(zTab, out);
drhd62c0f42015-04-09 13:34:29 +0000553 goto end_diff_one_table;
554 }
555
556 /* Build the comparison query */
557 for(n2=n; az[n2]; n2++){}
558 nQ = nPk2+1+2*(n2-nPk2);
559 if( n2>nPk2 ){
560 zSep = "SELECT ";
561 for(i=0; i<nPk; i++){
562 strPrintf(&sql, "%sB.%s", zSep, az[i]);
563 zSep = ", ";
564 }
565 strPrintf(&sql, ", 1%s -- changed row\n", nPk==n ? "" : ",");
566 while( az[i] ){
567 strPrintf(&sql, " A.%s IS NOT B.%s, B.%s%s\n",
568 az[i], az[i], az[i], i==n2-1 ? "" : ",");
569 i++;
570 }
571 strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId);
572 zSep = " WHERE";
573 for(i=0; i<nPk; i++){
574 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
575 zSep = " AND";
576 }
577 zSep = "\n AND (";
578 while( az[i] ){
579 strPrintf(&sql, "%sA.%s IS NOT B.%s%s\n",
580 zSep, az[i], az[i], i==n2-1 ? ")" : "");
581 zSep = " OR ";
582 i++;
583 }
584 strPrintf(&sql, " UNION ALL\n");
585 }
586 zSep = "SELECT ";
587 for(i=0; i<nPk; i++){
588 strPrintf(&sql, "%sA.%s", zSep, az[i]);
589 zSep = ", ";
590 }
591 strPrintf(&sql, ", 2%s -- deleted row\n", nPk==n ? "" : ",");
592 while( az[i] ){
593 strPrintf(&sql, " NULL, NULL%s\n", i==n2-1 ? "" : ",");
594 i++;
595 }
596 strPrintf(&sql, " FROM main.%s A\n", zId);
597 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B\n", zId);
598 zSep = " WHERE";
599 for(i=0; i<nPk; i++){
600 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
601 zSep = " AND";
602 }
603 strPrintf(&sql, ")\n");
604 zSep = " UNION ALL\nSELECT ";
605 for(i=0; i<nPk; i++){
606 strPrintf(&sql, "%sB.%s", zSep, az[i]);
607 zSep = ", ";
608 }
609 strPrintf(&sql, ", 3%s -- inserted row\n", nPk==n ? "" : ",");
610 while( az2[i] ){
611 strPrintf(&sql, " 1, B.%s%s\n", az[i], i==n2-1 ? "" : ",");
612 i++;
613 }
614 strPrintf(&sql, " FROM aux.%s B\n", zId);
615 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A\n", zId);
616 zSep = " WHERE";
617 for(i=0; i<nPk; i++){
618 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
619 zSep = " AND";
620 }
621 strPrintf(&sql, ")\n ORDER BY");
622 zSep = " ";
623 for(i=1; i<=nPk; i++){
624 strPrintf(&sql, "%s%d", zSep, i);
625 zSep = ", ";
626 }
627 strPrintf(&sql, ";\n");
628
629 if( g.fDebug & DEBUG_DIFF_SQL ){
630 printf("SQL for %s:\n%s\n", zId, sql.z);
631 goto end_diff_one_table;
632 }
633
634 /* Drop indexes that are missing in the destination */
635 pStmt = db_prepare(
636 "SELECT name FROM main.sqlite_master"
637 " WHERE type='index' AND tbl_name=%Q"
638 " AND sql IS NOT NULL"
639 " AND sql NOT IN (SELECT sql FROM aux.sqlite_master"
640 " WHERE type='index' AND tbl_name=%Q"
641 " AND sql IS NOT NULL)",
642 zTab, zTab);
643 while( SQLITE_ROW==sqlite3_step(pStmt) ){
644 char *z = safeId((const char*)sqlite3_column_text(pStmt,0));
drh8a1cd762015-04-14 19:01:08 +0000645 fprintf(out, "DROP INDEX %s;\n", z);
drhd62c0f42015-04-09 13:34:29 +0000646 sqlite3_free(z);
647 }
648 sqlite3_finalize(pStmt);
649
650 /* Run the query and output differences */
651 if( !g.bSchemaOnly ){
652 pStmt = db_prepare(sql.z);
653 while( SQLITE_ROW==sqlite3_step(pStmt) ){
654 int iType = sqlite3_column_int(pStmt, nPk);
655 if( iType==1 || iType==2 ){
656 if( iType==1 ){ /* Change the content of a row */
drh8a1cd762015-04-14 19:01:08 +0000657 fprintf(out, "UPDATE %s", zId);
drhd62c0f42015-04-09 13:34:29 +0000658 zSep = " SET";
659 for(i=nPk+1; i<nQ; i+=2){
660 if( sqlite3_column_int(pStmt,i)==0 ) continue;
drh8a1cd762015-04-14 19:01:08 +0000661 fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]);
drhd62c0f42015-04-09 13:34:29 +0000662 zSep = ",";
drh8a1cd762015-04-14 19:01:08 +0000663 printQuoted(out, sqlite3_column_value(pStmt,i+1));
drhd62c0f42015-04-09 13:34:29 +0000664 }
665 }else{ /* Delete a row */
drh8a1cd762015-04-14 19:01:08 +0000666 fprintf(out, "DELETE FROM %s", zId);
drhd62c0f42015-04-09 13:34:29 +0000667 }
668 zSep = " WHERE";
669 for(i=0; i<nPk; i++){
drh8a1cd762015-04-14 19:01:08 +0000670 fprintf(out, "%s %s=", zSep, az2[i]);
671 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000672 zSep = ",";
673 }
drh8a1cd762015-04-14 19:01:08 +0000674 fprintf(out, ";\n");
drhd62c0f42015-04-09 13:34:29 +0000675 }else{ /* Insert a row */
drh8a1cd762015-04-14 19:01:08 +0000676 fprintf(out, "INSERT INTO %s(%s", zId, az2[0]);
677 for(i=1; az2[i]; i++) fprintf(out, ",%s", az2[i]);
678 fprintf(out, ") VALUES");
drhd62c0f42015-04-09 13:34:29 +0000679 zSep = "(";
680 for(i=0; i<nPk2; i++){
drh8a1cd762015-04-14 19:01:08 +0000681 fprintf(out, "%s", zSep);
drhd62c0f42015-04-09 13:34:29 +0000682 zSep = ",";
drh8a1cd762015-04-14 19:01:08 +0000683 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000684 }
685 for(i=nPk2+2; i<nQ; i+=2){
drh8a1cd762015-04-14 19:01:08 +0000686 fprintf(out, ",");
687 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000688 }
drh8a1cd762015-04-14 19:01:08 +0000689 fprintf(out, ");\n");
drhd62c0f42015-04-09 13:34:29 +0000690 }
691 }
692 sqlite3_finalize(pStmt);
693 } /* endif !g.bSchemaOnly */
694
695 /* Create indexes that are missing in the source */
696 pStmt = db_prepare(
697 "SELECT sql FROM aux.sqlite_master"
698 " WHERE type='index' AND tbl_name=%Q"
699 " AND sql IS NOT NULL"
700 " AND sql NOT IN (SELECT sql FROM main.sqlite_master"
701 " WHERE type='index' AND tbl_name=%Q"
702 " AND sql IS NOT NULL)",
703 zTab, zTab);
704 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000705 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000706 }
707 sqlite3_finalize(pStmt);
708
709end_diff_one_table:
710 strFree(&sql);
711 sqlite3_free(zId);
712 namelistFree(az);
713 namelistFree(az2);
714 return;
715}
716
717/*
drh8a1cd762015-04-14 19:01:08 +0000718** Display a summary of differences between two versions of the same
719** table table.
720**
721** * Number of rows changed
722** * Number of rows added
723** * Number of rows deleted
724** * Number of identical rows
725*/
726static void summarize_one_table(const char *zTab, FILE *out){
727 char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
728 char **az = 0; /* Columns in main */
729 char **az2 = 0; /* Columns in aux */
730 int nPk; /* Primary key columns in main */
731 int nPk2; /* Primary key columns in aux */
732 int n; /* Number of columns in main */
733 int n2; /* Number of columns in aux */
734 int i; /* Loop counter */
735 const char *zSep; /* Separator string */
736 Str sql; /* Comparison query */
737 sqlite3_stmt *pStmt; /* Query statement to do the diff */
738 sqlite3_int64 nUpdate; /* Number of updated rows */
739 sqlite3_int64 nUnchanged; /* Number of unmodified rows */
740 sqlite3_int64 nDelete; /* Number of deleted rows */
741 sqlite3_int64 nInsert; /* Number of inserted rows */
742
743 strInit(&sql);
744 if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
745 if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
746 /* Table missing from second database. */
747 fprintf(out, "%s: missing from second database\n", zTab);
748 }
749 goto end_summarize_one_table;
750 }
751
752 if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
753 /* Table missing from source */
754 fprintf(out, "%s: missing from first database\n", zTab);
755 goto end_summarize_one_table;
756 }
757
758 az = columnNames("main", zTab, &nPk);
759 az2 = columnNames("aux", zTab, &nPk2);
760 if( az && az2 ){
761 for(n=0; az[n]; n++){
762 if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
763 }
764 }
765 if( az==0
766 || az2==0
767 || nPk!=nPk2
768 || az[n]
769 ){
770 /* Schema mismatch */
771 fprintf(out, "%s: incompatible schema\n", zTab);
772 goto end_summarize_one_table;
773 }
774
775 /* Build the comparison query */
776 for(n2=n; az[n2]; n2++){}
777 strPrintf(&sql, "SELECT 1, count(*)");
778 if( n2==nPk2 ){
779 strPrintf(&sql, ", 0\n");
780 }else{
781 zSep = ", sum(";
782 for(i=nPk; az[i]; i++){
783 strPrintf(&sql, "%sA.%s IS NOT B.%s", zSep, az[i], az[i]);
784 zSep = " OR ";
785 }
786 strPrintf(&sql, ")\n");
787 }
788 strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId);
789 zSep = " WHERE";
790 for(i=0; i<nPk; i++){
791 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
792 zSep = " AND";
793 }
794 strPrintf(&sql, " UNION ALL\n");
795 strPrintf(&sql, "SELECT 2, count(*), 0\n");
796 strPrintf(&sql, " FROM main.%s A\n", zId);
797 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B ", zId);
798 zSep = "WHERE";
799 for(i=0; i<nPk; i++){
800 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
801 zSep = " AND";
802 }
803 strPrintf(&sql, ")\n");
804 strPrintf(&sql, " UNION ALL\n");
805 strPrintf(&sql, "SELECT 3, count(*), 0\n");
806 strPrintf(&sql, " FROM aux.%s B\n", zId);
807 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A ", zId);
808 zSep = "WHERE";
809 for(i=0; i<nPk; i++){
810 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
811 zSep = " AND";
812 }
813 strPrintf(&sql, ")\n ORDER BY 1;\n");
814
815 if( (g.fDebug & DEBUG_DIFF_SQL)!=0 ){
816 printf("SQL for %s:\n%s\n", zId, sql.z);
817 goto end_summarize_one_table;
818 }
819
820 /* Run the query and output difference summary */
821 pStmt = db_prepare(sql.z);
822 nUpdate = 0;
823 nInsert = 0;
824 nDelete = 0;
825 nUnchanged = 0;
826 while( SQLITE_ROW==sqlite3_step(pStmt) ){
827 switch( sqlite3_column_int(pStmt,0) ){
828 case 1:
829 nUpdate = sqlite3_column_int64(pStmt,2);
830 nUnchanged = sqlite3_column_int64(pStmt,1) - nUpdate;
831 break;
832 case 2:
833 nDelete = sqlite3_column_int64(pStmt,1);
834 break;
835 case 3:
836 nInsert = sqlite3_column_int64(pStmt,1);
837 break;
838 }
839 }
840 sqlite3_finalize(pStmt);
841 fprintf(out, "%s: %lld changes, %lld inserts, %lld deletes, %lld unchanged\n",
842 zTab, nUpdate, nInsert, nDelete, nUnchanged);
843
844end_summarize_one_table:
845 strFree(&sql);
846 sqlite3_free(zId);
847 namelistFree(az);
848 namelistFree(az2);
849 return;
850}
851
852/*
drh697e5db2015-04-11 12:07:40 +0000853** Write a 64-bit signed integer as a varint onto out
854*/
855static void putsVarint(FILE *out, sqlite3_uint64 v){
856 int i, n;
drh6e42ce42015-04-11 13:48:01 +0000857 unsigned char p[12];
drh697e5db2015-04-11 12:07:40 +0000858 if( v & (((sqlite3_uint64)0xff000000)<<32) ){
859 p[8] = (unsigned char)v;
860 v >>= 8;
861 for(i=7; i>=0; i--){
862 p[i] = (unsigned char)((v & 0x7f) | 0x80);
863 v >>= 7;
864 }
865 fwrite(p, 8, 1, out);
866 }else{
867 n = 9;
868 do{
869 p[n--] = (unsigned char)((v & 0x7f) | 0x80);
870 v >>= 7;
871 }while( v!=0 );
drh6e42ce42015-04-11 13:48:01 +0000872 p[9] &= 0x7f;
873 fwrite(p+n+1, 9-n, 1, out);
874 }
875}
876
877/*
878** Write an SQLite value onto out.
879*/
880static void putValue(FILE *out, sqlite3_value *pVal){
881 int iDType = sqlite3_value_type(pVal);
882 sqlite3_int64 iX;
883 double rX;
884 sqlite3_uint64 uX;
885 int j;
886
887 putc(iDType, out);
888 switch( iDType ){
889 case SQLITE_INTEGER:
890 iX = sqlite3_value_int64(pVal);
891 memcpy(&uX, &iX, 8);
892 for(j=56; j>=0; j-=8) putc((uX>>j)&0xff, out);
893 break;
894 case SQLITE_FLOAT:
895 rX = sqlite3_value_int64(pVal);
896 memcpy(&uX, &rX, 8);
897 for(j=56; j>=0; j-=8) putc((uX>>j)&0xff, out);
898 break;
899 case SQLITE_TEXT:
900 iX = sqlite3_value_bytes(pVal);
901 putsVarint(out, (sqlite3_uint64)iX);
902 fwrite(sqlite3_value_text(pVal),1,iX,out);
903 break;
904 case SQLITE_BLOB:
905 iX = sqlite3_value_bytes(pVal);
906 putsVarint(out, (sqlite3_uint64)iX);
907 fwrite(sqlite3_value_blob(pVal),1,iX,out);
908 break;
909 case SQLITE_NULL:
910 break;
drh697e5db2015-04-11 12:07:40 +0000911 }
912}
913
914/*
drh83e63dc2015-04-10 19:41:18 +0000915** Generate a CHANGESET for all differences from main.zTab to aux.zTab.
916*/
917static void changeset_one_table(const char *zTab, FILE *out){
918 sqlite3_stmt *pStmt; /* SQL statment */
919 char *zId = safeId(zTab); /* Escaped name of the table */
920 char **azCol = 0; /* List of escaped column names */
921 int nCol = 0; /* Number of columns */
922 int *aiFlg = 0; /* 0 if column is not part of PK */
923 int *aiPk = 0; /* Column numbers for each PK column */
924 int nPk = 0; /* Number of PRIMARY KEY columns */
925 Str sql; /* SQL for the diff query */
drh6e42ce42015-04-11 13:48:01 +0000926 int i, k; /* Loop counters */
drh83e63dc2015-04-10 19:41:18 +0000927 const char *zSep; /* List separator */
928
929 pStmt = db_prepare(
930 "SELECT A.sql=B.sql FROM main.sqlite_master A, aux.sqlite_master B"
931 " WHERE A.name=%Q AND B.name=%Q", zTab, zTab
932 );
933 if( SQLITE_ROW==sqlite3_step(pStmt) ){
934 if( sqlite3_column_int(pStmt,0)==0 ){
935 runtimeError("schema changes for table %s", safeId(zTab));
936 }
937 }else{
938 runtimeError("table %s missing from one or both databases", safeId(zTab));
939 }
940 sqlite3_finalize(pStmt);
941 pStmt = db_prepare("PRAGMA main.table_info=%Q", zTab);
942 while( SQLITE_ROW==sqlite3_step(pStmt) ){
943 nCol++;
944 azCol = sqlite3_realloc(azCol, sizeof(char*)*nCol);
945 if( azCol==0 ) runtimeError("out of memory");
946 aiFlg = sqlite3_realloc(aiFlg, sizeof(int)*nCol);
947 if( aiFlg==0 ) runtimeError("out of memory");
948 azCol[nCol-1] = safeId((const char*)sqlite3_column_text(pStmt,1));
949 aiFlg[nCol-1] = i = sqlite3_column_int(pStmt,5);
950 if( i>0 ){
951 if( i>nPk ){
952 nPk = i;
953 aiPk = sqlite3_realloc(aiPk, sizeof(int)*nPk);
954 if( aiPk==0 ) runtimeError("out of memory");
955 }
956 aiPk[i-1] = nCol-1;
957 }
958 }
959 sqlite3_finalize(pStmt);
960 if( nPk==0 ) goto end_changeset_one_table;
961 strInit(&sql);
962 if( nCol>nPk ){
drh697e5db2015-04-11 12:07:40 +0000963 strPrintf(&sql, "SELECT %d", SQLITE_UPDATE);
drh6e42ce42015-04-11 13:48:01 +0000964 for(i=0; i<nCol; i++){
965 if( aiFlg[i] ){
966 strPrintf(&sql, ",\n A.%s", azCol[i]);
967 }else{
968 strPrintf(&sql, ",\n A.%s IS NOT B.%s, A.%s, B.%s",
969 azCol[i], azCol[i], azCol[i], azCol[i]);
970 }
971 }
drh83e63dc2015-04-10 19:41:18 +0000972 strPrintf(&sql,"\n FROM main.%s A, aux.%s B\n", zId, zId);
973 zSep = " WHERE";
974 for(i=0; i<nPk; i++){
975 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
976 zSep = " AND";
977 }
978 zSep = "\n AND (";
979 for(i=0; i<nCol; i++){
980 if( aiFlg[i] ) continue;
981 strPrintf(&sql, "%sA.%s IS NOT B.%s", zSep, azCol[i], azCol[i]);
982 zSep = " OR\n ";
983 }
984 strPrintf(&sql,")\n UNION ALL\n");
985 }
drh697e5db2015-04-11 12:07:40 +0000986 strPrintf(&sql, "SELECT %d", SQLITE_DELETE);
drh6e42ce42015-04-11 13:48:01 +0000987 for(i=0; i<nCol; i++){
988 if( aiFlg[i] ){
989 strPrintf(&sql, ",\n A.%s", azCol[i]);
990 }else{
991 strPrintf(&sql, ",\n 1, A.%s, NULL", azCol[i]);
992 }
993 }
994 strPrintf(&sql, "\n FROM main.%s A\n", zId);
drh83e63dc2015-04-10 19:41:18 +0000995 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B\n", zId);
996 zSep = " WHERE";
997 for(i=0; i<nPk; i++){
998 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
999 zSep = " AND";
1000 }
1001 strPrintf(&sql, ")\n UNION ALL\n");
drh697e5db2015-04-11 12:07:40 +00001002 strPrintf(&sql, "SELECT %d", SQLITE_INSERT);
drh6e42ce42015-04-11 13:48:01 +00001003 for(i=0; i<nCol; i++){
1004 if( aiFlg[i] ){
1005 strPrintf(&sql, ",\n B.%s", azCol[i]);
1006 }else{
1007 strPrintf(&sql, ",\n 1, NULL, B.%s", azCol[i]);
1008 }
1009 }
1010 strPrintf(&sql, "\n FROM aux.%s B\n", zId);
drh83e63dc2015-04-10 19:41:18 +00001011 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A\n", zId);
1012 zSep = " WHERE";
1013 for(i=0; i<nPk; i++){
1014 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1015 zSep = " AND";
1016 }
1017 strPrintf(&sql, ")\n");
1018 strPrintf(&sql, " ORDER BY");
1019 zSep = " ";
1020 for(i=0; i<nPk; i++){
drh6e42ce42015-04-11 13:48:01 +00001021 strPrintf(&sql, "%s %d", zSep, aiPk[i]+2);
drh83e63dc2015-04-10 19:41:18 +00001022 zSep = ",";
1023 }
1024 strPrintf(&sql, ";\n");
1025
drh697e5db2015-04-11 12:07:40 +00001026 if( g.fDebug & DEBUG_DIFF_SQL ){
1027 printf("SQL for %s:\n%s\n", zId, sql.z);
1028 goto end_changeset_one_table;
1029 }
1030
1031 putc('T', out);
1032 putsVarint(out, (sqlite3_uint64)nCol);
1033 for(i=0; i<nCol; i++) putc(aiFlg[i]!=0, out);
1034 fwrite(zTab, 1, strlen(zTab), out);
1035 putc(0, out);
1036
1037 pStmt = db_prepare("%s", sql.z);
1038 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1039 int iType = sqlite3_column_int(pStmt,0);
drh697e5db2015-04-11 12:07:40 +00001040 putc(iType, out);
1041 putc(0, out);
drh6e42ce42015-04-11 13:48:01 +00001042 switch( sqlite3_column_int(pStmt,0) ){
1043 case SQLITE_UPDATE: {
1044 for(k=1, i=0; i<nCol; i++){
1045 if( aiFlg[i] ){
1046 putValue(out, sqlite3_column_value(pStmt,k));
1047 k++;
1048 }else if( sqlite3_column_int(pStmt,k) ){
1049 putValue(out, sqlite3_column_value(pStmt,k+1));
1050 k += 3;
1051 }else{
1052 putc(0, out);
1053 k += 3;
1054 }
1055 }
1056 for(k=1, i=0; i<nCol; i++){
1057 if( aiFlg[i] ){
1058 putc(0, out);
1059 k++;
1060 }else if( sqlite3_column_int(pStmt,k) ){
1061 putValue(out, sqlite3_column_value(pStmt,k+2));
1062 k += 3;
1063 }else{
1064 putc(0, out);
1065 k += 3;
1066 }
1067 }
1068 break;
1069 }
1070 case SQLITE_INSERT: {
1071 for(k=1, i=0; i<nCol; i++){
1072 if( aiFlg[i] ){
1073 putValue(out, sqlite3_column_value(pStmt,k));
1074 k++;
1075 }else{
1076 putValue(out, sqlite3_column_value(pStmt,k+2));
1077 k += 3;
1078 }
1079 }
1080 break;
1081 }
1082 case SQLITE_DELETE: {
1083 for(k=1, i=0; i<nCol; i++){
1084 if( aiFlg[i] ){
1085 putValue(out, sqlite3_column_value(pStmt,k));
1086 k++;
1087 }else{
1088 putValue(out, sqlite3_column_value(pStmt,k+1));
1089 k += 3;
1090 }
1091 }
1092 break;
drh697e5db2015-04-11 12:07:40 +00001093 }
1094 }
1095 }
1096 sqlite3_finalize(pStmt);
drh83e63dc2015-04-10 19:41:18 +00001097
1098end_changeset_one_table:
1099 while( nCol>0 ) sqlite3_free(azCol[--nCol]);
1100 sqlite3_free(azCol);
1101 sqlite3_free(aiPk);
1102 sqlite3_free(zId);
1103}
1104
1105/*
drhd62c0f42015-04-09 13:34:29 +00001106** Print sketchy documentation for this utility program
1107*/
1108static void showHelp(void){
1109 printf("Usage: %s [options] DB1 DB2\n", g.zArgv0);
1110 printf(
1111"Output SQL text that would transform DB1 into DB2.\n"
1112"Options:\n"
drh83e63dc2015-04-10 19:41:18 +00001113" --changeset FILE Write a CHANGESET into FILE\n"
drha37591c2015-04-09 18:14:03 +00001114" --primarykey Use schema-defined PRIMARY KEYs\n"
drhd62c0f42015-04-09 13:34:29 +00001115" --schema Show only differences in the schema\n"
drh8a1cd762015-04-14 19:01:08 +00001116" --summary Show only a summary of the differences\n"
drhd62c0f42015-04-09 13:34:29 +00001117" --table TAB Show only differences in table TAB\n"
1118 );
1119}
1120
1121int main(int argc, char **argv){
1122 const char *zDb1 = 0;
1123 const char *zDb2 = 0;
1124 int i;
1125 int rc;
1126 char *zErrMsg = 0;
1127 char *zSql;
1128 sqlite3_stmt *pStmt;
1129 char *zTab = 0;
drh8a1cd762015-04-14 19:01:08 +00001130 FILE *out = stdout;
1131 void (*xDiff)(const char*,FILE*) = diff_one_table;
drhd62c0f42015-04-09 13:34:29 +00001132
1133 g.zArgv0 = argv[0];
1134 for(i=1; i<argc; i++){
1135 const char *z = argv[i];
1136 if( z[0]=='-' ){
1137 z++;
1138 if( z[0]=='-' ) z++;
drh83e63dc2015-04-10 19:41:18 +00001139 if( strcmp(z,"changeset")==0 ){
1140 out = fopen(argv[++i], "wb");
1141 if( out==0 ) cmdlineError("cannot open: %s", argv[i]);
drh8a1cd762015-04-14 19:01:08 +00001142 xDiff = changeset_one_table;
drh83e63dc2015-04-10 19:41:18 +00001143 }else
drhd62c0f42015-04-09 13:34:29 +00001144 if( strcmp(z,"debug")==0 ){
1145 g.fDebug = strtol(argv[++i], 0, 0);
1146 }else
1147 if( strcmp(z,"help")==0 ){
1148 showHelp();
1149 return 0;
1150 }else
drha37591c2015-04-09 18:14:03 +00001151 if( strcmp(z,"primarykey")==0 ){
1152 g.bSchemaPK = 1;
1153 }else
drhd62c0f42015-04-09 13:34:29 +00001154 if( strcmp(z,"schema")==0 ){
1155 g.bSchemaOnly = 1;
1156 }else
drh8a1cd762015-04-14 19:01:08 +00001157 if( strcmp(z,"summary")==0 ){
1158 xDiff = summarize_one_table;
1159 }else
drhd62c0f42015-04-09 13:34:29 +00001160 if( strcmp(z,"table")==0 ){
1161 zTab = argv[++i];
1162 }else
1163 {
1164 cmdlineError("unknown option: %s", argv[i]);
1165 }
1166 }else if( zDb1==0 ){
1167 zDb1 = argv[i];
1168 }else if( zDb2==0 ){
1169 zDb2 = argv[i];
1170 }else{
1171 cmdlineError("unknown argument: %s", argv[i]);
1172 }
1173 }
1174 if( zDb2==0 ){
1175 cmdlineError("two database arguments required");
1176 }
1177 rc = sqlite3_open(zDb1, &g.db);
1178 if( rc ){
1179 cmdlineError("cannot open database file \"%s\"", zDb1);
1180 }
1181 rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_master", 0, 0, &zErrMsg);
1182 if( rc || zErrMsg ){
1183 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1);
1184 }
1185 zSql = sqlite3_mprintf("ATTACH %Q as aux;", zDb2);
1186 rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
1187 if( rc || zErrMsg ){
1188 cmdlineError("cannot attach database \"%s\"", zDb2);
1189 }
1190 rc = sqlite3_exec(g.db, "SELECT * FROM aux.sqlite_master", 0, 0, &zErrMsg);
1191 if( rc || zErrMsg ){
1192 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb2);
1193 }
1194
1195 if( zTab ){
drh8a1cd762015-04-14 19:01:08 +00001196 xDiff(zTab, out);
drhd62c0f42015-04-09 13:34:29 +00001197 }else{
1198 /* Handle tables one by one */
1199 pStmt = db_prepare(
1200 "SELECT name FROM main.sqlite_master\n"
1201 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1202 " UNION\n"
1203 "SELECT name FROM aux.sqlite_master\n"
1204 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1205 " ORDER BY name"
1206 );
1207 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +00001208 xDiff((const char*)sqlite3_column_text(pStmt,0), out);
drhd62c0f42015-04-09 13:34:29 +00001209 }
1210 sqlite3_finalize(pStmt);
1211 }
1212
1213 /* TBD: Handle trigger differences */
1214 /* TBD: Handle view differences */
1215 sqlite3_close(g.db);
1216 return 0;
1217}