blob: 3aae46a1f49b107b1ddc5669cefd7124a3986ced [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>
26#include "sqlite3.h"
27
28/*
29** All global variables are gathered into the "g" singleton.
30*/
31struct GlobalVars {
32 const char *zArgv0; /* Name of program */
33 int bSchemaOnly; /* Only show schema differences */
drha37591c2015-04-09 18:14:03 +000034 int bSchemaPK; /* Use the schema-defined PK, not the true PK */
drhd62c0f42015-04-09 13:34:29 +000035 unsigned fDebug; /* Debug flags */
36 sqlite3 *db; /* The database connection */
37} g;
38
39/*
40** Allowed values for g.fDebug
41*/
42#define DEBUG_COLUMN_NAMES 0x000001
43#define DEBUG_DIFF_SQL 0x000002
44
45/*
46** Dynamic string object
47*/
48typedef struct Str Str;
49struct Str {
50 char *z; /* Text of the string */
51 int nAlloc; /* Bytes allocated in z[] */
52 int nUsed; /* Bytes actually used in z[] */
53};
54
55/*
56** Initialize a Str object
57*/
58static void strInit(Str *p){
59 p->z = 0;
60 p->nAlloc = 0;
61 p->nUsed = 0;
62}
63
64/*
65** Print an error resulting from faulting command-line arguments and
66** abort the program.
67*/
68static void cmdlineError(const char *zFormat, ...){
69 va_list ap;
70 fprintf(stderr, "%s: ", g.zArgv0);
71 va_start(ap, zFormat);
72 vfprintf(stderr, zFormat, ap);
73 va_end(ap);
74 fprintf(stderr, "\n\"%s --help\" for more help\n", g.zArgv0);
75 exit(1);
76}
77
78/*
79** Print an error message for an error that occurs at runtime, then
80** abort the program.
81*/
82static void runtimeError(const char *zFormat, ...){
83 va_list ap;
84 fprintf(stderr, "%s: ", g.zArgv0);
85 va_start(ap, zFormat);
86 vfprintf(stderr, zFormat, ap);
87 va_end(ap);
88 fprintf(stderr, "\n");
89 exit(1);
90}
91
92/*
93** Free all memory held by a Str object
94*/
95static void strFree(Str *p){
96 sqlite3_free(p->z);
97 strInit(p);
98}
99
100/*
101** Add formatted text to the end of a Str object
102*/
103static void strPrintf(Str *p, const char *zFormat, ...){
104 int nNew;
105 for(;;){
106 if( p->z ){
107 va_list ap;
108 va_start(ap, zFormat);
109 sqlite3_vsnprintf(p->nAlloc-p->nUsed, p->z+p->nUsed, zFormat, ap);
110 va_end(ap);
111 nNew = (int)strlen(p->z + p->nUsed);
112 }else{
113 nNew = p->nAlloc;
114 }
115 if( p->nUsed+nNew < p->nAlloc-1 ){
116 p->nUsed += nNew;
117 break;
118 }
119 p->nAlloc = p->nAlloc*2 + 1000;
120 p->z = sqlite3_realloc(p->z, p->nAlloc);
121 if( p->z==0 ) runtimeError("out of memory");
122 }
123}
124
125
126
127/* Safely quote an SQL identifier. Use the minimum amount of transformation
128** necessary to allow the string to be used with %s.
129**
130** Space to hold the returned string is obtained from sqlite3_malloc(). The
131** caller is responsible for ensuring this space is freed when no longer
132** needed.
133*/
134static char *safeId(const char *zId){
135 /* All SQLite keywords, in alphabetical order */
136 static const char *azKeywords[] = {
137 "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
138 "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
139 "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
140 "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
141 "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
142 "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
143 "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
144 "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
145 "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
146 "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
147 "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO", "NOT", "NOTNULL",
148 "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
149 "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
150 "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
151 "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
152 "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
153 "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
154 "WITH", "WITHOUT",
155 };
156 int lwr, upr, mid, c, i, x;
157 for(i=x=0; (c = zId[i])!=0; i++){
158 if( !isalpha(c) && c!='_' ){
159 if( i>0 && isdigit(c) ){
160 x++;
161 }else{
162 return sqlite3_mprintf("\"%w\"", zId);
163 }
164 }
165 }
166 if( x ) return sqlite3_mprintf("%s", zId);
167 lwr = 0;
168 upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1;
169 while( lwr<=upr ){
170 mid = (lwr+upr)/2;
171 c = sqlite3_stricmp(azKeywords[mid], zId);
172 if( c==0 ) return sqlite3_mprintf("\"%w\"", zId);
173 if( c<0 ){
174 lwr = mid+1;
175 }else{
176 upr = mid-1;
177 }
178 }
179 return sqlite3_mprintf("%s", zId);
180}
181
182/*
183** Prepare a new SQL statement. Print an error and abort if anything
184** goes wrong.
185*/
186static sqlite3_stmt *db_vprepare(const char *zFormat, va_list ap){
187 char *zSql;
188 int rc;
189 sqlite3_stmt *pStmt;
190
191 zSql = sqlite3_vmprintf(zFormat, ap);
192 if( zSql==0 ) runtimeError("out of memory");
193 rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt, 0);
194 if( rc ){
195 runtimeError("SQL statement error: %s\n\"%s\"", sqlite3_errmsg(g.db),
196 zSql);
197 }
198 sqlite3_free(zSql);
199 return pStmt;
200}
201static sqlite3_stmt *db_prepare(const char *zFormat, ...){
202 va_list ap;
203 sqlite3_stmt *pStmt;
204 va_start(ap, zFormat);
205 pStmt = db_vprepare(zFormat, ap);
206 va_end(ap);
207 return pStmt;
208}
209
210/*
211** Free a list of strings
212*/
213static void namelistFree(char **az){
214 if( az ){
215 int i;
216 for(i=0; az[i]; i++) sqlite3_free(az[i]);
217 sqlite3_free(az);
218 }
219}
220
221/*
222** Return a list of column names for the table zDb.zTab. Space to
drh39b355c2015-04-09 13:40:18 +0000223** hold the list is obtained from sqlite3_malloc() and should released
224** using namelistFree() when no longer needed.
drhd62c0f42015-04-09 13:34:29 +0000225**
drha37591c2015-04-09 18:14:03 +0000226** Primary key columns are listed first, followed by data columns.
227** The number of columns in the primary key is returned in *pnPkey.
drhd62c0f42015-04-09 13:34:29 +0000228**
drha37591c2015-04-09 18:14:03 +0000229** Normally, the "primary key" in the previous sentence is the true
230** primary key - the rowid or INTEGER PRIMARY KEY for ordinary tables
231** or the declared PRIMARY KEY for WITHOUT ROWID tables. However, if
232** the g.bSchemaPK flag is set, then the schema-defined PRIMARY KEY is
233** used in all cases. In that case, entries that have NULL values in
234** any of their primary key fields will be excluded from the analysis.
235**
236** If the primary key for a table is the rowid but rowid is inaccessible,
drhd62c0f42015-04-09 13:34:29 +0000237** then this routine returns a NULL pointer.
238**
239** Examples:
240** CREATE TABLE t1(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(c));
241** *pnPKey = 1;
drha37591c2015-04-09 18:14:03 +0000242** az = { "rowid", "a", "b", "c", 0 } // Normal case
243** az = { "c", "a", "b", 0 } // g.bSchemaPK==1
drhd62c0f42015-04-09 13:34:29 +0000244**
245** CREATE TABLE t2(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(b));
246** *pnPKey = 1;
247** az = { "b", "a", "c", 0 }
248**
249** CREATE TABLE t3(x,y,z,PRIMARY KEY(y,z));
drha37591c2015-04-09 18:14:03 +0000250** *pnPKey = 1 // Normal case
251** az = { "rowid", "x", "y", "z", 0 } // Normal case
252** *pnPKey = 2 // g.bSchemaPK==1
253** az = { "y", "x", "z", 0 } // g.bSchemaPK==1
drhd62c0f42015-04-09 13:34:29 +0000254**
255** CREATE TABLE t4(x,y,z,PRIMARY KEY(y,z)) WITHOUT ROWID;
256** *pnPKey = 2
257** az = { "y", "z", "x", 0 }
258**
259** CREATE TABLE t5(rowid,_rowid_,oid);
260** az = 0 // The rowid is not accessible
261*/
262static char **columnNames(const char *zDb, const char *zTab, int *pnPKey){
drha37591c2015-04-09 18:14:03 +0000263 char **az = 0; /* List of column names to be returned */
264 int naz = 0; /* Number of entries in az[] */
265 sqlite3_stmt *pStmt; /* SQL statement being run */
drhd62c0f42015-04-09 13:34:29 +0000266 char *zPkIdxName = 0; /* Name of the PRIMARY KEY index */
drha37591c2015-04-09 18:14:03 +0000267 int truePk = 0; /* PRAGMA table_info indentifies the PK to use */
drhd62c0f42015-04-09 13:34:29 +0000268 int nPK = 0; /* Number of PRIMARY KEY columns */
drha37591c2015-04-09 18:14:03 +0000269 int i, j; /* Loop counters */
drhd62c0f42015-04-09 13:34:29 +0000270
drha37591c2015-04-09 18:14:03 +0000271 if( g.bSchemaPK==0 ){
272 /* Normal case: Figure out what the true primary key is for the table.
273 ** * For WITHOUT ROWID tables, the true primary key is the same as
274 ** the schema PRIMARY KEY, which is guaranteed to be present.
275 ** * For rowid tables with an INTEGER PRIMARY KEY, the true primary
276 ** key is the INTEGER PRIMARY KEY.
277 ** * For all other rowid tables, the rowid is the true primary key.
278 */
279 pStmt = db_prepare("PRAGMA %s.index_list=%Q", zDb, zTab);
drhd62c0f42015-04-09 13:34:29 +0000280 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drha37591c2015-04-09 18:14:03 +0000281 if( sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,3),"pk")==0 ){
282 zPkIdxName = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
283 break;
284 }
drhd62c0f42015-04-09 13:34:29 +0000285 }
286 sqlite3_finalize(pStmt);
drha37591c2015-04-09 18:14:03 +0000287 if( zPkIdxName ){
288 int nKey = 0;
289 int nCol = 0;
290 truePk = 0;
291 pStmt = db_prepare("PRAGMA %s.index_xinfo=%Q", zDb, zPkIdxName);
292 while( SQLITE_ROW==sqlite3_step(pStmt) ){
293 nCol++;
294 if( sqlite3_column_int(pStmt,5) ){ nKey++; continue; }
295 if( sqlite3_column_int(pStmt,1)>=0 ) truePk = 1;
296 }
297 if( nCol==nKey ) truePk = 1;
298 if( truePk ){
299 nPK = nKey;
300 }else{
301 nPK = 1;
302 }
303 sqlite3_finalize(pStmt);
304 sqlite3_free(zPkIdxName);
305 }else{
306 truePk = 1;
307 nPK = 1;
308 }
309 pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
drhd62c0f42015-04-09 13:34:29 +0000310 }else{
drha37591c2015-04-09 18:14:03 +0000311 /* The g.bSchemaPK==1 case: Use whatever primary key is declared
312 ** in the schema. The "rowid" will still be used as the primary key
313 ** if the table definition does not contain a PRIMARY KEY.
314 */
315 nPK = 0;
316 pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
317 while( SQLITE_ROW==sqlite3_step(pStmt) ){
318 if( sqlite3_column_int(pStmt,5)>0 ) nPK++;
319 }
320 sqlite3_reset(pStmt);
321 if( nPK==0 ) nPK = 1;
drhd62c0f42015-04-09 13:34:29 +0000322 truePk = 1;
drhd62c0f42015-04-09 13:34:29 +0000323 }
324 *pnPKey = nPK;
325 naz = nPK;
326 az = sqlite3_malloc( sizeof(char*)*(nPK+1) );
327 if( az==0 ) runtimeError("out of memory");
328 memset(az, 0, sizeof(char*)*(nPK+1));
drhd62c0f42015-04-09 13:34:29 +0000329 while( SQLITE_ROW==sqlite3_step(pStmt) ){
330 int iPKey;
331 if( truePk && (iPKey = sqlite3_column_int(pStmt,5))>0 ){
332 az[iPKey-1] = safeId((char*)sqlite3_column_text(pStmt,1));
333 }else{
334 az = sqlite3_realloc(az, sizeof(char*)*(naz+2) );
335 if( az==0 ) runtimeError("out of memory");
336 az[naz++] = safeId((char*)sqlite3_column_text(pStmt,1));
337 }
338 }
339 sqlite3_finalize(pStmt);
340 if( az ) az[naz] = 0;
341 if( az[0]==0 ){
342 const char *azRowid[] = { "rowid", "_rowid_", "oid" };
343 for(i=0; i<sizeof(azRowid)/sizeof(azRowid[0]); i++){
344 for(j=1; j<naz; j++){
345 if( sqlite3_stricmp(az[j], azRowid[i])==0 ) break;
346 }
347 if( j>=naz ){
348 az[0] = sqlite3_mprintf("%s", azRowid[i]);
349 break;
350 }
351 }
352 if( az[0]==0 ){
353 for(i=1; i<naz; i++) sqlite3_free(az[i]);
354 sqlite3_free(az);
355 az = 0;
356 }
357 }
358 return az;
359}
360
361/*
362** Print the sqlite3_value X as an SQL literal.
363*/
drh8a1cd762015-04-14 19:01:08 +0000364static void printQuoted(FILE *out, sqlite3_value *X){
drhd62c0f42015-04-09 13:34:29 +0000365 switch( sqlite3_value_type(X) ){
366 case SQLITE_FLOAT: {
367 double r1;
368 char zBuf[50];
369 r1 = sqlite3_value_double(X);
370 sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
drh8a1cd762015-04-14 19:01:08 +0000371 fprintf(out, "%s", zBuf);
drhd62c0f42015-04-09 13:34:29 +0000372 break;
373 }
374 case SQLITE_INTEGER: {
drh8a1cd762015-04-14 19:01:08 +0000375 fprintf(out, "%lld", sqlite3_value_int64(X));
drhd62c0f42015-04-09 13:34:29 +0000376 break;
377 }
378 case SQLITE_BLOB: {
379 const unsigned char *zBlob = sqlite3_value_blob(X);
380 int nBlob = sqlite3_value_bytes(X);
381 if( zBlob ){
382 int i;
drh8a1cd762015-04-14 19:01:08 +0000383 fprintf(out, "x'");
drhd62c0f42015-04-09 13:34:29 +0000384 for(i=0; i<nBlob; i++){
drh8a1cd762015-04-14 19:01:08 +0000385 fprintf(out, "%02x", zBlob[i]);
drhd62c0f42015-04-09 13:34:29 +0000386 }
drh8a1cd762015-04-14 19:01:08 +0000387 fprintf(out, "'");
drhd62c0f42015-04-09 13:34:29 +0000388 }else{
drh8a1cd762015-04-14 19:01:08 +0000389 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000390 }
391 break;
392 }
393 case SQLITE_TEXT: {
394 const unsigned char *zArg = sqlite3_value_text(X);
395 int i, j;
396
397 if( zArg==0 ){
drh8a1cd762015-04-14 19:01:08 +0000398 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000399 }else{
drh8a1cd762015-04-14 19:01:08 +0000400 fprintf(out, "'");
drhd62c0f42015-04-09 13:34:29 +0000401 for(i=j=0; zArg[i]; i++){
402 if( zArg[i]=='\'' ){
drh8a1cd762015-04-14 19:01:08 +0000403 fprintf(out, "%.*s'", i-j+1, &zArg[j]);
drhd62c0f42015-04-09 13:34:29 +0000404 j = i+1;
405 }
406 }
drh8a1cd762015-04-14 19:01:08 +0000407 fprintf(out, "%s'", &zArg[j]);
drhd62c0f42015-04-09 13:34:29 +0000408 }
409 break;
410 }
411 case SQLITE_NULL: {
drh8a1cd762015-04-14 19:01:08 +0000412 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000413 break;
414 }
415 }
416}
417
418/*
419** Output SQL that will recreate the aux.zTab table.
420*/
drh8a1cd762015-04-14 19:01:08 +0000421static void dump_table(const char *zTab, FILE *out){
drhd62c0f42015-04-09 13:34:29 +0000422 char *zId = safeId(zTab); /* Name of the table */
423 char **az = 0; /* List of columns */
424 int nPk; /* Number of true primary key columns */
425 int nCol; /* Number of data columns */
426 int i; /* Loop counter */
427 sqlite3_stmt *pStmt; /* SQL statement */
428 const char *zSep; /* Separator string */
429 Str ins; /* Beginning of the INSERT statement */
430
431 pStmt = db_prepare("SELECT sql FROM aux.sqlite_master WHERE name=%Q", zTab);
432 if( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000433 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000434 }
435 sqlite3_finalize(pStmt);
436 if( !g.bSchemaOnly ){
437 az = columnNames("aux", zTab, &nPk);
438 strInit(&ins);
439 if( az==0 ){
440 pStmt = db_prepare("SELECT * FROM aux.%s", zId);
441 strPrintf(&ins,"INSERT INTO %s VALUES", zId);
442 }else{
443 Str sql;
444 strInit(&sql);
445 zSep = "SELECT";
446 for(i=0; az[i]; i++){
447 strPrintf(&sql, "%s %s", zSep, az[i]);
448 zSep = ",";
449 }
450 strPrintf(&sql," FROM aux.%s", zId);
451 zSep = " ORDER BY";
452 for(i=1; i<=nPk; i++){
453 strPrintf(&sql, "%s %d", zSep, i);
454 zSep = ",";
455 }
456 pStmt = db_prepare("%s", sql.z);
457 strFree(&sql);
458 strPrintf(&ins, "INSERT INTO %s", zId);
459 zSep = "(";
460 for(i=0; az[i]; i++){
461 strPrintf(&ins, "%s%s", zSep, az[i]);
462 zSep = ",";
463 }
464 strPrintf(&ins,") VALUES");
465 namelistFree(az);
466 }
467 nCol = sqlite3_column_count(pStmt);
468 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000469 fprintf(out, "%s",ins.z);
drhd62c0f42015-04-09 13:34:29 +0000470 zSep = "(";
471 for(i=0; i<nCol; i++){
drh8a1cd762015-04-14 19:01:08 +0000472 fprintf(out, "%s",zSep);
473 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000474 zSep = ",";
475 }
drh8a1cd762015-04-14 19:01:08 +0000476 fprintf(out, ");\n");
drhd62c0f42015-04-09 13:34:29 +0000477 }
478 sqlite3_finalize(pStmt);
479 strFree(&ins);
480 } /* endif !g.bSchemaOnly */
481 pStmt = db_prepare("SELECT sql FROM aux.sqlite_master"
482 " WHERE type='index' AND tbl_name=%Q AND sql IS NOT NULL",
483 zTab);
484 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000485 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000486 }
487 sqlite3_finalize(pStmt);
488}
489
490
491/*
492** Compute all differences for a single table.
493*/
drh8a1cd762015-04-14 19:01:08 +0000494static void diff_one_table(const char *zTab, FILE *out){
drhd62c0f42015-04-09 13:34:29 +0000495 char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
496 char **az = 0; /* Columns in main */
497 char **az2 = 0; /* Columns in aux */
498 int nPk; /* Primary key columns in main */
499 int nPk2; /* Primary key columns in aux */
drhb3f3d642015-04-25 18:39:21 +0000500 int n = 0; /* Number of columns in main */
drhd62c0f42015-04-09 13:34:29 +0000501 int n2; /* Number of columns in aux */
502 int nQ; /* Number of output columns in the diff query */
503 int i; /* Loop counter */
504 const char *zSep; /* Separator string */
505 Str sql; /* Comparison query */
506 sqlite3_stmt *pStmt; /* Query statement to do the diff */
507
508 strInit(&sql);
509 if( g.fDebug==DEBUG_COLUMN_NAMES ){
510 /* Simply run columnNames() on all tables of the origin
511 ** database and show the results. This is used for testing
512 ** and debugging of the columnNames() function.
513 */
514 az = columnNames("aux",zTab, &nPk);
515 if( az==0 ){
516 printf("Rowid not accessible for %s\n", zId);
517 }else{
518 printf("%s:", zId);
519 for(i=0; az[i]; i++){
520 printf(" %s", az[i]);
521 if( i+1==nPk ) printf(" *");
522 }
523 printf("\n");
524 }
525 goto end_diff_one_table;
526 }
527
528
529 if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
530 if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
531 /* Table missing from second database. */
drh8a1cd762015-04-14 19:01:08 +0000532 fprintf(out, "DROP TABLE %s;\n", zId);
drhd62c0f42015-04-09 13:34:29 +0000533 }
534 goto end_diff_one_table;
535 }
536
537 if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
538 /* Table missing from source */
drh8a1cd762015-04-14 19:01:08 +0000539 dump_table(zTab, out);
drhd62c0f42015-04-09 13:34:29 +0000540 goto end_diff_one_table;
541 }
542
543 az = columnNames("main", zTab, &nPk);
544 az2 = columnNames("aux", zTab, &nPk2);
545 if( az && az2 ){
546 for(n=0; az[n]; n++){
547 if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
548 }
549 }
550 if( az==0
551 || az2==0
552 || nPk!=nPk2
553 || az[n]
554 ){
555 /* Schema mismatch */
drh8a1cd762015-04-14 19:01:08 +0000556 fprintf(out, "DROP TABLE %s;\n", zId);
557 dump_table(zTab, out);
drhd62c0f42015-04-09 13:34:29 +0000558 goto end_diff_one_table;
559 }
560
561 /* Build the comparison query */
562 for(n2=n; az[n2]; n2++){}
563 nQ = nPk2+1+2*(n2-nPk2);
564 if( n2>nPk2 ){
565 zSep = "SELECT ";
566 for(i=0; i<nPk; i++){
567 strPrintf(&sql, "%sB.%s", zSep, az[i]);
568 zSep = ", ";
569 }
570 strPrintf(&sql, ", 1%s -- changed row\n", nPk==n ? "" : ",");
571 while( az[i] ){
572 strPrintf(&sql, " A.%s IS NOT B.%s, B.%s%s\n",
573 az[i], az[i], az[i], i==n2-1 ? "" : ",");
574 i++;
575 }
576 strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId);
577 zSep = " WHERE";
578 for(i=0; i<nPk; i++){
579 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
580 zSep = " AND";
581 }
582 zSep = "\n AND (";
583 while( az[i] ){
584 strPrintf(&sql, "%sA.%s IS NOT B.%s%s\n",
585 zSep, az[i], az[i], i==n2-1 ? ")" : "");
586 zSep = " OR ";
587 i++;
588 }
589 strPrintf(&sql, " UNION ALL\n");
590 }
591 zSep = "SELECT ";
592 for(i=0; i<nPk; i++){
593 strPrintf(&sql, "%sA.%s", zSep, az[i]);
594 zSep = ", ";
595 }
596 strPrintf(&sql, ", 2%s -- deleted row\n", nPk==n ? "" : ",");
597 while( az[i] ){
598 strPrintf(&sql, " NULL, NULL%s\n", i==n2-1 ? "" : ",");
599 i++;
600 }
601 strPrintf(&sql, " FROM main.%s A\n", zId);
602 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B\n", zId);
603 zSep = " WHERE";
604 for(i=0; i<nPk; i++){
605 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
606 zSep = " AND";
607 }
608 strPrintf(&sql, ")\n");
609 zSep = " UNION ALL\nSELECT ";
610 for(i=0; i<nPk; i++){
611 strPrintf(&sql, "%sB.%s", zSep, az[i]);
612 zSep = ", ";
613 }
614 strPrintf(&sql, ", 3%s -- inserted row\n", nPk==n ? "" : ",");
615 while( az2[i] ){
616 strPrintf(&sql, " 1, B.%s%s\n", az[i], i==n2-1 ? "" : ",");
617 i++;
618 }
619 strPrintf(&sql, " FROM aux.%s B\n", zId);
620 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A\n", zId);
621 zSep = " WHERE";
622 for(i=0; i<nPk; i++){
623 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
624 zSep = " AND";
625 }
626 strPrintf(&sql, ")\n ORDER BY");
627 zSep = " ";
628 for(i=1; i<=nPk; i++){
629 strPrintf(&sql, "%s%d", zSep, i);
630 zSep = ", ";
631 }
632 strPrintf(&sql, ";\n");
633
634 if( g.fDebug & DEBUG_DIFF_SQL ){
635 printf("SQL for %s:\n%s\n", zId, sql.z);
636 goto end_diff_one_table;
637 }
638
639 /* Drop indexes that are missing in the destination */
640 pStmt = db_prepare(
641 "SELECT name FROM main.sqlite_master"
642 " WHERE type='index' AND tbl_name=%Q"
643 " AND sql IS NOT NULL"
644 " AND sql NOT IN (SELECT sql FROM aux.sqlite_master"
645 " WHERE type='index' AND tbl_name=%Q"
646 " AND sql IS NOT NULL)",
647 zTab, zTab);
648 while( SQLITE_ROW==sqlite3_step(pStmt) ){
649 char *z = safeId((const char*)sqlite3_column_text(pStmt,0));
drh8a1cd762015-04-14 19:01:08 +0000650 fprintf(out, "DROP INDEX %s;\n", z);
drhd62c0f42015-04-09 13:34:29 +0000651 sqlite3_free(z);
652 }
653 sqlite3_finalize(pStmt);
654
655 /* Run the query and output differences */
656 if( !g.bSchemaOnly ){
657 pStmt = db_prepare(sql.z);
658 while( SQLITE_ROW==sqlite3_step(pStmt) ){
659 int iType = sqlite3_column_int(pStmt, nPk);
660 if( iType==1 || iType==2 ){
661 if( iType==1 ){ /* Change the content of a row */
drh8a1cd762015-04-14 19:01:08 +0000662 fprintf(out, "UPDATE %s", zId);
drhd62c0f42015-04-09 13:34:29 +0000663 zSep = " SET";
664 for(i=nPk+1; i<nQ; i+=2){
665 if( sqlite3_column_int(pStmt,i)==0 ) continue;
drh8a1cd762015-04-14 19:01:08 +0000666 fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]);
drhd62c0f42015-04-09 13:34:29 +0000667 zSep = ",";
drh8a1cd762015-04-14 19:01:08 +0000668 printQuoted(out, sqlite3_column_value(pStmt,i+1));
drhd62c0f42015-04-09 13:34:29 +0000669 }
670 }else{ /* Delete a row */
drh8a1cd762015-04-14 19:01:08 +0000671 fprintf(out, "DELETE FROM %s", zId);
drhd62c0f42015-04-09 13:34:29 +0000672 }
673 zSep = " WHERE";
674 for(i=0; i<nPk; i++){
drh8a1cd762015-04-14 19:01:08 +0000675 fprintf(out, "%s %s=", zSep, az2[i]);
676 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000677 zSep = ",";
678 }
drh8a1cd762015-04-14 19:01:08 +0000679 fprintf(out, ";\n");
drhd62c0f42015-04-09 13:34:29 +0000680 }else{ /* Insert a row */
drh8a1cd762015-04-14 19:01:08 +0000681 fprintf(out, "INSERT INTO %s(%s", zId, az2[0]);
682 for(i=1; az2[i]; i++) fprintf(out, ",%s", az2[i]);
683 fprintf(out, ") VALUES");
drhd62c0f42015-04-09 13:34:29 +0000684 zSep = "(";
685 for(i=0; i<nPk2; i++){
drh8a1cd762015-04-14 19:01:08 +0000686 fprintf(out, "%s", zSep);
drhd62c0f42015-04-09 13:34:29 +0000687 zSep = ",";
drh8a1cd762015-04-14 19:01:08 +0000688 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000689 }
690 for(i=nPk2+2; i<nQ; i+=2){
drh8a1cd762015-04-14 19:01:08 +0000691 fprintf(out, ",");
692 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000693 }
drh8a1cd762015-04-14 19:01:08 +0000694 fprintf(out, ");\n");
drhd62c0f42015-04-09 13:34:29 +0000695 }
696 }
697 sqlite3_finalize(pStmt);
698 } /* endif !g.bSchemaOnly */
699
700 /* Create indexes that are missing in the source */
701 pStmt = db_prepare(
702 "SELECT sql FROM aux.sqlite_master"
703 " WHERE type='index' AND tbl_name=%Q"
704 " AND sql IS NOT NULL"
705 " AND sql NOT IN (SELECT sql FROM main.sqlite_master"
706 " WHERE type='index' AND tbl_name=%Q"
707 " AND sql IS NOT NULL)",
708 zTab, zTab);
709 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000710 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000711 }
712 sqlite3_finalize(pStmt);
713
714end_diff_one_table:
715 strFree(&sql);
716 sqlite3_free(zId);
717 namelistFree(az);
718 namelistFree(az2);
719 return;
720}
721
722/*
drh8a1cd762015-04-14 19:01:08 +0000723** Display a summary of differences between two versions of the same
724** table table.
725**
726** * Number of rows changed
727** * Number of rows added
728** * Number of rows deleted
729** * Number of identical rows
730*/
731static void summarize_one_table(const char *zTab, FILE *out){
732 char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
733 char **az = 0; /* Columns in main */
734 char **az2 = 0; /* Columns in aux */
735 int nPk; /* Primary key columns in main */
736 int nPk2; /* Primary key columns in aux */
drhb3f3d642015-04-25 18:39:21 +0000737 int n = 0; /* Number of columns in main */
drh8a1cd762015-04-14 19:01:08 +0000738 int n2; /* Number of columns in aux */
739 int i; /* Loop counter */
740 const char *zSep; /* Separator string */
741 Str sql; /* Comparison query */
742 sqlite3_stmt *pStmt; /* Query statement to do the diff */
743 sqlite3_int64 nUpdate; /* Number of updated rows */
744 sqlite3_int64 nUnchanged; /* Number of unmodified rows */
745 sqlite3_int64 nDelete; /* Number of deleted rows */
746 sqlite3_int64 nInsert; /* Number of inserted rows */
747
748 strInit(&sql);
749 if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
750 if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
751 /* Table missing from second database. */
752 fprintf(out, "%s: missing from second database\n", zTab);
753 }
754 goto end_summarize_one_table;
755 }
756
757 if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
758 /* Table missing from source */
759 fprintf(out, "%s: missing from first database\n", zTab);
760 goto end_summarize_one_table;
761 }
762
763 az = columnNames("main", zTab, &nPk);
764 az2 = columnNames("aux", zTab, &nPk2);
765 if( az && az2 ){
766 for(n=0; az[n]; n++){
767 if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
768 }
769 }
770 if( az==0
771 || az2==0
772 || nPk!=nPk2
773 || az[n]
774 ){
775 /* Schema mismatch */
776 fprintf(out, "%s: incompatible schema\n", zTab);
777 goto end_summarize_one_table;
778 }
779
780 /* Build the comparison query */
781 for(n2=n; az[n2]; n2++){}
782 strPrintf(&sql, "SELECT 1, count(*)");
783 if( n2==nPk2 ){
784 strPrintf(&sql, ", 0\n");
785 }else{
786 zSep = ", sum(";
787 for(i=nPk; az[i]; i++){
788 strPrintf(&sql, "%sA.%s IS NOT B.%s", zSep, az[i], az[i]);
789 zSep = " OR ";
790 }
791 strPrintf(&sql, ")\n");
792 }
793 strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId);
794 zSep = " WHERE";
795 for(i=0; i<nPk; i++){
796 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
797 zSep = " AND";
798 }
799 strPrintf(&sql, " UNION ALL\n");
800 strPrintf(&sql, "SELECT 2, count(*), 0\n");
801 strPrintf(&sql, " FROM main.%s A\n", zId);
802 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B ", zId);
803 zSep = "WHERE";
804 for(i=0; i<nPk; i++){
805 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
806 zSep = " AND";
807 }
808 strPrintf(&sql, ")\n");
809 strPrintf(&sql, " UNION ALL\n");
810 strPrintf(&sql, "SELECT 3, count(*), 0\n");
811 strPrintf(&sql, " FROM aux.%s B\n", zId);
812 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A ", zId);
813 zSep = "WHERE";
814 for(i=0; i<nPk; i++){
815 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
816 zSep = " AND";
817 }
818 strPrintf(&sql, ")\n ORDER BY 1;\n");
819
820 if( (g.fDebug & DEBUG_DIFF_SQL)!=0 ){
821 printf("SQL for %s:\n%s\n", zId, sql.z);
822 goto end_summarize_one_table;
823 }
824
825 /* Run the query and output difference summary */
826 pStmt = db_prepare(sql.z);
827 nUpdate = 0;
828 nInsert = 0;
829 nDelete = 0;
830 nUnchanged = 0;
831 while( SQLITE_ROW==sqlite3_step(pStmt) ){
832 switch( sqlite3_column_int(pStmt,0) ){
833 case 1:
834 nUpdate = sqlite3_column_int64(pStmt,2);
835 nUnchanged = sqlite3_column_int64(pStmt,1) - nUpdate;
836 break;
837 case 2:
838 nDelete = sqlite3_column_int64(pStmt,1);
839 break;
840 case 3:
841 nInsert = sqlite3_column_int64(pStmt,1);
842 break;
843 }
844 }
845 sqlite3_finalize(pStmt);
846 fprintf(out, "%s: %lld changes, %lld inserts, %lld deletes, %lld unchanged\n",
847 zTab, nUpdate, nInsert, nDelete, nUnchanged);
848
849end_summarize_one_table:
850 strFree(&sql);
851 sqlite3_free(zId);
852 namelistFree(az);
853 namelistFree(az2);
854 return;
855}
856
857/*
drh697e5db2015-04-11 12:07:40 +0000858** Write a 64-bit signed integer as a varint onto out
859*/
860static void putsVarint(FILE *out, sqlite3_uint64 v){
861 int i, n;
drh6e42ce42015-04-11 13:48:01 +0000862 unsigned char p[12];
drh697e5db2015-04-11 12:07:40 +0000863 if( v & (((sqlite3_uint64)0xff000000)<<32) ){
864 p[8] = (unsigned char)v;
865 v >>= 8;
866 for(i=7; i>=0; i--){
867 p[i] = (unsigned char)((v & 0x7f) | 0x80);
868 v >>= 7;
869 }
870 fwrite(p, 8, 1, out);
871 }else{
872 n = 9;
873 do{
874 p[n--] = (unsigned char)((v & 0x7f) | 0x80);
875 v >>= 7;
876 }while( v!=0 );
drh6e42ce42015-04-11 13:48:01 +0000877 p[9] &= 0x7f;
878 fwrite(p+n+1, 9-n, 1, out);
879 }
880}
881
882/*
883** Write an SQLite value onto out.
884*/
885static void putValue(FILE *out, sqlite3_value *pVal){
886 int iDType = sqlite3_value_type(pVal);
887 sqlite3_int64 iX;
888 double rX;
889 sqlite3_uint64 uX;
890 int j;
891
892 putc(iDType, out);
893 switch( iDType ){
894 case SQLITE_INTEGER:
895 iX = sqlite3_value_int64(pVal);
896 memcpy(&uX, &iX, 8);
897 for(j=56; j>=0; j-=8) putc((uX>>j)&0xff, out);
898 break;
899 case SQLITE_FLOAT:
drh33aa4db2015-05-04 15:04:47 +0000900 rX = sqlite3_value_double(pVal);
drh6e42ce42015-04-11 13:48:01 +0000901 memcpy(&uX, &rX, 8);
902 for(j=56; j>=0; j-=8) putc((uX>>j)&0xff, out);
903 break;
904 case SQLITE_TEXT:
905 iX = sqlite3_value_bytes(pVal);
906 putsVarint(out, (sqlite3_uint64)iX);
drh33aa4db2015-05-04 15:04:47 +0000907 fwrite(sqlite3_value_text(pVal),1,(size_t)iX,out);
drh6e42ce42015-04-11 13:48:01 +0000908 break;
909 case SQLITE_BLOB:
910 iX = sqlite3_value_bytes(pVal);
911 putsVarint(out, (sqlite3_uint64)iX);
drh33aa4db2015-05-04 15:04:47 +0000912 fwrite(sqlite3_value_blob(pVal),1,(size_t)iX,out);
drh6e42ce42015-04-11 13:48:01 +0000913 break;
914 case SQLITE_NULL:
915 break;
drh697e5db2015-04-11 12:07:40 +0000916 }
917}
918
919/*
drh83e63dc2015-04-10 19:41:18 +0000920** Generate a CHANGESET for all differences from main.zTab to aux.zTab.
921*/
922static void changeset_one_table(const char *zTab, FILE *out){
923 sqlite3_stmt *pStmt; /* SQL statment */
924 char *zId = safeId(zTab); /* Escaped name of the table */
925 char **azCol = 0; /* List of escaped column names */
926 int nCol = 0; /* Number of columns */
927 int *aiFlg = 0; /* 0 if column is not part of PK */
928 int *aiPk = 0; /* Column numbers for each PK column */
929 int nPk = 0; /* Number of PRIMARY KEY columns */
930 Str sql; /* SQL for the diff query */
drh6e42ce42015-04-11 13:48:01 +0000931 int i, k; /* Loop counters */
drh83e63dc2015-04-10 19:41:18 +0000932 const char *zSep; /* List separator */
933
934 pStmt = db_prepare(
935 "SELECT A.sql=B.sql FROM main.sqlite_master A, aux.sqlite_master B"
936 " WHERE A.name=%Q AND B.name=%Q", zTab, zTab
937 );
938 if( SQLITE_ROW==sqlite3_step(pStmt) ){
939 if( sqlite3_column_int(pStmt,0)==0 ){
940 runtimeError("schema changes for table %s", safeId(zTab));
941 }
942 }else{
943 runtimeError("table %s missing from one or both databases", safeId(zTab));
944 }
945 sqlite3_finalize(pStmt);
946 pStmt = db_prepare("PRAGMA main.table_info=%Q", zTab);
947 while( SQLITE_ROW==sqlite3_step(pStmt) ){
948 nCol++;
949 azCol = sqlite3_realloc(azCol, sizeof(char*)*nCol);
950 if( azCol==0 ) runtimeError("out of memory");
951 aiFlg = sqlite3_realloc(aiFlg, sizeof(int)*nCol);
952 if( aiFlg==0 ) runtimeError("out of memory");
953 azCol[nCol-1] = safeId((const char*)sqlite3_column_text(pStmt,1));
954 aiFlg[nCol-1] = i = sqlite3_column_int(pStmt,5);
955 if( i>0 ){
956 if( i>nPk ){
957 nPk = i;
958 aiPk = sqlite3_realloc(aiPk, sizeof(int)*nPk);
959 if( aiPk==0 ) runtimeError("out of memory");
960 }
961 aiPk[i-1] = nCol-1;
962 }
963 }
964 sqlite3_finalize(pStmt);
965 if( nPk==0 ) goto end_changeset_one_table;
966 strInit(&sql);
967 if( nCol>nPk ){
drh697e5db2015-04-11 12:07:40 +0000968 strPrintf(&sql, "SELECT %d", SQLITE_UPDATE);
drh6e42ce42015-04-11 13:48:01 +0000969 for(i=0; i<nCol; i++){
970 if( aiFlg[i] ){
971 strPrintf(&sql, ",\n A.%s", azCol[i]);
972 }else{
973 strPrintf(&sql, ",\n A.%s IS NOT B.%s, A.%s, B.%s",
974 azCol[i], azCol[i], azCol[i], azCol[i]);
975 }
976 }
drh83e63dc2015-04-10 19:41:18 +0000977 strPrintf(&sql,"\n FROM main.%s A, aux.%s B\n", zId, zId);
978 zSep = " WHERE";
979 for(i=0; i<nPk; i++){
980 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
981 zSep = " AND";
982 }
983 zSep = "\n AND (";
984 for(i=0; i<nCol; i++){
985 if( aiFlg[i] ) continue;
986 strPrintf(&sql, "%sA.%s IS NOT B.%s", zSep, azCol[i], azCol[i]);
987 zSep = " OR\n ";
988 }
989 strPrintf(&sql,")\n UNION ALL\n");
990 }
drh697e5db2015-04-11 12:07:40 +0000991 strPrintf(&sql, "SELECT %d", SQLITE_DELETE);
drh6e42ce42015-04-11 13:48:01 +0000992 for(i=0; i<nCol; i++){
993 if( aiFlg[i] ){
994 strPrintf(&sql, ",\n A.%s", azCol[i]);
995 }else{
996 strPrintf(&sql, ",\n 1, A.%s, NULL", azCol[i]);
997 }
998 }
999 strPrintf(&sql, "\n FROM main.%s A\n", zId);
drh83e63dc2015-04-10 19:41:18 +00001000 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B\n", zId);
1001 zSep = " WHERE";
1002 for(i=0; i<nPk; i++){
1003 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1004 zSep = " AND";
1005 }
1006 strPrintf(&sql, ")\n UNION ALL\n");
drh697e5db2015-04-11 12:07:40 +00001007 strPrintf(&sql, "SELECT %d", SQLITE_INSERT);
drh6e42ce42015-04-11 13:48:01 +00001008 for(i=0; i<nCol; i++){
1009 if( aiFlg[i] ){
1010 strPrintf(&sql, ",\n B.%s", azCol[i]);
1011 }else{
1012 strPrintf(&sql, ",\n 1, NULL, B.%s", azCol[i]);
1013 }
1014 }
1015 strPrintf(&sql, "\n FROM aux.%s B\n", zId);
drh83e63dc2015-04-10 19:41:18 +00001016 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A\n", zId);
1017 zSep = " WHERE";
1018 for(i=0; i<nPk; i++){
1019 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1020 zSep = " AND";
1021 }
1022 strPrintf(&sql, ")\n");
1023 strPrintf(&sql, " ORDER BY");
1024 zSep = " ";
1025 for(i=0; i<nPk; i++){
drh6e42ce42015-04-11 13:48:01 +00001026 strPrintf(&sql, "%s %d", zSep, aiPk[i]+2);
drh83e63dc2015-04-10 19:41:18 +00001027 zSep = ",";
1028 }
1029 strPrintf(&sql, ";\n");
1030
drh697e5db2015-04-11 12:07:40 +00001031 if( g.fDebug & DEBUG_DIFF_SQL ){
1032 printf("SQL for %s:\n%s\n", zId, sql.z);
1033 goto end_changeset_one_table;
1034 }
1035
1036 putc('T', out);
1037 putsVarint(out, (sqlite3_uint64)nCol);
1038 for(i=0; i<nCol; i++) putc(aiFlg[i]!=0, out);
1039 fwrite(zTab, 1, strlen(zTab), out);
1040 putc(0, out);
1041
1042 pStmt = db_prepare("%s", sql.z);
1043 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1044 int iType = sqlite3_column_int(pStmt,0);
drh697e5db2015-04-11 12:07:40 +00001045 putc(iType, out);
1046 putc(0, out);
drh6e42ce42015-04-11 13:48:01 +00001047 switch( sqlite3_column_int(pStmt,0) ){
1048 case SQLITE_UPDATE: {
1049 for(k=1, i=0; i<nCol; i++){
1050 if( aiFlg[i] ){
1051 putValue(out, sqlite3_column_value(pStmt,k));
1052 k++;
1053 }else if( sqlite3_column_int(pStmt,k) ){
1054 putValue(out, sqlite3_column_value(pStmt,k+1));
1055 k += 3;
1056 }else{
1057 putc(0, out);
1058 k += 3;
1059 }
1060 }
1061 for(k=1, i=0; i<nCol; i++){
1062 if( aiFlg[i] ){
1063 putc(0, out);
1064 k++;
1065 }else if( sqlite3_column_int(pStmt,k) ){
1066 putValue(out, sqlite3_column_value(pStmt,k+2));
1067 k += 3;
1068 }else{
1069 putc(0, out);
1070 k += 3;
1071 }
1072 }
1073 break;
1074 }
1075 case SQLITE_INSERT: {
1076 for(k=1, i=0; i<nCol; i++){
1077 if( aiFlg[i] ){
1078 putValue(out, sqlite3_column_value(pStmt,k));
1079 k++;
1080 }else{
1081 putValue(out, sqlite3_column_value(pStmt,k+2));
1082 k += 3;
1083 }
1084 }
1085 break;
1086 }
1087 case SQLITE_DELETE: {
1088 for(k=1, i=0; i<nCol; i++){
1089 if( aiFlg[i] ){
1090 putValue(out, sqlite3_column_value(pStmt,k));
1091 k++;
1092 }else{
1093 putValue(out, sqlite3_column_value(pStmt,k+1));
1094 k += 3;
1095 }
1096 }
1097 break;
drh697e5db2015-04-11 12:07:40 +00001098 }
1099 }
1100 }
1101 sqlite3_finalize(pStmt);
drh83e63dc2015-04-10 19:41:18 +00001102
1103end_changeset_one_table:
1104 while( nCol>0 ) sqlite3_free(azCol[--nCol]);
1105 sqlite3_free(azCol);
1106 sqlite3_free(aiPk);
1107 sqlite3_free(zId);
1108}
1109
1110/*
drhd62c0f42015-04-09 13:34:29 +00001111** Print sketchy documentation for this utility program
1112*/
1113static void showHelp(void){
1114 printf("Usage: %s [options] DB1 DB2\n", g.zArgv0);
1115 printf(
1116"Output SQL text that would transform DB1 into DB2.\n"
1117"Options:\n"
drh83e63dc2015-04-10 19:41:18 +00001118" --changeset FILE Write a CHANGESET into FILE\n"
drh9a9219f2015-05-04 13:25:56 +00001119" -L|--lib LIBRARY Load an SQLite extension library\n"
drha37591c2015-04-09 18:14:03 +00001120" --primarykey Use schema-defined PRIMARY KEYs\n"
drhd62c0f42015-04-09 13:34:29 +00001121" --schema Show only differences in the schema\n"
drh8a1cd762015-04-14 19:01:08 +00001122" --summary Show only a summary of the differences\n"
drhd62c0f42015-04-09 13:34:29 +00001123" --table TAB Show only differences in table TAB\n"
1124 );
1125}
1126
1127int main(int argc, char **argv){
1128 const char *zDb1 = 0;
1129 const char *zDb2 = 0;
1130 int i;
1131 int rc;
1132 char *zErrMsg = 0;
1133 char *zSql;
1134 sqlite3_stmt *pStmt;
1135 char *zTab = 0;
drh8a1cd762015-04-14 19:01:08 +00001136 FILE *out = stdout;
1137 void (*xDiff)(const char*,FILE*) = diff_one_table;
drh9a9219f2015-05-04 13:25:56 +00001138 int nExt = 0;
drh33aa4db2015-05-04 15:04:47 +00001139 char **azExt = 0;
drhd62c0f42015-04-09 13:34:29 +00001140
1141 g.zArgv0 = argv[0];
drhaa62e482015-05-12 00:46:40 +00001142 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
drhd62c0f42015-04-09 13:34:29 +00001143 for(i=1; i<argc; i++){
1144 const char *z = argv[i];
1145 if( z[0]=='-' ){
1146 z++;
1147 if( z[0]=='-' ) z++;
drh83e63dc2015-04-10 19:41:18 +00001148 if( strcmp(z,"changeset")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001149 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drh83e63dc2015-04-10 19:41:18 +00001150 out = fopen(argv[++i], "wb");
1151 if( out==0 ) cmdlineError("cannot open: %s", argv[i]);
drh8a1cd762015-04-14 19:01:08 +00001152 xDiff = changeset_one_table;
drh83e63dc2015-04-10 19:41:18 +00001153 }else
drhd62c0f42015-04-09 13:34:29 +00001154 if( strcmp(z,"debug")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001155 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drhd62c0f42015-04-09 13:34:29 +00001156 g.fDebug = strtol(argv[++i], 0, 0);
1157 }else
1158 if( strcmp(z,"help")==0 ){
1159 showHelp();
1160 return 0;
1161 }else
drh9a9219f2015-05-04 13:25:56 +00001162 if( strcmp(z,"lib")==0 || strcmp(z,"L")==0 ){
1163 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
1164 azExt = realloc(azExt, sizeof(azExt[0])*(nExt+1));
1165 if( azExt==0 ) cmdlineError("out of memory");
1166 azExt[nExt++] = argv[++i];
1167 }else
drha37591c2015-04-09 18:14:03 +00001168 if( strcmp(z,"primarykey")==0 ){
1169 g.bSchemaPK = 1;
1170 }else
drhd62c0f42015-04-09 13:34:29 +00001171 if( strcmp(z,"schema")==0 ){
1172 g.bSchemaOnly = 1;
1173 }else
drh8a1cd762015-04-14 19:01:08 +00001174 if( strcmp(z,"summary")==0 ){
1175 xDiff = summarize_one_table;
1176 }else
drhd62c0f42015-04-09 13:34:29 +00001177 if( strcmp(z,"table")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001178 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drhd62c0f42015-04-09 13:34:29 +00001179 zTab = argv[++i];
1180 }else
1181 {
1182 cmdlineError("unknown option: %s", argv[i]);
1183 }
1184 }else if( zDb1==0 ){
1185 zDb1 = argv[i];
1186 }else if( zDb2==0 ){
1187 zDb2 = argv[i];
1188 }else{
1189 cmdlineError("unknown argument: %s", argv[i]);
1190 }
1191 }
1192 if( zDb2==0 ){
1193 cmdlineError("two database arguments required");
1194 }
1195 rc = sqlite3_open(zDb1, &g.db);
1196 if( rc ){
1197 cmdlineError("cannot open database file \"%s\"", zDb1);
1198 }
1199 rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_master", 0, 0, &zErrMsg);
1200 if( rc || zErrMsg ){
1201 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1);
1202 }
drh9a9219f2015-05-04 13:25:56 +00001203 sqlite3_enable_load_extension(g.db, 1);
1204 for(i=0; i<nExt; i++){
1205 rc = sqlite3_load_extension(g.db, azExt[i], 0, &zErrMsg);
1206 if( rc || zErrMsg ){
1207 cmdlineError("error loading %s: %s", azExt[i], zErrMsg);
1208 }
1209 }
1210 free(azExt);
drhd62c0f42015-04-09 13:34:29 +00001211 zSql = sqlite3_mprintf("ATTACH %Q as aux;", zDb2);
1212 rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
1213 if( rc || zErrMsg ){
1214 cmdlineError("cannot attach database \"%s\"", zDb2);
1215 }
1216 rc = sqlite3_exec(g.db, "SELECT * FROM aux.sqlite_master", 0, 0, &zErrMsg);
1217 if( rc || zErrMsg ){
1218 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb2);
1219 }
1220
1221 if( zTab ){
drh8a1cd762015-04-14 19:01:08 +00001222 xDiff(zTab, out);
drhd62c0f42015-04-09 13:34:29 +00001223 }else{
1224 /* Handle tables one by one */
1225 pStmt = db_prepare(
1226 "SELECT name FROM main.sqlite_master\n"
1227 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1228 " UNION\n"
1229 "SELECT name FROM aux.sqlite_master\n"
1230 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1231 " ORDER BY name"
1232 );
1233 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +00001234 xDiff((const char*)sqlite3_column_text(pStmt,0), out);
drhd62c0f42015-04-09 13:34:29 +00001235 }
1236 sqlite3_finalize(pStmt);
1237 }
1238
1239 /* TBD: Handle trigger differences */
1240 /* TBD: Handle view differences */
1241 sqlite3_close(g.db);
1242 return 0;
1243}