| OLD | NEW | 
 | (Empty) | 
|     1 /* |  | 
|     2 ** 2001 September 15 |  | 
|     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 ** This file contains code to implement the "sqlite" command line |  | 
|    13 ** utility for accessing SQLite databases. |  | 
|    14 ** |  | 
|    15 ** $Id: shell.c,v 1.210 2009/05/31 17:16:10 drh Exp $ |  | 
|    16 */ |  | 
|    17 #if defined(_WIN32) || defined(WIN32) |  | 
|    18 /* This needs to come before any includes for MSVC compiler */ |  | 
|    19 #define _CRT_SECURE_NO_WARNINGS |  | 
|    20 #endif |  | 
|    21  |  | 
|    22 #include <stdlib.h> |  | 
|    23 #include <string.h> |  | 
|    24 #include <stdio.h> |  | 
|    25 #include <assert.h> |  | 
|    26 #include "sqlite3.h" |  | 
|    27 #include <ctype.h> |  | 
|    28 #include <stdarg.h> |  | 
|    29  |  | 
|    30 #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) |  | 
|    31 # include <signal.h> |  | 
|    32 # if !defined(__RTP__) && !defined(_WRS_KERNEL) |  | 
|    33 #  include <pwd.h> |  | 
|    34 # endif |  | 
|    35 # include <unistd.h> |  | 
|    36 # include <sys/types.h> |  | 
|    37 #endif |  | 
|    38  |  | 
|    39 #ifdef __OS2__ |  | 
|    40 # include <unistd.h> |  | 
|    41 #endif |  | 
|    42  |  | 
|    43 #if defined(HAVE_READLINE) && HAVE_READLINE==1 |  | 
|    44 # include <readline/readline.h> |  | 
|    45 # include <readline/history.h> |  | 
|    46 #else |  | 
|    47 # define readline(p) local_getline(p,stdin) |  | 
|    48 # define add_history(X) |  | 
|    49 # define read_history(X) |  | 
|    50 # define write_history(X) |  | 
|    51 # define stifle_history(X) |  | 
|    52 #endif |  | 
|    53  |  | 
|    54 #if defined(_WIN32) || defined(WIN32) |  | 
|    55 # include <io.h> |  | 
|    56 #define isatty(h) _isatty(h) |  | 
|    57 #define access(f,m) _access((f),(m)) |  | 
|    58 #else |  | 
|    59 /* Make sure isatty() has a prototype. |  | 
|    60 */ |  | 
|    61 extern int isatty(); |  | 
|    62 #endif |  | 
|    63  |  | 
|    64 #if defined(_WIN32_WCE) |  | 
|    65 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() |  | 
|    66  * thus we always assume that we have a console. That can be |  | 
|    67  * overridden with the -batch command line option. |  | 
|    68  */ |  | 
|    69 #define isatty(x) 1 |  | 
|    70 #endif |  | 
|    71  |  | 
|    72 #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__
      ) && !defined(_WRS_KERNEL) |  | 
|    73 #include <sys/time.h> |  | 
|    74 #include <sys/resource.h> |  | 
|    75  |  | 
|    76 /* Saved resource information for the beginning of an operation */ |  | 
|    77 static struct rusage sBegin; |  | 
|    78  |  | 
|    79 /* True if the timer is enabled */ |  | 
|    80 static int enableTimer = 0; |  | 
|    81  |  | 
|    82 /* |  | 
|    83 ** Begin timing an operation |  | 
|    84 */ |  | 
|    85 static void beginTimer(void){ |  | 
|    86   if( enableTimer ){ |  | 
|    87     getrusage(RUSAGE_SELF, &sBegin); |  | 
|    88   } |  | 
|    89 } |  | 
|    90  |  | 
|    91 /* Return the difference of two time_structs in seconds */ |  | 
|    92 static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ |  | 
|    93   return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +  |  | 
|    94          (double)(pEnd->tv_sec - pStart->tv_sec); |  | 
|    95 } |  | 
|    96  |  | 
|    97 /* |  | 
|    98 ** Print the timing results. |  | 
|    99 */ |  | 
|   100 static void endTimer(void){ |  | 
|   101   if( enableTimer ){ |  | 
|   102     struct rusage sEnd; |  | 
|   103     getrusage(RUSAGE_SELF, &sEnd); |  | 
|   104     printf("CPU Time: user %f sys %f\n", |  | 
|   105        timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), |  | 
|   106        timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); |  | 
|   107   } |  | 
|   108 } |  | 
|   109 #define BEGIN_TIMER beginTimer() |  | 
|   110 #define END_TIMER endTimer() |  | 
|   111 #define HAS_TIMER 1 |  | 
|   112 #else |  | 
|   113 #define BEGIN_TIMER  |  | 
|   114 #define END_TIMER |  | 
|   115 #define HAS_TIMER 0 |  | 
|   116 #endif |  | 
|   117  |  | 
|   118 /* |  | 
|   119 ** Used to prevent warnings about unused parameters |  | 
|   120 */ |  | 
|   121 #define UNUSED_PARAMETER(x) (void)(x) |  | 
|   122  |  | 
|   123  |  | 
|   124 /************************************************************************** |  | 
|   125 *************************************************************************** |  | 
|   126 ** Begin genfkey logic. |  | 
|   127 */ |  | 
|   128 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined SQLITE_OMIT_SUBQUERY |  | 
|   129  |  | 
|   130 #define GENFKEY_ERROR         1 |  | 
|   131 #define GENFKEY_DROPTRIGGER   2 |  | 
|   132 #define GENFKEY_CREATETRIGGER 3 |  | 
|   133 static int genfkey_create_triggers(sqlite3 *, const char *, void *, |  | 
|   134   int (*)(void *, int, const char *) |  | 
|   135 ); |  | 
|   136  |  | 
|   137 struct GenfkeyCb { |  | 
|   138   void *pCtx; |  | 
|   139   int eType; |  | 
|   140   int (*xData)(void *, int, const char *); |  | 
|   141 }; |  | 
|   142 typedef struct GenfkeyCb GenfkeyCb; |  | 
|   143  |  | 
|   144 /* The code in this file defines a sqlite3 virtual-table module that |  | 
|   145 ** provides a read-only view of the current database schema. There is one |  | 
|   146 ** row in the schema table for each column in the database schema. |  | 
|   147 */ |  | 
|   148 #define SCHEMA \ |  | 
|   149 "CREATE TABLE x("                                                            \ |  | 
|   150   "database,"          /* Name of database (i.e. main, temp etc.) */         \ |  | 
|   151   "tablename,"         /* Name of table */                                   \ |  | 
|   152   "cid,"               /* Column number (from left-to-right, 0 upward) */    \ |  | 
|   153   "name,"              /* Column name */                                     \ |  | 
|   154   "type,"              /* Specified type (i.e. VARCHAR(32)) */               \ |  | 
|   155   "not_null,"          /* Boolean. True if NOT NULL was specified */         \ |  | 
|   156   "dflt_value,"        /* Default value for this column */                   \ |  | 
|   157   "pk"                 /* True if this column is part of the primary key */  \ |  | 
|   158 ")" |  | 
|   159  |  | 
|   160 #define SCHEMA2 \ |  | 
|   161 "CREATE TABLE x("                                                            \ |  | 
|   162   "database,"          /* Name of database (i.e. main, temp etc.) */         \ |  | 
|   163   "from_tbl,"          /* Name of table */                                   \ |  | 
|   164   "fkid,"                                                                    \ |  | 
|   165   "seq,"                                                                     \ |  | 
|   166   "to_tbl,"                                                                  \ |  | 
|   167   "from_col,"                                                                \ |  | 
|   168   "to_col,"                                                                  \ |  | 
|   169   "on_update,"                                                               \ |  | 
|   170   "on_delete,"                                                               \ |  | 
|   171   "match"                                                                    \ |  | 
|   172 ")" |  | 
|   173  |  | 
|   174 #define SCHEMA3 \ |  | 
|   175 "CREATE TABLE x("                                                            \ |  | 
|   176   "database,"          /* Name of database (i.e. main, temp etc.) */         \ |  | 
|   177   "tablename,"         /* Name of table */                                   \ |  | 
|   178   "seq,"                                                                     \ |  | 
|   179   "name,"                                                                    \ |  | 
|   180   "isunique"                                                                 \ |  | 
|   181 ")" |  | 
|   182  |  | 
|   183 #define SCHEMA4 \ |  | 
|   184 "CREATE TABLE x("                                                            \ |  | 
|   185   "database,"          /* Name of database (i.e. main, temp etc.) */         \ |  | 
|   186   "indexname,"         /* Name of table */                                   \ |  | 
|   187   "seqno,"                                                                   \ |  | 
|   188   "cid,"                                                                     \ |  | 
|   189   "name"                                                                     \ |  | 
|   190 ")" |  | 
|   191  |  | 
|   192 #define SCHEMA5 \ |  | 
|   193 "CREATE TABLE x("                                                            \ |  | 
|   194   "database,"          /* Name of database (i.e. main, temp etc.) */         \ |  | 
|   195   "triggername,"       /* Name of trigger */                                 \ |  | 
|   196   "dummy"              /* Unused */                                          \ |  | 
|   197 ")" |  | 
|   198  |  | 
|   199 typedef struct SchemaTable SchemaTable; |  | 
|   200 struct SchemaTable { |  | 
|   201   const char *zName; |  | 
|   202   const char *zObject; |  | 
|   203   const char *zPragma; |  | 
|   204   const char *zSchema; |  | 
|   205 } aSchemaTable[] = { |  | 
|   206   { "table_info",       "table", "PRAGMA %Q.table_info(%Q)",       SCHEMA }, |  | 
|   207   { "foreign_key_list", "table", "PRAGMA %Q.foreign_key_list(%Q)", SCHEMA2 }, |  | 
|   208   { "index_list",       "table", "PRAGMA %Q.index_list(%Q)",       SCHEMA3 }, |  | 
|   209   { "index_info",       "index", "PRAGMA %Q.index_info(%Q)",       SCHEMA4 }, |  | 
|   210   { "trigger_list",     "trigger", "SELECT 1",                     SCHEMA5 }, |  | 
|   211   { 0, 0, 0, 0 } |  | 
|   212 }; |  | 
|   213  |  | 
|   214 typedef struct schema_vtab schema_vtab; |  | 
|   215 typedef struct schema_cursor schema_cursor; |  | 
|   216  |  | 
|   217 /* A schema table object */ |  | 
|   218 struct schema_vtab { |  | 
|   219   sqlite3_vtab base; |  | 
|   220   sqlite3 *db; |  | 
|   221   SchemaTable *pType; |  | 
|   222 }; |  | 
|   223  |  | 
|   224 /* A schema table cursor object */ |  | 
|   225 struct schema_cursor { |  | 
|   226   sqlite3_vtab_cursor base; |  | 
|   227   sqlite3_stmt *pDbList; |  | 
|   228   sqlite3_stmt *pTableList; |  | 
|   229   sqlite3_stmt *pColumnList; |  | 
|   230   int rowid; |  | 
|   231 }; |  | 
|   232  |  | 
|   233 /* |  | 
|   234 ** Table destructor for the schema module. |  | 
|   235 */ |  | 
|   236 static int schemaDestroy(sqlite3_vtab *pVtab){ |  | 
|   237   sqlite3_free(pVtab); |  | 
|   238   return 0; |  | 
|   239 } |  | 
|   240  |  | 
|   241 /* |  | 
|   242 ** Table constructor for the schema module. |  | 
|   243 */ |  | 
|   244 static int schemaCreate( |  | 
|   245   sqlite3 *db, |  | 
|   246   void *pAux, |  | 
|   247   int argc, const char *const*argv, |  | 
|   248   sqlite3_vtab **ppVtab, |  | 
|   249   char **pzErr |  | 
|   250 ){ |  | 
|   251   int rc = SQLITE_NOMEM; |  | 
|   252   schema_vtab *pVtab; |  | 
|   253   SchemaTable *pType = &aSchemaTable[0]; |  | 
|   254  |  | 
|   255   UNUSED_PARAMETER(pzErr); |  | 
|   256   if( argc>3 ){ |  | 
|   257     int i; |  | 
|   258     pType = 0; |  | 
|   259     for(i=0; aSchemaTable[i].zName; i++){  |  | 
|   260       if( 0==strcmp(argv[3], aSchemaTable[i].zName) ){ |  | 
|   261         pType = &aSchemaTable[i]; |  | 
|   262       } |  | 
|   263     } |  | 
|   264     if( !pType ){ |  | 
|   265       return SQLITE_ERROR; |  | 
|   266     } |  | 
|   267   } |  | 
|   268  |  | 
|   269   pVtab = sqlite3_malloc(sizeof(schema_vtab)); |  | 
|   270   if( pVtab ){ |  | 
|   271     memset(pVtab, 0, sizeof(schema_vtab)); |  | 
|   272     pVtab->db = (sqlite3 *)pAux; |  | 
|   273     pVtab->pType = pType; |  | 
|   274     rc = sqlite3_declare_vtab(db, pType->zSchema); |  | 
|   275   } |  | 
|   276   *ppVtab = (sqlite3_vtab *)pVtab; |  | 
|   277   return rc; |  | 
|   278 } |  | 
|   279  |  | 
|   280 /* |  | 
|   281 ** Open a new cursor on the schema table. |  | 
|   282 */ |  | 
|   283 static int schemaOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ |  | 
|   284   int rc = SQLITE_NOMEM; |  | 
|   285   schema_cursor *pCur; |  | 
|   286   UNUSED_PARAMETER(pVTab); |  | 
|   287   pCur = sqlite3_malloc(sizeof(schema_cursor)); |  | 
|   288   if( pCur ){ |  | 
|   289     memset(pCur, 0, sizeof(schema_cursor)); |  | 
|   290     *ppCursor = (sqlite3_vtab_cursor *)pCur; |  | 
|   291     rc = SQLITE_OK; |  | 
|   292   } |  | 
|   293   return rc; |  | 
|   294 } |  | 
|   295  |  | 
|   296 /* |  | 
|   297 ** Close a schema table cursor. |  | 
|   298 */ |  | 
|   299 static int schemaClose(sqlite3_vtab_cursor *cur){ |  | 
|   300   schema_cursor *pCur = (schema_cursor *)cur; |  | 
|   301   sqlite3_finalize(pCur->pDbList); |  | 
|   302   sqlite3_finalize(pCur->pTableList); |  | 
|   303   sqlite3_finalize(pCur->pColumnList); |  | 
|   304   sqlite3_free(pCur); |  | 
|   305   return SQLITE_OK; |  | 
|   306 } |  | 
|   307  |  | 
|   308 static void columnToResult(sqlite3_context *ctx, sqlite3_stmt *pStmt, int iCol){ |  | 
|   309   switch( sqlite3_column_type(pStmt, iCol) ){ |  | 
|   310     case SQLITE_NULL: |  | 
|   311       sqlite3_result_null(ctx); |  | 
|   312       break; |  | 
|   313     case SQLITE_INTEGER: |  | 
|   314       sqlite3_result_int64(ctx, sqlite3_column_int64(pStmt, iCol)); |  | 
|   315       break; |  | 
|   316     case SQLITE_FLOAT: |  | 
|   317       sqlite3_result_double(ctx, sqlite3_column_double(pStmt, iCol)); |  | 
|   318       break; |  | 
|   319     case SQLITE_TEXT: { |  | 
|   320       const char *z = (const char *)sqlite3_column_text(pStmt, iCol); |  | 
|   321       sqlite3_result_text(ctx, z, -1, SQLITE_TRANSIENT); |  | 
|   322       break; |  | 
|   323     } |  | 
|   324   } |  | 
|   325 } |  | 
|   326  |  | 
|   327 /* |  | 
|   328 ** Retrieve a column of data. |  | 
|   329 */ |  | 
|   330 static int schemaColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ |  | 
|   331   schema_cursor *pCur = (schema_cursor *)cur; |  | 
|   332   switch( i ){ |  | 
|   333     case 0: |  | 
|   334       columnToResult(ctx, pCur->pDbList, 1); |  | 
|   335       break; |  | 
|   336     case 1: |  | 
|   337       columnToResult(ctx, pCur->pTableList, 0); |  | 
|   338       break; |  | 
|   339     default: |  | 
|   340       columnToResult(ctx, pCur->pColumnList, i-2); |  | 
|   341       break; |  | 
|   342   } |  | 
|   343   return SQLITE_OK; |  | 
|   344 } |  | 
|   345  |  | 
|   346 /* |  | 
|   347 ** Retrieve the current rowid. |  | 
|   348 */ |  | 
|   349 static int schemaRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |  | 
|   350   schema_cursor *pCur = (schema_cursor *)cur; |  | 
|   351   *pRowid = pCur->rowid; |  | 
|   352   return SQLITE_OK; |  | 
|   353 } |  | 
|   354  |  | 
|   355 static int finalize(sqlite3_stmt **ppStmt){ |  | 
|   356   int rc = sqlite3_finalize(*ppStmt); |  | 
|   357   *ppStmt = 0; |  | 
|   358   return rc; |  | 
|   359 } |  | 
|   360  |  | 
|   361 static int schemaEof(sqlite3_vtab_cursor *cur){ |  | 
|   362   schema_cursor *pCur = (schema_cursor *)cur; |  | 
|   363   return (pCur->pDbList ? 0 : 1); |  | 
|   364 } |  | 
|   365  |  | 
|   366 /* |  | 
|   367 ** Advance the cursor to the next row. |  | 
|   368 */ |  | 
|   369 static int schemaNext(sqlite3_vtab_cursor *cur){ |  | 
|   370   int rc = SQLITE_OK; |  | 
|   371   schema_cursor *pCur = (schema_cursor *)cur; |  | 
|   372   schema_vtab *pVtab = (schema_vtab *)(cur->pVtab); |  | 
|   373   char *zSql = 0; |  | 
|   374  |  | 
|   375   while( !pCur->pColumnList || SQLITE_ROW!=sqlite3_step(pCur->pColumnList) ){ |  | 
|   376     if( SQLITE_OK!=(rc = finalize(&pCur->pColumnList)) ) goto next_exit; |  | 
|   377  |  | 
|   378     while( !pCur->pTableList || SQLITE_ROW!=sqlite3_step(pCur->pTableList) ){ |  | 
|   379       if( SQLITE_OK!=(rc = finalize(&pCur->pTableList)) ) goto next_exit; |  | 
|   380  |  | 
|   381       assert(pCur->pDbList); |  | 
|   382       while( SQLITE_ROW!=sqlite3_step(pCur->pDbList) ){ |  | 
|   383         rc = finalize(&pCur->pDbList); |  | 
|   384         goto next_exit; |  | 
|   385       } |  | 
|   386  |  | 
|   387       /* Set zSql to the SQL to pull the list of tables from the  |  | 
|   388       ** sqlite_master (or sqlite_temp_master) table of the database |  | 
|   389       ** identfied by the row pointed to by the SQL statement pCur->pDbList |  | 
|   390       ** (iterating through a "PRAGMA database_list;" statement). |  | 
|   391       */ |  | 
|   392       if( sqlite3_column_int(pCur->pDbList, 0)==1 ){ |  | 
|   393         zSql = sqlite3_mprintf( |  | 
|   394             "SELECT name FROM sqlite_temp_master WHERE type=%Q", |  | 
|   395             pVtab->pType->zObject |  | 
|   396         ); |  | 
|   397       }else{ |  | 
|   398         sqlite3_stmt *pDbList = pCur->pDbList; |  | 
|   399         zSql = sqlite3_mprintf( |  | 
|   400             "SELECT name FROM %Q.sqlite_master WHERE type=%Q", |  | 
|   401              sqlite3_column_text(pDbList, 1), pVtab->pType->zObject |  | 
|   402         ); |  | 
|   403       } |  | 
|   404       if( !zSql ){ |  | 
|   405         rc = SQLITE_NOMEM; |  | 
|   406         goto next_exit; |  | 
|   407       } |  | 
|   408  |  | 
|   409       rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pTableList, 0); |  | 
|   410       sqlite3_free(zSql); |  | 
|   411       if( rc!=SQLITE_OK ) goto next_exit; |  | 
|   412     } |  | 
|   413  |  | 
|   414     /* Set zSql to the SQL to the table_info pragma for the table currently |  | 
|   415     ** identified by the rows pointed to by statements pCur->pDbList and |  | 
|   416     ** pCur->pTableList. |  | 
|   417     */ |  | 
|   418     zSql = sqlite3_mprintf(pVtab->pType->zPragma, |  | 
|   419         sqlite3_column_text(pCur->pDbList, 1), |  | 
|   420         sqlite3_column_text(pCur->pTableList, 0) |  | 
|   421     ); |  | 
|   422  |  | 
|   423     if( !zSql ){ |  | 
|   424       rc = SQLITE_NOMEM; |  | 
|   425       goto next_exit; |  | 
|   426     } |  | 
|   427     rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pColumnList, 0); |  | 
|   428     sqlite3_free(zSql); |  | 
|   429     if( rc!=SQLITE_OK ) goto next_exit; |  | 
|   430   } |  | 
|   431   pCur->rowid++; |  | 
|   432  |  | 
|   433 next_exit: |  | 
|   434   /* TODO: Handle rc */ |  | 
|   435   return rc; |  | 
|   436 } |  | 
|   437  |  | 
|   438 /* |  | 
|   439 ** Reset a schema table cursor. |  | 
|   440 */ |  | 
|   441 static int schemaFilter( |  | 
|   442   sqlite3_vtab_cursor *pVtabCursor,  |  | 
|   443   int idxNum, const char *idxStr, |  | 
|   444   int argc, sqlite3_value **argv |  | 
|   445 ){ |  | 
|   446   int rc; |  | 
|   447   schema_vtab *pVtab = (schema_vtab *)(pVtabCursor->pVtab); |  | 
|   448   schema_cursor *pCur = (schema_cursor *)pVtabCursor; |  | 
|   449   UNUSED_PARAMETER(idxNum); |  | 
|   450   UNUSED_PARAMETER(idxStr); |  | 
|   451   UNUSED_PARAMETER(argc); |  | 
|   452   UNUSED_PARAMETER(argv); |  | 
|   453   pCur->rowid = 0; |  | 
|   454   finalize(&pCur->pTableList); |  | 
|   455   finalize(&pCur->pColumnList); |  | 
|   456   finalize(&pCur->pDbList); |  | 
|   457   rc = sqlite3_prepare(pVtab->db,"SELECT 0, 'main'", -1, &pCur->pDbList, 0); |  | 
|   458   return (rc==SQLITE_OK ? schemaNext(pVtabCursor) : rc); |  | 
|   459 } |  | 
|   460  |  | 
|   461 /* |  | 
|   462 ** Analyse the WHERE condition. |  | 
|   463 */ |  | 
|   464 static int schemaBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ |  | 
|   465   UNUSED_PARAMETER(tab); |  | 
|   466   UNUSED_PARAMETER(pIdxInfo); |  | 
|   467   return SQLITE_OK; |  | 
|   468 } |  | 
|   469  |  | 
|   470 /* |  | 
|   471 ** A virtual table module that merely echos method calls into TCL |  | 
|   472 ** variables. |  | 
|   473 */ |  | 
|   474 static sqlite3_module schemaModule = { |  | 
|   475   0,                           /* iVersion */ |  | 
|   476   schemaCreate, |  | 
|   477   schemaCreate, |  | 
|   478   schemaBestIndex, |  | 
|   479   schemaDestroy, |  | 
|   480   schemaDestroy, |  | 
|   481   schemaOpen,                  /* xOpen - open a cursor */ |  | 
|   482   schemaClose,                 /* xClose - close a cursor */ |  | 
|   483   schemaFilter,                /* xFilter - configure scan constraints */ |  | 
|   484   schemaNext,                  /* xNext - advance a cursor */ |  | 
|   485   schemaEof,                   /* xEof */ |  | 
|   486   schemaColumn,                /* xColumn - read data */ |  | 
|   487   schemaRowid,                 /* xRowid - read data */ |  | 
|   488   0,                           /* xUpdate */ |  | 
|   489   0,                           /* xBegin */ |  | 
|   490   0,                           /* xSync */ |  | 
|   491   0,                           /* xCommit */ |  | 
|   492   0,                           /* xRollback */ |  | 
|   493   0,                           /* xFindMethod */ |  | 
|   494   0,                           /* xRename */ |  | 
|   495 }; |  | 
|   496  |  | 
|   497 /* |  | 
|   498 ** Extension load function. |  | 
|   499 */ |  | 
|   500 static int installSchemaModule(sqlite3 *db, sqlite3 *sdb){ |  | 
|   501   sqlite3_create_module(db, "schema", &schemaModule, (void *)sdb); |  | 
|   502   return 0; |  | 
|   503 } |  | 
|   504  |  | 
|   505 /* |  | 
|   506 **   sj(zValue, zJoin) |  | 
|   507 ** |  | 
|   508 ** The following block contains the implementation of an aggregate  |  | 
|   509 ** function that returns a string. Each time the function is stepped,  |  | 
|   510 ** it appends data to an internal buffer. When the aggregate is finalized, |  | 
|   511 ** the contents of the buffer are returned. |  | 
|   512 ** |  | 
|   513 ** The first time the aggregate is stepped the buffer is set to a copy |  | 
|   514 ** of the first argument. The second time and subsequent times it is |  | 
|   515 ** stepped a copy of the second argument is appended to the buffer, then |  | 
|   516 ** a copy of the first. |  | 
|   517 ** |  | 
|   518 ** Example: |  | 
|   519 ** |  | 
|   520 **   INSERT INTO t1(a) VALUES('1'); |  | 
|   521 **   INSERT INTO t1(a) VALUES('2'); |  | 
|   522 **   INSERT INTO t1(a) VALUES('3'); |  | 
|   523 **   SELECT sj(a, ', ') FROM t1; |  | 
|   524 ** |  | 
|   525 **     =>  "1, 2, 3" |  | 
|   526 ** |  | 
|   527 */ |  | 
|   528 struct StrBuffer { |  | 
|   529   char *zBuf; |  | 
|   530 }; |  | 
|   531 typedef struct StrBuffer StrBuffer; |  | 
|   532 static void joinFinalize(sqlite3_context *context){ |  | 
|   533   StrBuffer *p; |  | 
|   534   p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer)); |  | 
|   535   sqlite3_result_text(context, p->zBuf, -1, SQLITE_TRANSIENT); |  | 
|   536   sqlite3_free(p->zBuf); |  | 
|   537 } |  | 
|   538 static void joinStep( |  | 
|   539   sqlite3_context *context, |  | 
|   540   int argc, |  | 
|   541   sqlite3_value **argv |  | 
|   542 ){ |  | 
|   543   StrBuffer *p; |  | 
|   544   UNUSED_PARAMETER(argc); |  | 
|   545   p = (StrBuffer *)sqlite3_aggregate_context(context, sizeof(StrBuffer)); |  | 
|   546   if( p->zBuf==0 ){ |  | 
|   547     p->zBuf = sqlite3_mprintf("%s", sqlite3_value_text(argv[0])); |  | 
|   548   }else{ |  | 
|   549     char *zTmp = p->zBuf; |  | 
|   550     p->zBuf = sqlite3_mprintf("%s%s%s",  |  | 
|   551         zTmp, sqlite3_value_text(argv[1]), sqlite3_value_text(argv[0]) |  | 
|   552     ); |  | 
|   553     sqlite3_free(zTmp); |  | 
|   554   } |  | 
|   555 } |  | 
|   556  |  | 
|   557 /* |  | 
|   558 **   dq(zString) |  | 
|   559 ** |  | 
|   560 ** This scalar function accepts a single argument and interprets it as |  | 
|   561 ** a text value. The return value is the argument enclosed in double |  | 
|   562 ** quotes. If any double quote characters are present in the argument,  |  | 
|   563 ** these are escaped. |  | 
|   564 ** |  | 
|   565 **   dq('the raven "Nevermore."') == '"the raven ""Nevermore."""' |  | 
|   566 */ |  | 
|   567 static void doublequote( |  | 
|   568   sqlite3_context *context,  |  | 
|   569   int argc,  |  | 
|   570   sqlite3_value **argv |  | 
|   571 ){ |  | 
|   572   int ii; |  | 
|   573   char *zOut; |  | 
|   574   char *zCsr; |  | 
|   575   const char *zIn = (const char *)sqlite3_value_text(argv[0]); |  | 
|   576   int nIn = sqlite3_value_bytes(argv[0]); |  | 
|   577  |  | 
|   578   UNUSED_PARAMETER(argc); |  | 
|   579   zOut = sqlite3_malloc(nIn*2+3); |  | 
|   580   zCsr = zOut; |  | 
|   581   *zCsr++ = '"'; |  | 
|   582   for(ii=0; ii<nIn; ii++){ |  | 
|   583     *zCsr++ = zIn[ii]; |  | 
|   584     if( zIn[ii]=='"' ){ |  | 
|   585       *zCsr++ = '"'; |  | 
|   586     } |  | 
|   587   } |  | 
|   588   *zCsr++ = '"'; |  | 
|   589   *zCsr++ = '\0'; |  | 
|   590  |  | 
|   591   sqlite3_result_text(context, zOut, -1, SQLITE_TRANSIENT); |  | 
|   592   sqlite3_free(zOut); |  | 
|   593 } |  | 
|   594  |  | 
|   595 /* |  | 
|   596 **   multireplace(zString, zSearch1, zReplace1, ...) |  | 
|   597 */ |  | 
|   598 static void multireplace( |  | 
|   599   sqlite3_context *context,  |  | 
|   600   int argc,  |  | 
|   601   sqlite3_value **argv |  | 
|   602 ){ |  | 
|   603   int i = 0; |  | 
|   604   char *zOut = 0; |  | 
|   605   int nOut = 0; |  | 
|   606   int nMalloc = 0; |  | 
|   607   const char *zIn = (const char *)sqlite3_value_text(argv[0]); |  | 
|   608   int nIn = sqlite3_value_bytes(argv[0]); |  | 
|   609  |  | 
|   610   while( i<nIn ){ |  | 
|   611     const char *zCopy = &zIn[i]; |  | 
|   612     int nCopy = 1; |  | 
|   613     int nReplace = 1; |  | 
|   614     int j; |  | 
|   615     for(j=1; j<(argc-1); j+=2){ |  | 
|   616       const char *z = (const char *)sqlite3_value_text(argv[j]); |  | 
|   617       int n = sqlite3_value_bytes(argv[j]); |  | 
|   618       if( n<=(nIn-i) && 0==strncmp(z, zCopy, n) ){ |  | 
|   619         zCopy = (const char *)sqlite3_value_text(argv[j+1]); |  | 
|   620         nCopy = sqlite3_value_bytes(argv[j+1]); |  | 
|   621         nReplace = n; |  | 
|   622         break; |  | 
|   623       } |  | 
|   624     } |  | 
|   625     if( (nOut+nCopy)>nMalloc ){ |  | 
|   626       char *zNew; |  | 
|   627       nMalloc = 16 + (nOut+nCopy)*2; |  | 
|   628       zNew = (char*)sqlite3_realloc(zOut, nMalloc); |  | 
|   629       if( zNew==0 ){ |  | 
|   630         sqlite3_result_error_nomem(context); |  | 
|   631         return; |  | 
|   632       }else{ |  | 
|   633         zOut = zNew; |  | 
|   634       } |  | 
|   635     } |  | 
|   636     assert( nMalloc>=(nOut+nCopy) ); |  | 
|   637     memcpy(&zOut[nOut], zCopy, nCopy); |  | 
|   638     i += nReplace; |  | 
|   639     nOut += nCopy; |  | 
|   640   } |  | 
|   641  |  | 
|   642   sqlite3_result_text(context, zOut, nOut, SQLITE_TRANSIENT); |  | 
|   643   sqlite3_free(zOut); |  | 
|   644 } |  | 
|   645  |  | 
|   646 /* |  | 
|   647 ** A callback for sqlite3_exec() invokes the callback specified by the |  | 
|   648 ** GenfkeyCb structure pointed to by the void* passed as the first argument. |  | 
|   649 */ |  | 
|   650 static int invokeCallback(void *p, int nArg, char **azArg, char **azCol){ |  | 
|   651   GenfkeyCb *pCb = (GenfkeyCb *)p; |  | 
|   652   UNUSED_PARAMETER(nArg); |  | 
|   653   UNUSED_PARAMETER(azCol); |  | 
|   654   return pCb->xData(pCb->pCtx, pCb->eType, azArg[0]); |  | 
|   655 } |  | 
|   656  |  | 
|   657 int detectSchemaProblem( |  | 
|   658   sqlite3 *db,                   /* Database connection */ |  | 
|   659   const char *zMessage,          /* English language error message */ |  | 
|   660   const char *zSql,              /* SQL statement to run */ |  | 
|   661   GenfkeyCb *pCb |  | 
|   662 ){ |  | 
|   663   sqlite3_stmt *pStmt; |  | 
|   664   int rc; |  | 
|   665   rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |  | 
|   666   if( rc!=SQLITE_OK ){ |  | 
|   667     return rc; |  | 
|   668   } |  | 
|   669   while( SQLITE_ROW==sqlite3_step(pStmt) ){ |  | 
|   670     char *zDel; |  | 
|   671     int iFk = sqlite3_column_int(pStmt, 0); |  | 
|   672     const char *zTab = (const char *)sqlite3_column_text(pStmt, 1); |  | 
|   673     zDel = sqlite3_mprintf("Error in table %s: %s", zTab, zMessage); |  | 
|   674     rc = pCb->xData(pCb->pCtx, pCb->eType, zDel); |  | 
|   675     sqlite3_free(zDel); |  | 
|   676     if( rc!=SQLITE_OK ) return rc; |  | 
|   677     zDel = sqlite3_mprintf( |  | 
|   678         "DELETE FROM temp.fkey WHERE from_tbl = %Q AND fkid = %d" |  | 
|   679         , zTab, iFk |  | 
|   680     ); |  | 
|   681     sqlite3_exec(db, zDel, 0, 0, 0); |  | 
|   682     sqlite3_free(zDel); |  | 
|   683   } |  | 
|   684   sqlite3_finalize(pStmt); |  | 
|   685   return SQLITE_OK; |  | 
|   686 } |  | 
|   687  |  | 
|   688 /* |  | 
|   689 ** Create and populate temporary table "fkey". |  | 
|   690 */ |  | 
|   691 static int populateTempTable(sqlite3 *db, GenfkeyCb *pCallback){ |  | 
|   692   int rc; |  | 
|   693    |  | 
|   694   rc = sqlite3_exec(db,  |  | 
|   695       "CREATE VIRTUAL TABLE temp.v_fkey USING schema(foreign_key_list);" |  | 
|   696       "CREATE VIRTUAL TABLE temp.v_col USING schema(table_info);" |  | 
|   697       "CREATE VIRTUAL TABLE temp.v_idxlist USING schema(index_list);" |  | 
|   698       "CREATE VIRTUAL TABLE temp.v_idxinfo USING schema(index_info);" |  | 
|   699       "CREATE VIRTUAL TABLE temp.v_triggers USING schema(trigger_list);" |  | 
|   700       "CREATE TABLE temp.fkey AS " |  | 
|   701         "SELECT from_tbl, to_tbl, fkid, from_col, to_col, on_update, on_delete " |  | 
|   702         "FROM temp.v_fkey WHERE database = 'main';" |  | 
|   703       , 0, 0, 0 |  | 
|   704   ); |  | 
|   705   if( rc!=SQLITE_OK ) return rc; |  | 
|   706  |  | 
|   707   rc = detectSchemaProblem(db, "foreign key columns do not exist", |  | 
|   708     "SELECT fkid, from_tbl " |  | 
|   709     "FROM temp.fkey " |  | 
|   710     "WHERE to_col IS NOT NULL AND NOT EXISTS (SELECT 1 " |  | 
|   711         "FROM temp.v_col WHERE tablename=to_tbl AND name==to_col" |  | 
|   712     ")", pCallback |  | 
|   713   ); |  | 
|   714   if( rc!=SQLITE_OK ) return rc; |  | 
|   715  |  | 
|   716   /* At this point the temp.fkey table is mostly populated. If any foreign |  | 
|   717   ** keys were specified so that they implicitly refer to they primary |  | 
|   718   ** key of the parent table, the "to_col" values of the temp.fkey rows |  | 
|   719   ** are still set to NULL. |  | 
|   720   ** |  | 
|   721   ** This is easily fixed for single column primary keys, but not for |  | 
|   722   ** composites. With a composite primary key, there is no way to reliably |  | 
|   723   ** query sqlite for the order in which the columns that make up the |  | 
|   724   ** composite key were declared i.e. there is no way to tell if the |  | 
|   725   ** schema actually contains "PRIMARY KEY(a, b)" or "PRIMARY KEY(b, a)". |  | 
|   726   ** Therefore, this case is not handled. The following function call |  | 
|   727   ** detects instances of this case. |  | 
|   728   */ |  | 
|   729   rc = detectSchemaProblem(db, "implicit mapping to composite primary key", |  | 
|   730     "SELECT fkid, from_tbl " |  | 
|   731     "FROM temp.fkey " |  | 
|   732     "WHERE to_col IS NULL " |  | 
|   733     "GROUP BY fkid, from_tbl HAVING count(*) > 1", pCallback |  | 
|   734   ); |  | 
|   735   if( rc!=SQLITE_OK ) return rc; |  | 
|   736  |  | 
|   737   /* Detect attempts to implicitly map to the primary key of a table  |  | 
|   738   ** that has no primary key column. |  | 
|   739   */ |  | 
|   740   rc = detectSchemaProblem(db, "implicit mapping to non-existant primary key", |  | 
|   741     "SELECT fkid, from_tbl " |  | 
|   742     "FROM temp.fkey " |  | 
|   743     "WHERE to_col IS NULL AND NOT EXISTS " |  | 
|   744       "(SELECT 1 FROM temp.v_col WHERE pk AND tablename = temp.fkey.to_tbl)" |  | 
|   745     , pCallback |  | 
|   746   ); |  | 
|   747   if( rc!=SQLITE_OK ) return rc; |  | 
|   748  |  | 
|   749   /* Fix all the implicit primary key mappings in the temp.fkey table. */ |  | 
|   750   rc = sqlite3_exec(db,  |  | 
|   751     "UPDATE temp.fkey SET to_col = " |  | 
|   752       "(SELECT name FROM temp.v_col WHERE pk AND tablename=temp.fkey.to_tbl)" |  | 
|   753     " WHERE to_col IS NULL;" |  | 
|   754     , 0, 0, 0 |  | 
|   755   ); |  | 
|   756   if( rc!=SQLITE_OK ) return rc; |  | 
|   757  |  | 
|   758   /* Now check that all all parent keys are either primary keys or  |  | 
|   759   ** subject to a unique constraint. |  | 
|   760   */ |  | 
|   761   rc = sqlite3_exec(db,  |  | 
|   762     "CREATE TABLE temp.idx2 AS SELECT " |  | 
|   763       "il.tablename AS tablename," |  | 
|   764       "ii.indexname AS indexname," |  | 
|   765       "ii.name AS col " |  | 
|   766       "FROM temp.v_idxlist AS il, temp.v_idxinfo AS ii " |  | 
|   767       "WHERE il.isunique AND il.database='main' AND ii.indexname = il.name;" |  | 
|   768     "INSERT INTO temp.idx2 " |  | 
|   769       "SELECT tablename, 'pk', name FROM temp.v_col WHERE pk;" |  | 
|   770  |  | 
|   771     "CREATE TABLE temp.idx AS SELECT " |  | 
|   772       "tablename, indexname, sj(dq(col),',') AS cols " |  | 
|   773       "FROM (SELECT * FROM temp.idx2 ORDER BY col) "  |  | 
|   774       "GROUP BY tablename, indexname;" |  | 
|   775  |  | 
|   776     "CREATE TABLE temp.fkey2 AS SELECT " |  | 
|   777         "fkid, from_tbl, to_tbl, sj(dq(to_col),',') AS cols " |  | 
|   778         "FROM (SELECT * FROM temp.fkey ORDER BY to_col) "  |  | 
|   779         "GROUP BY fkid, from_tbl;" |  | 
|   780  |  | 
|   781     "CREATE TABLE temp.triggers AS SELECT " |  | 
|   782         "triggername FROM temp.v_triggers WHERE database='main' AND " |  | 
|   783         "triggername LIKE 'genfkey%';" |  | 
|   784     , 0, 0, 0 |  | 
|   785   ); |  | 
|   786   if( rc!=SQLITE_OK ) return rc; |  | 
|   787   rc = detectSchemaProblem(db, "foreign key is not unique", |  | 
|   788     "SELECT fkid, from_tbl " |  | 
|   789     "FROM temp.fkey2 " |  | 
|   790     "WHERE NOT EXISTS (SELECT 1 " |  | 
|   791         "FROM temp.idx WHERE tablename=to_tbl AND fkey2.cols==idx.cols" |  | 
|   792     ")", pCallback |  | 
|   793   ); |  | 
|   794   if( rc!=SQLITE_OK ) return rc; |  | 
|   795  |  | 
|   796   return rc; |  | 
|   797 } |  | 
|   798  |  | 
|   799 #define GENFKEY_ERROR         1 |  | 
|   800 #define GENFKEY_DROPTRIGGER   2 |  | 
|   801 #define GENFKEY_CREATETRIGGER 3 |  | 
|   802 static int genfkey_create_triggers( |  | 
|   803   sqlite3 *sdb,                        /* Connection to read schema from */ |  | 
|   804   const char *zDb,                     /* Name of db to read ("main", "temp") */ |  | 
|   805   void *pCtx,                          /* Context pointer to pass to xData */ |  | 
|   806   int (*xData)(void *, int, const char *) |  | 
|   807 ){ |  | 
|   808   const char *zSql = |  | 
|   809     "SELECT multireplace('" |  | 
|   810  |  | 
|   811       "-- Triggers for foreign key mapping:\n" |  | 
|   812       "--\n" |  | 
|   813       "--     /from_readable/ REFERENCES /to_readable/\n" |  | 
|   814       "--     on delete /on_delete/\n" |  | 
|   815       "--     on update /on_update/\n" |  | 
|   816       "--\n" |  | 
|   817  |  | 
|   818       /* The "BEFORE INSERT ON <referencing>" trigger. This trigger's job is to |  | 
|   819       ** throw an exception if the user tries to insert a row into the |  | 
|   820       ** referencing table for which there is no corresponding row in |  | 
|   821       ** the referenced table. |  | 
|   822       */ |  | 
|   823       "CREATE TRIGGER /name/_insert_referencing BEFORE INSERT ON /tbl/ WHEN \n" |  | 
|   824       "    /key_notnull/ AND NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"  |  | 
|   825       "BEGIN\n" |  | 
|   826         "  SELECT RAISE(ABORT, ''constraint failed'');\n" |  | 
|   827       "END;\n" |  | 
|   828  |  | 
|   829       /* The "BEFORE UPDATE ON <referencing>" trigger. This trigger's job  |  | 
|   830       ** is to throw an exception if the user tries to update a row in the |  | 
|   831       ** referencing table causing it to correspond to no row in the |  | 
|   832       ** referenced table. |  | 
|   833       */ |  | 
|   834       "CREATE TRIGGER /name/_update_referencing BEFORE\n" |  | 
|   835       "    UPDATE OF /rkey_list/ ON /tbl/ WHEN \n" |  | 
|   836       "    /key_notnull/ AND \n" |  | 
|   837       "    NOT EXISTS (SELECT 1 FROM /ref/ WHERE /cond1/)\n"  |  | 
|   838       "BEGIN\n" |  | 
|   839         "  SELECT RAISE(ABORT, ''constraint failed'');\n" |  | 
|   840       "END;\n" |  | 
|   841  |  | 
|   842  |  | 
|   843       /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job  |  | 
|   844       ** is to detect when a row is deleted from the referenced table to  |  | 
|   845       ** which rows in the referencing table correspond. The action taken |  | 
|   846       ** depends on the value of the 'ON DELETE' clause. |  | 
|   847       */ |  | 
|   848       "CREATE TRIGGER /name/_delete_referenced BEFORE DELETE ON /ref/ WHEN\n" |  | 
|   849       "    EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n" |  | 
|   850       "BEGIN\n" |  | 
|   851       "  /delete_action/\n" |  | 
|   852       "END;\n" |  | 
|   853  |  | 
|   854       /* The "BEFORE DELETE ON <referenced>" trigger. This trigger's job  |  | 
|   855       ** is to detect when the key columns of a row in the referenced table  |  | 
|   856       ** to which one or more rows in the referencing table correspond are |  | 
|   857       ** updated. The action taken depends on the value of the 'ON UPDATE'  |  | 
|   858       ** clause. |  | 
|   859       */ |  | 
|   860       "CREATE TRIGGER /name/_update_referenced AFTER\n" |  | 
|   861       "    UPDATE OF /fkey_list/ ON /ref/ WHEN \n" |  | 
|   862       "    EXISTS (SELECT 1 FROM /tbl/ WHERE /cond2/)\n" |  | 
|   863       "BEGIN\n" |  | 
|   864       "  /update_action/\n" |  | 
|   865       "END;\n" |  | 
|   866     "'" |  | 
|   867  |  | 
|   868     /* These are used in the SQL comment written above each set of triggers */ |  | 
|   869     ", '/from_readable/',  from_tbl || '(' || sj(from_col, ', ') || ')'" |  | 
|   870     ", '/to_readable/',    to_tbl || '(' || sj(to_col, ', ') || ')'" |  | 
|   871     ", '/on_delete/', on_delete" |  | 
|   872     ", '/on_update/', on_update" |  | 
|   873  |  | 
|   874     ", '/name/',   'genfkey' || min(rowid)" |  | 
|   875     ", '/tbl/',    dq(from_tbl)" |  | 
|   876     ", '/ref/',    dq(to_tbl)" |  | 
|   877     ", '/key_notnull/', sj('new.' || dq(from_col) || ' IS NOT NULL', ' AND ')" |  | 
|   878  |  | 
|   879     ", '/fkey_list/', sj(to_col, ', ')" |  | 
|   880     ", '/rkey_list/', sj(from_col, ', ')" |  | 
|   881  |  | 
|   882     ", '/cond1/',  sj(multireplace('new./from/ == /to/'" |  | 
|   883                    ", '/from/', dq(from_col)" |  | 
|   884                    ", '/to/',   dq(to_col)" |  | 
|   885                    "), ' AND ')" |  | 
|   886     ", '/cond2/',  sj(multireplace('old./to/ == /from/'" |  | 
|   887                    ", '/from/', dq(from_col)" |  | 
|   888                    ", '/to/',   dq(to_col)" |  | 
|   889                    "), ' AND ')" |  | 
|   890  |  | 
|   891     ", '/update_action/', CASE on_update " |  | 
|   892       "WHEN 'SET NULL' THEN " |  | 
|   893         "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' " |  | 
|   894         ", '/setlist/', sj(from_col||' = NULL',', ')" |  | 
|   895         ", '/tbl/',     dq(from_tbl)" |  | 
|   896         ", '/where/',   sj(from_col||' = old.'||dq(to_col),' AND ')" |  | 
|   897         ")" |  | 
|   898       "WHEN 'CASCADE' THEN " |  | 
|   899         "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' " |  | 
|   900         ", '/setlist/', sj(dq(from_col)||' = new.'||dq(to_col),', ')" |  | 
|   901         ", '/tbl/',     dq(from_tbl)" |  | 
|   902         ", '/where/',   sj(dq(from_col)||' = old.'||dq(to_col),' AND ')" |  | 
|   903         ")" |  | 
|   904       "ELSE " |  | 
|   905       "  'SELECT RAISE(ABORT, ''constraint failed'');'" |  | 
|   906       "END " |  | 
|   907  |  | 
|   908     ", '/delete_action/', CASE on_delete " |  | 
|   909       "WHEN 'SET NULL' THEN " |  | 
|   910         "multireplace('UPDATE /tbl/ SET /setlist/ WHERE /where/;' " |  | 
|   911         ", '/setlist/', sj(from_col||' = NULL',', ')" |  | 
|   912         ", '/tbl/',     dq(from_tbl)" |  | 
|   913         ", '/where/',   sj(from_col||' = old.'||dq(to_col),' AND ')" |  | 
|   914         ")" |  | 
|   915       "WHEN 'CASCADE' THEN " |  | 
|   916         "multireplace('DELETE FROM /tbl/ WHERE /where/;' " |  | 
|   917         ", '/tbl/',     dq(from_tbl)" |  | 
|   918         ", '/where/',   sj(dq(from_col)||' = old.'||dq(to_col),' AND ')" |  | 
|   919         ")" |  | 
|   920       "ELSE " |  | 
|   921       "  'SELECT RAISE(ABORT, ''constraint failed'');'" |  | 
|   922       "END " |  | 
|   923  |  | 
|   924     ") FROM temp.fkey " |  | 
|   925     "GROUP BY from_tbl, fkid" |  | 
|   926   ; |  | 
|   927  |  | 
|   928   int rc; |  | 
|   929   const int enc = SQLITE_UTF8; |  | 
|   930   sqlite3 *db = 0; |  | 
|   931  |  | 
|   932   GenfkeyCb cb; |  | 
|   933   cb.xData = xData; |  | 
|   934   cb.pCtx = pCtx; |  | 
|   935  |  | 
|   936   UNUSED_PARAMETER(zDb); |  | 
|   937  |  | 
|   938   /* Open the working database handle. */ |  | 
|   939   rc = sqlite3_open(":memory:", &db); |  | 
|   940   if( rc!=SQLITE_OK ) goto genfkey_exit; |  | 
|   941  |  | 
|   942   /* Create the special scalar and aggregate functions used by this program. */ |  | 
|   943   sqlite3_create_function(db, "dq", 1, enc, 0, doublequote, 0, 0); |  | 
|   944   sqlite3_create_function(db, "multireplace", -1, enc, db, multireplace, 0, 0); |  | 
|   945   sqlite3_create_function(db, "sj", 2, enc, 0, 0, joinStep, joinFinalize); |  | 
|   946  |  | 
|   947   /* Install the "schema" virtual table module */ |  | 
|   948   installSchemaModule(db, sdb); |  | 
|   949  |  | 
|   950   /* Create and populate a temp table with the information required to |  | 
|   951   ** build the foreign key triggers. See function populateTempTable() |  | 
|   952   ** for details. |  | 
|   953   */ |  | 
|   954   cb.eType = GENFKEY_ERROR; |  | 
|   955   rc = populateTempTable(db, &cb); |  | 
|   956   if( rc!=SQLITE_OK ) goto genfkey_exit; |  | 
|   957  |  | 
|   958   /* Unless the --no-drop option was specified, generate DROP TRIGGER |  | 
|   959   ** statements to drop any triggers in the database generated by a |  | 
|   960   ** previous run of this program. |  | 
|   961   */ |  | 
|   962   cb.eType = GENFKEY_DROPTRIGGER; |  | 
|   963   rc = sqlite3_exec(db,  |  | 
|   964     "SELECT 'DROP TRIGGER main.' || dq(triggername) || ';' FROM triggers" |  | 
|   965     ,invokeCallback, (void *)&cb, 0 |  | 
|   966   ); |  | 
|   967   if( rc!=SQLITE_OK ) goto genfkey_exit; |  | 
|   968  |  | 
|   969   /* Run the main query to create the trigger definitions. */ |  | 
|   970   cb.eType = GENFKEY_CREATETRIGGER; |  | 
|   971   rc = sqlite3_exec(db, zSql, invokeCallback, (void *)&cb, 0); |  | 
|   972   if( rc!=SQLITE_OK ) goto genfkey_exit; |  | 
|   973  |  | 
|   974 genfkey_exit: |  | 
|   975   sqlite3_close(db); |  | 
|   976   return rc; |  | 
|   977 } |  | 
|   978  |  | 
|   979  |  | 
|   980 #endif |  | 
|   981 /* End genfkey logic. */ |  | 
|   982 /*************************************************************************/ |  | 
|   983 /*************************************************************************/ |  | 
|   984  |  | 
|   985 /* |  | 
|   986 ** If the following flag is set, then command execution stops |  | 
|   987 ** at an error if we are not interactive. |  | 
|   988 */ |  | 
|   989 static int bail_on_error = 0; |  | 
|   990  |  | 
|   991 /* |  | 
|   992 ** Threat stdin as an interactive input if the following variable |  | 
|   993 ** is true.  Otherwise, assume stdin is connected to a file or pipe. |  | 
|   994 */ |  | 
|   995 static int stdin_is_interactive = 1; |  | 
|   996  |  | 
|   997 /* |  | 
|   998 ** The following is the open SQLite database.  We make a pointer |  | 
|   999 ** to this database a static variable so that it can be accessed |  | 
|  1000 ** by the SIGINT handler to interrupt database processing. |  | 
|  1001 */ |  | 
|  1002 static sqlite3 *db = 0; |  | 
|  1003  |  | 
|  1004 /* |  | 
|  1005 ** True if an interrupt (Control-C) has been received. |  | 
|  1006 */ |  | 
|  1007 static volatile int seenInterrupt = 0; |  | 
|  1008  |  | 
|  1009 /* |  | 
|  1010 ** This is the name of our program. It is set in main(), used |  | 
|  1011 ** in a number of other places, mostly for error messages. |  | 
|  1012 */ |  | 
|  1013 static char *Argv0; |  | 
|  1014  |  | 
|  1015 /* |  | 
|  1016 ** Prompt strings. Initialized in main. Settable with |  | 
|  1017 **   .prompt main continue |  | 
|  1018 */ |  | 
|  1019 static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/ |  | 
|  1020 static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */ |  | 
|  1021  |  | 
|  1022 /* |  | 
|  1023 ** Write I/O traces to the following stream. |  | 
|  1024 */ |  | 
|  1025 #ifdef SQLITE_ENABLE_IOTRACE |  | 
|  1026 static FILE *iotrace = 0; |  | 
|  1027 #endif |  | 
|  1028  |  | 
|  1029 /* |  | 
|  1030 ** This routine works like printf in that its first argument is a |  | 
|  1031 ** format string and subsequent arguments are values to be substituted |  | 
|  1032 ** in place of % fields.  The result of formatting this string |  | 
|  1033 ** is written to iotrace. |  | 
|  1034 */ |  | 
|  1035 #ifdef SQLITE_ENABLE_IOTRACE |  | 
|  1036 static void iotracePrintf(const char *zFormat, ...){ |  | 
|  1037   va_list ap; |  | 
|  1038   char *z; |  | 
|  1039   if( iotrace==0 ) return; |  | 
|  1040   va_start(ap, zFormat); |  | 
|  1041   z = sqlite3_vmprintf(zFormat, ap); |  | 
|  1042   va_end(ap); |  | 
|  1043   fprintf(iotrace, "%s", z); |  | 
|  1044   sqlite3_free(z); |  | 
|  1045 } |  | 
|  1046 #endif |  | 
|  1047  |  | 
|  1048  |  | 
|  1049 /* |  | 
|  1050 ** Determines if a string is a number of not. |  | 
|  1051 */ |  | 
|  1052 static int isNumber(const char *z, int *realnum){ |  | 
|  1053   if( *z=='-' || *z=='+' ) z++; |  | 
|  1054   if( !isdigit(*z) ){ |  | 
|  1055     return 0; |  | 
|  1056   } |  | 
|  1057   z++; |  | 
|  1058   if( realnum ) *realnum = 0; |  | 
|  1059   while( isdigit(*z) ){ z++; } |  | 
|  1060   if( *z=='.' ){ |  | 
|  1061     z++; |  | 
|  1062     if( !isdigit(*z) ) return 0; |  | 
|  1063     while( isdigit(*z) ){ z++; } |  | 
|  1064     if( realnum ) *realnum = 1; |  | 
|  1065   } |  | 
|  1066   if( *z=='e' || *z=='E' ){ |  | 
|  1067     z++; |  | 
|  1068     if( *z=='+' || *z=='-' ) z++; |  | 
|  1069     if( !isdigit(*z) ) return 0; |  | 
|  1070     while( isdigit(*z) ){ z++; } |  | 
|  1071     if( realnum ) *realnum = 1; |  | 
|  1072   } |  | 
|  1073   return *z==0; |  | 
|  1074 } |  | 
|  1075  |  | 
|  1076 /* |  | 
|  1077 ** A global char* and an SQL function to access its current value  |  | 
|  1078 ** from within an SQL statement. This program used to use the  |  | 
|  1079 ** sqlite_exec_printf() API to substitue a string into an SQL statement. |  | 
|  1080 ** The correct way to do this with sqlite3 is to use the bind API, but |  | 
|  1081 ** since the shell is built around the callback paradigm it would be a lot |  | 
|  1082 ** of work. Instead just use this hack, which is quite harmless. |  | 
|  1083 */ |  | 
|  1084 static const char *zShellStatic = 0; |  | 
|  1085 static void shellstaticFunc( |  | 
|  1086   sqlite3_context *context, |  | 
|  1087   int argc, |  | 
|  1088   sqlite3_value **argv |  | 
|  1089 ){ |  | 
|  1090   assert( 0==argc ); |  | 
|  1091   assert( zShellStatic ); |  | 
|  1092   UNUSED_PARAMETER(argc); |  | 
|  1093   UNUSED_PARAMETER(argv); |  | 
|  1094   sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC); |  | 
|  1095 } |  | 
|  1096  |  | 
|  1097  |  | 
|  1098 /* |  | 
|  1099 ** This routine reads a line of text from FILE in, stores |  | 
|  1100 ** the text in memory obtained from malloc() and returns a pointer |  | 
|  1101 ** to the text.  NULL is returned at end of file, or if malloc() |  | 
|  1102 ** fails. |  | 
|  1103 ** |  | 
|  1104 ** The interface is like "readline" but no command-line editing |  | 
|  1105 ** is done. |  | 
|  1106 */ |  | 
|  1107 static char *local_getline(char *zPrompt, FILE *in){ |  | 
|  1108   char *zLine; |  | 
|  1109   int nLine; |  | 
|  1110   int n; |  | 
|  1111   int eol; |  | 
|  1112  |  | 
|  1113   if( zPrompt && *zPrompt ){ |  | 
|  1114     printf("%s",zPrompt); |  | 
|  1115     fflush(stdout); |  | 
|  1116   } |  | 
|  1117   nLine = 100; |  | 
|  1118   zLine = malloc( nLine ); |  | 
|  1119   if( zLine==0 ) return 0; |  | 
|  1120   n = 0; |  | 
|  1121   eol = 0; |  | 
|  1122   while( !eol ){ |  | 
|  1123     if( n+100>nLine ){ |  | 
|  1124       nLine = nLine*2 + 100; |  | 
|  1125       zLine = realloc(zLine, nLine); |  | 
|  1126       if( zLine==0 ) return 0; |  | 
|  1127     } |  | 
|  1128     if( fgets(&zLine[n], nLine - n, in)==0 ){ |  | 
|  1129       if( n==0 ){ |  | 
|  1130         free(zLine); |  | 
|  1131         return 0; |  | 
|  1132       } |  | 
|  1133       zLine[n] = 0; |  | 
|  1134       eol = 1; |  | 
|  1135       break; |  | 
|  1136     } |  | 
|  1137     while( zLine[n] ){ n++; } |  | 
|  1138     if( n>0 && zLine[n-1]=='\n' ){ |  | 
|  1139       n--; |  | 
|  1140       zLine[n] = 0; |  | 
|  1141       eol = 1; |  | 
|  1142     } |  | 
|  1143   } |  | 
|  1144   zLine = realloc( zLine, n+1 ); |  | 
|  1145   return zLine; |  | 
|  1146 } |  | 
|  1147  |  | 
|  1148 /* |  | 
|  1149 ** Retrieve a single line of input text. |  | 
|  1150 ** |  | 
|  1151 ** zPrior is a string of prior text retrieved.  If not the empty |  | 
|  1152 ** string, then issue a continuation prompt. |  | 
|  1153 */ |  | 
|  1154 static char *one_input_line(const char *zPrior, FILE *in){ |  | 
|  1155   char *zPrompt; |  | 
|  1156   char *zResult; |  | 
|  1157   if( in!=0 ){ |  | 
|  1158     return local_getline(0, in); |  | 
|  1159   } |  | 
|  1160   if( zPrior && zPrior[0] ){ |  | 
|  1161     zPrompt = continuePrompt; |  | 
|  1162   }else{ |  | 
|  1163     zPrompt = mainPrompt; |  | 
|  1164   } |  | 
|  1165   zResult = readline(zPrompt); |  | 
|  1166 #if defined(HAVE_READLINE) && HAVE_READLINE==1 |  | 
|  1167   if( zResult && *zResult ) add_history(zResult); |  | 
|  1168 #endif |  | 
|  1169   return zResult; |  | 
|  1170 } |  | 
|  1171  |  | 
|  1172 struct previous_mode_data { |  | 
|  1173   int valid;        /* Is there legit data in here? */ |  | 
|  1174   int mode; |  | 
|  1175   int showHeader; |  | 
|  1176   int colWidth[100]; |  | 
|  1177 }; |  | 
|  1178  |  | 
|  1179 /* |  | 
|  1180 ** An pointer to an instance of this structure is passed from |  | 
|  1181 ** the main program to the callback.  This is used to communicate |  | 
|  1182 ** state and mode information. |  | 
|  1183 */ |  | 
|  1184 struct callback_data { |  | 
|  1185   sqlite3 *db;            /* The database */ |  | 
|  1186   int echoOn;            /* True to echo input commands */ |  | 
|  1187   int cnt;               /* Number of records displayed so far */ |  | 
|  1188   FILE *out;             /* Write results here */ |  | 
|  1189   int mode;              /* An output mode setting */ |  | 
|  1190   int writableSchema;    /* True if PRAGMA writable_schema=ON */ |  | 
|  1191   int showHeader;        /* True to show column names in List or Column mode */ |  | 
|  1192   char *zDestTable;      /* Name of destination table when MODE_Insert */ |  | 
|  1193   char separator[20];    /* Separator character for MODE_List */ |  | 
|  1194   int colWidth[100];     /* Requested width of each column when in column mode*/ |  | 
|  1195   int actualWidth[100];  /* Actual width of each column */ |  | 
|  1196   char nullvalue[20];    /* The text to print when a NULL comes back from |  | 
|  1197                          ** the database */ |  | 
|  1198   struct previous_mode_data explainPrev; |  | 
|  1199                          /* Holds the mode information just before |  | 
|  1200                          ** .explain ON */ |  | 
|  1201   char outfile[FILENAME_MAX]; /* Filename for *out */ |  | 
|  1202   const char *zDbFilename;    /* name of the database file */ |  | 
|  1203 }; |  | 
|  1204  |  | 
|  1205 /* |  | 
|  1206 ** These are the allowed modes. |  | 
|  1207 */ |  | 
|  1208 #define MODE_Line     0  /* One column per line.  Blank line between records */ |  | 
|  1209 #define MODE_Column   1  /* One record per line in neat columns */ |  | 
|  1210 #define MODE_List     2  /* One record per line with a separator */ |  | 
|  1211 #define MODE_Semi     3  /* Same as MODE_List but append ";" to each line */ |  | 
|  1212 #define MODE_Html     4  /* Generate an XHTML table */ |  | 
|  1213 #define MODE_Insert   5  /* Generate SQL "insert" statements */ |  | 
|  1214 #define MODE_Tcl      6  /* Generate ANSI-C or TCL quoted elements */ |  | 
|  1215 #define MODE_Csv      7  /* Quote strings, numbers are plain */ |  | 
|  1216 #define MODE_Explain  8  /* Like MODE_Column, but do not truncate data */ |  | 
|  1217  |  | 
|  1218 static const char *modeDescr[] = { |  | 
|  1219   "line", |  | 
|  1220   "column", |  | 
|  1221   "list", |  | 
|  1222   "semi", |  | 
|  1223   "html", |  | 
|  1224   "insert", |  | 
|  1225   "tcl", |  | 
|  1226   "csv", |  | 
|  1227   "explain", |  | 
|  1228 }; |  | 
|  1229  |  | 
|  1230 /* |  | 
|  1231 ** Number of elements in an array |  | 
|  1232 */ |  | 
|  1233 #define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0])) |  | 
|  1234  |  | 
|  1235 /* |  | 
|  1236 ** Compute a string length that is limited to what can be stored in |  | 
|  1237 ** lower 30 bits of a 32-bit signed integer. |  | 
|  1238 */ |  | 
|  1239 static int strlen30(const char *z){ |  | 
|  1240   const char *z2 = z; |  | 
|  1241   while( *z2 ){ z2++; } |  | 
|  1242   return 0x3fffffff & (int)(z2 - z); |  | 
|  1243 } |  | 
|  1244  |  | 
|  1245 /* |  | 
|  1246 ** Output the given string as a quoted string using SQL quoting conventions. |  | 
|  1247 */ |  | 
|  1248 static void output_quoted_string(FILE *out, const char *z){ |  | 
|  1249   int i; |  | 
|  1250   int nSingle = 0; |  | 
|  1251   for(i=0; z[i]; i++){ |  | 
|  1252     if( z[i]=='\'' ) nSingle++; |  | 
|  1253   } |  | 
|  1254   if( nSingle==0 ){ |  | 
|  1255     fprintf(out,"'%s'",z); |  | 
|  1256   }else{ |  | 
|  1257     fprintf(out,"'"); |  | 
|  1258     while( *z ){ |  | 
|  1259       for(i=0; z[i] && z[i]!='\''; i++){} |  | 
|  1260       if( i==0 ){ |  | 
|  1261         fprintf(out,"''"); |  | 
|  1262         z++; |  | 
|  1263       }else if( z[i]=='\'' ){ |  | 
|  1264         fprintf(out,"%.*s''",i,z); |  | 
|  1265         z += i+1; |  | 
|  1266       }else{ |  | 
|  1267         fprintf(out,"%s",z); |  | 
|  1268         break; |  | 
|  1269       } |  | 
|  1270     } |  | 
|  1271     fprintf(out,"'"); |  | 
|  1272   } |  | 
|  1273 } |  | 
|  1274  |  | 
|  1275 /* |  | 
|  1276 ** Output the given string as a quoted according to C or TCL quoting rules. |  | 
|  1277 */ |  | 
|  1278 static void output_c_string(FILE *out, const char *z){ |  | 
|  1279   unsigned int c; |  | 
|  1280   fputc('"', out); |  | 
|  1281   while( (c = *(z++))!=0 ){ |  | 
|  1282     if( c=='\\' ){ |  | 
|  1283       fputc(c, out); |  | 
|  1284       fputc(c, out); |  | 
|  1285     }else if( c=='\t' ){ |  | 
|  1286       fputc('\\', out); |  | 
|  1287       fputc('t', out); |  | 
|  1288     }else if( c=='\n' ){ |  | 
|  1289       fputc('\\', out); |  | 
|  1290       fputc('n', out); |  | 
|  1291     }else if( c=='\r' ){ |  | 
|  1292       fputc('\\', out); |  | 
|  1293       fputc('r', out); |  | 
|  1294     }else if( !isprint(c) ){ |  | 
|  1295       fprintf(out, "\\%03o", c&0xff); |  | 
|  1296     }else{ |  | 
|  1297       fputc(c, out); |  | 
|  1298     } |  | 
|  1299   } |  | 
|  1300   fputc('"', out); |  | 
|  1301 } |  | 
|  1302  |  | 
|  1303 /* |  | 
|  1304 ** Output the given string with characters that are special to |  | 
|  1305 ** HTML escaped. |  | 
|  1306 */ |  | 
|  1307 static void output_html_string(FILE *out, const char *z){ |  | 
|  1308   int i; |  | 
|  1309   while( *z ){ |  | 
|  1310     for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){} |  | 
|  1311     if( i>0 ){ |  | 
|  1312       fprintf(out,"%.*s",i,z); |  | 
|  1313     } |  | 
|  1314     if( z[i]=='<' ){ |  | 
|  1315       fprintf(out,"<"); |  | 
|  1316     }else if( z[i]=='&' ){ |  | 
|  1317       fprintf(out,"&"); |  | 
|  1318     }else{ |  | 
|  1319       break; |  | 
|  1320     } |  | 
|  1321     z += i + 1; |  | 
|  1322   } |  | 
|  1323 } |  | 
|  1324  |  | 
|  1325 /* |  | 
|  1326 ** If a field contains any character identified by a 1 in the following |  | 
|  1327 ** array, then the string must be quoted for CSV. |  | 
|  1328 */ |  | 
|  1329 static const char needCsvQuote[] = { |  | 
|  1330   1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,    |  | 
|  1331   1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,    |  | 
|  1332   1, 0, 1, 0, 0, 0, 0, 1,   0, 0, 0, 0, 0, 0, 0, 0,  |  | 
|  1333   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  |  | 
|  1334   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  |  | 
|  1335   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  |  | 
|  1336   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,  |  | 
|  1337   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 1,  |  | 
|  1338   1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,    |  | 
|  1339   1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,    |  | 
|  1340   1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,    |  | 
|  1341   1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,    |  | 
|  1342   1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,    |  | 
|  1343   1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,    |  | 
|  1344   1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,    |  | 
|  1345   1, 1, 1, 1, 1, 1, 1, 1,   1, 1, 1, 1, 1, 1, 1, 1,    |  | 
|  1346 }; |  | 
|  1347  |  | 
|  1348 /* |  | 
|  1349 ** Output a single term of CSV.  Actually, p->separator is used for |  | 
|  1350 ** the separator, which may or may not be a comma.  p->nullvalue is |  | 
|  1351 ** the null value.  Strings are quoted using ANSI-C rules.  Numbers |  | 
|  1352 ** appear outside of quotes. |  | 
|  1353 */ |  | 
|  1354 static void output_csv(struct callback_data *p, const char *z, int bSep){ |  | 
|  1355   FILE *out = p->out; |  | 
|  1356   if( z==0 ){ |  | 
|  1357     fprintf(out,"%s",p->nullvalue); |  | 
|  1358   }else{ |  | 
|  1359     int i; |  | 
|  1360     int nSep = strlen30(p->separator); |  | 
|  1361     for(i=0; z[i]; i++){ |  | 
|  1362       if( needCsvQuote[((unsigned char*)z)[i]]  |  | 
|  1363          || (z[i]==p->separator[0] &&  |  | 
|  1364              (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){ |  | 
|  1365         i = 0; |  | 
|  1366         break; |  | 
|  1367       } |  | 
|  1368     } |  | 
|  1369     if( i==0 ){ |  | 
|  1370       putc('"', out); |  | 
|  1371       for(i=0; z[i]; i++){ |  | 
|  1372         if( z[i]=='"' ) putc('"', out); |  | 
|  1373         putc(z[i], out); |  | 
|  1374       } |  | 
|  1375       putc('"', out); |  | 
|  1376     }else{ |  | 
|  1377       fprintf(out, "%s", z); |  | 
|  1378     } |  | 
|  1379   } |  | 
|  1380   if( bSep ){ |  | 
|  1381     fprintf(p->out, "%s", p->separator); |  | 
|  1382   } |  | 
|  1383 } |  | 
|  1384  |  | 
|  1385 #ifdef SIGINT |  | 
|  1386 /* |  | 
|  1387 ** This routine runs when the user presses Ctrl-C |  | 
|  1388 */ |  | 
|  1389 static void interrupt_handler(int NotUsed){ |  | 
|  1390   UNUSED_PARAMETER(NotUsed); |  | 
|  1391   seenInterrupt = 1; |  | 
|  1392   if( db ) sqlite3_interrupt(db); |  | 
|  1393 } |  | 
|  1394 #endif |  | 
|  1395  |  | 
|  1396 /* |  | 
|  1397 ** This is the callback routine that the SQLite library |  | 
|  1398 ** invokes for each row of a query result. |  | 
|  1399 */ |  | 
|  1400 static int callback(void *pArg, int nArg, char **azArg, char **azCol){ |  | 
|  1401   int i; |  | 
|  1402   struct callback_data *p = (struct callback_data*)pArg; |  | 
|  1403   switch( p->mode ){ |  | 
|  1404     case MODE_Line: { |  | 
|  1405       int w = 5; |  | 
|  1406       if( azArg==0 ) break; |  | 
|  1407       for(i=0; i<nArg; i++){ |  | 
|  1408         int len = strlen30(azCol[i] ? azCol[i] : ""); |  | 
|  1409         if( len>w ) w = len; |  | 
|  1410       } |  | 
|  1411       if( p->cnt++>0 ) fprintf(p->out,"\n"); |  | 
|  1412       for(i=0; i<nArg; i++){ |  | 
|  1413         fprintf(p->out,"%*s = %s\n", w, azCol[i], |  | 
|  1414                 azArg[i] ? azArg[i] : p->nullvalue); |  | 
|  1415       } |  | 
|  1416       break; |  | 
|  1417     } |  | 
|  1418     case MODE_Explain: |  | 
|  1419     case MODE_Column: { |  | 
|  1420       if( p->cnt++==0 ){ |  | 
|  1421         for(i=0; i<nArg; i++){ |  | 
|  1422           int w, n; |  | 
|  1423           if( i<ArraySize(p->colWidth) ){ |  | 
|  1424             w = p->colWidth[i]; |  | 
|  1425           }else{ |  | 
|  1426             w = 0; |  | 
|  1427           } |  | 
|  1428           if( w<=0 ){ |  | 
|  1429             w = strlen30(azCol[i] ? azCol[i] : ""); |  | 
|  1430             if( w<10 ) w = 10; |  | 
|  1431             n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue); |  | 
|  1432             if( w<n ) w = n; |  | 
|  1433           } |  | 
|  1434           if( i<ArraySize(p->actualWidth) ){ |  | 
|  1435             p->actualWidth[i] = w; |  | 
|  1436           } |  | 
|  1437           if( p->showHeader ){ |  | 
|  1438             fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": "  "); |  | 
|  1439           } |  | 
|  1440         } |  | 
|  1441         if( p->showHeader ){ |  | 
|  1442           for(i=0; i<nArg; i++){ |  | 
|  1443             int w; |  | 
|  1444             if( i<ArraySize(p->actualWidth) ){ |  | 
|  1445                w = p->actualWidth[i]; |  | 
|  1446             }else{ |  | 
|  1447                w = 10; |  | 
|  1448             } |  | 
|  1449             fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------" |  | 
|  1450                    "----------------------------------------------------------", |  | 
|  1451                     i==nArg-1 ? "\n": "  "); |  | 
|  1452           } |  | 
|  1453         } |  | 
|  1454       } |  | 
|  1455       if( azArg==0 ) break; |  | 
|  1456       for(i=0; i<nArg; i++){ |  | 
|  1457         int w; |  | 
|  1458         if( i<ArraySize(p->actualWidth) ){ |  | 
|  1459            w = p->actualWidth[i]; |  | 
|  1460         }else{ |  | 
|  1461            w = 10; |  | 
|  1462         } |  | 
|  1463         if( p->mode==MODE_Explain && azArg[i] &&  |  | 
|  1464            strlen30(azArg[i])>w ){ |  | 
|  1465           w = strlen30(azArg[i]); |  | 
|  1466         } |  | 
|  1467         fprintf(p->out,"%-*.*s%s",w,w, |  | 
|  1468             azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  "); |  | 
|  1469       } |  | 
|  1470       break; |  | 
|  1471     } |  | 
|  1472     case MODE_Semi: |  | 
|  1473     case MODE_List: { |  | 
|  1474       if( p->cnt++==0 && p->showHeader ){ |  | 
|  1475         for(i=0; i<nArg; i++){ |  | 
|  1476           fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator); |  | 
|  1477         } |  | 
|  1478       } |  | 
|  1479       if( azArg==0 ) break; |  | 
|  1480       for(i=0; i<nArg; i++){ |  | 
|  1481         char *z = azArg[i]; |  | 
|  1482         if( z==0 ) z = p->nullvalue; |  | 
|  1483         fprintf(p->out, "%s", z); |  | 
|  1484         if( i<nArg-1 ){ |  | 
|  1485           fprintf(p->out, "%s", p->separator); |  | 
|  1486         }else if( p->mode==MODE_Semi ){ |  | 
|  1487           fprintf(p->out, ";\n"); |  | 
|  1488         }else{ |  | 
|  1489           fprintf(p->out, "\n"); |  | 
|  1490         } |  | 
|  1491       } |  | 
|  1492       break; |  | 
|  1493     } |  | 
|  1494     case MODE_Html: { |  | 
|  1495       if( p->cnt++==0 && p->showHeader ){ |  | 
|  1496         fprintf(p->out,"<TR>"); |  | 
|  1497         for(i=0; i<nArg; i++){ |  | 
|  1498           fprintf(p->out,"<TH>%s</TH>",azCol[i]); |  | 
|  1499         } |  | 
|  1500         fprintf(p->out,"</TR>\n"); |  | 
|  1501       } |  | 
|  1502       if( azArg==0 ) break; |  | 
|  1503       fprintf(p->out,"<TR>"); |  | 
|  1504       for(i=0; i<nArg; i++){ |  | 
|  1505         fprintf(p->out,"<TD>"); |  | 
|  1506         output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); |  | 
|  1507         fprintf(p->out,"</TD>\n"); |  | 
|  1508       } |  | 
|  1509       fprintf(p->out,"</TR>\n"); |  | 
|  1510       break; |  | 
|  1511     } |  | 
|  1512     case MODE_Tcl: { |  | 
|  1513       if( p->cnt++==0 && p->showHeader ){ |  | 
|  1514         for(i=0; i<nArg; i++){ |  | 
|  1515           output_c_string(p->out,azCol[i] ? azCol[i] : ""); |  | 
|  1516           fprintf(p->out, "%s", p->separator); |  | 
|  1517         } |  | 
|  1518         fprintf(p->out,"\n"); |  | 
|  1519       } |  | 
|  1520       if( azArg==0 ) break; |  | 
|  1521       for(i=0; i<nArg; i++){ |  | 
|  1522         output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue); |  | 
|  1523         fprintf(p->out, "%s", p->separator); |  | 
|  1524       } |  | 
|  1525       fprintf(p->out,"\n"); |  | 
|  1526       break; |  | 
|  1527     } |  | 
|  1528     case MODE_Csv: { |  | 
|  1529       if( p->cnt++==0 && p->showHeader ){ |  | 
|  1530         for(i=0; i<nArg; i++){ |  | 
|  1531           output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |  | 
|  1532         } |  | 
|  1533         fprintf(p->out,"\n"); |  | 
|  1534       } |  | 
|  1535       if( azArg==0 ) break; |  | 
|  1536       for(i=0; i<nArg; i++){ |  | 
|  1537         output_csv(p, azArg[i], i<nArg-1); |  | 
|  1538       } |  | 
|  1539       fprintf(p->out,"\n"); |  | 
|  1540       break; |  | 
|  1541     } |  | 
|  1542     case MODE_Insert: { |  | 
|  1543       if( azArg==0 ) break; |  | 
|  1544       fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable); |  | 
|  1545       for(i=0; i<nArg; i++){ |  | 
|  1546         char *zSep = i>0 ? ",": ""; |  | 
|  1547         if( azArg[i]==0 ){ |  | 
|  1548           fprintf(p->out,"%sNULL",zSep); |  | 
|  1549         }else if( isNumber(azArg[i], 0) ){ |  | 
|  1550           fprintf(p->out,"%s%s",zSep, azArg[i]); |  | 
|  1551         }else{ |  | 
|  1552           if( zSep[0] ) fprintf(p->out,"%s",zSep); |  | 
|  1553           output_quoted_string(p->out, azArg[i]); |  | 
|  1554         } |  | 
|  1555       } |  | 
|  1556       fprintf(p->out,");\n"); |  | 
|  1557       break; |  | 
|  1558     } |  | 
|  1559   } |  | 
|  1560   return 0; |  | 
|  1561 } |  | 
|  1562  |  | 
|  1563 /* |  | 
|  1564 ** Set the destination table field of the callback_data structure to |  | 
|  1565 ** the name of the table given.  Escape any quote characters in the |  | 
|  1566 ** table name. |  | 
|  1567 */ |  | 
|  1568 static void set_table_name(struct callback_data *p, const char *zName){ |  | 
|  1569   int i, n; |  | 
|  1570   int needQuote; |  | 
|  1571   char *z; |  | 
|  1572  |  | 
|  1573   if( p->zDestTable ){ |  | 
|  1574     free(p->zDestTable); |  | 
|  1575     p->zDestTable = 0; |  | 
|  1576   } |  | 
|  1577   if( zName==0 ) return; |  | 
|  1578   needQuote = !isalpha((unsigned char)*zName) && *zName!='_'; |  | 
|  1579   for(i=n=0; zName[i]; i++, n++){ |  | 
|  1580     if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){ |  | 
|  1581       needQuote = 1; |  | 
|  1582       if( zName[i]=='\'' ) n++; |  | 
|  1583     } |  | 
|  1584   } |  | 
|  1585   if( needQuote ) n += 2; |  | 
|  1586   z = p->zDestTable = malloc( n+1 ); |  | 
|  1587   if( z==0 ){ |  | 
|  1588     fprintf(stderr,"Out of memory!\n"); |  | 
|  1589     exit(1); |  | 
|  1590   } |  | 
|  1591   n = 0; |  | 
|  1592   if( needQuote ) z[n++] = '\''; |  | 
|  1593   for(i=0; zName[i]; i++){ |  | 
|  1594     z[n++] = zName[i]; |  | 
|  1595     if( zName[i]=='\'' ) z[n++] = '\''; |  | 
|  1596   } |  | 
|  1597   if( needQuote ) z[n++] = '\''; |  | 
|  1598   z[n] = 0; |  | 
|  1599 } |  | 
|  1600  |  | 
|  1601 /* zIn is either a pointer to a NULL-terminated string in memory obtained |  | 
|  1602 ** from malloc(), or a NULL pointer. The string pointed to by zAppend is |  | 
|  1603 ** added to zIn, and the result returned in memory obtained from malloc(). |  | 
|  1604 ** zIn, if it was not NULL, is freed. |  | 
|  1605 ** |  | 
|  1606 ** If the third argument, quote, is not '\0', then it is used as a  |  | 
|  1607 ** quote character for zAppend. |  | 
|  1608 */ |  | 
|  1609 static char *appendText(char *zIn, char const *zAppend, char quote){ |  | 
|  1610   int len; |  | 
|  1611   int i; |  | 
|  1612   int nAppend = strlen30(zAppend); |  | 
|  1613   int nIn = (zIn?strlen30(zIn):0); |  | 
|  1614  |  | 
|  1615   len = nAppend+nIn+1; |  | 
|  1616   if( quote ){ |  | 
|  1617     len += 2; |  | 
|  1618     for(i=0; i<nAppend; i++){ |  | 
|  1619       if( zAppend[i]==quote ) len++; |  | 
|  1620     } |  | 
|  1621   } |  | 
|  1622  |  | 
|  1623   zIn = (char *)realloc(zIn, len); |  | 
|  1624   if( !zIn ){ |  | 
|  1625     return 0; |  | 
|  1626   } |  | 
|  1627  |  | 
|  1628   if( quote ){ |  | 
|  1629     char *zCsr = &zIn[nIn]; |  | 
|  1630     *zCsr++ = quote; |  | 
|  1631     for(i=0; i<nAppend; i++){ |  | 
|  1632       *zCsr++ = zAppend[i]; |  | 
|  1633       if( zAppend[i]==quote ) *zCsr++ = quote; |  | 
|  1634     } |  | 
|  1635     *zCsr++ = quote; |  | 
|  1636     *zCsr++ = '\0'; |  | 
|  1637     assert( (zCsr-zIn)==len ); |  | 
|  1638   }else{ |  | 
|  1639     memcpy(&zIn[nIn], zAppend, nAppend); |  | 
|  1640     zIn[len-1] = '\0'; |  | 
|  1641   } |  | 
|  1642  |  | 
|  1643   return zIn; |  | 
|  1644 } |  | 
|  1645  |  | 
|  1646  |  | 
|  1647 /* |  | 
|  1648 ** Execute a query statement that has a single result column.  Print |  | 
|  1649 ** that result column on a line by itself with a semicolon terminator. |  | 
|  1650 ** |  | 
|  1651 ** This is used, for example, to show the schema of the database by |  | 
|  1652 ** querying the SQLITE_MASTER table. |  | 
|  1653 */ |  | 
|  1654 static int run_table_dump_query( |  | 
|  1655   FILE *out,              /* Send output here */ |  | 
|  1656   sqlite3 *db,            /* Database to query */ |  | 
|  1657   const char *zSelect,    /* SELECT statement to extract content */ |  | 
|  1658   const char *zFirstRow   /* Print before first row, if not NULL */ |  | 
|  1659 ){ |  | 
|  1660   sqlite3_stmt *pSelect; |  | 
|  1661   int rc; |  | 
|  1662   rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0); |  | 
|  1663   if( rc!=SQLITE_OK || !pSelect ){ |  | 
|  1664     return rc; |  | 
|  1665   } |  | 
|  1666   rc = sqlite3_step(pSelect); |  | 
|  1667   while( rc==SQLITE_ROW ){ |  | 
|  1668     if( zFirstRow ){ |  | 
|  1669       fprintf(out, "%s", zFirstRow); |  | 
|  1670       zFirstRow = 0; |  | 
|  1671     } |  | 
|  1672     fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0)); |  | 
|  1673     rc = sqlite3_step(pSelect); |  | 
|  1674   } |  | 
|  1675   return sqlite3_finalize(pSelect); |  | 
|  1676 } |  | 
|  1677  |  | 
|  1678  |  | 
|  1679 /* |  | 
|  1680 ** This is a different callback routine used for dumping the database. |  | 
|  1681 ** Each row received by this callback consists of a table name, |  | 
|  1682 ** the table type ("index" or "table") and SQL to create the table. |  | 
|  1683 ** This routine should print text sufficient to recreate the table. |  | 
|  1684 */ |  | 
|  1685 static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ |  | 
|  1686   int rc; |  | 
|  1687   const char *zTable; |  | 
|  1688   const char *zType; |  | 
|  1689   const char *zSql; |  | 
|  1690   const char *zPrepStmt = 0; |  | 
|  1691   struct callback_data *p = (struct callback_data *)pArg; |  | 
|  1692  |  | 
|  1693   UNUSED_PARAMETER(azCol); |  | 
|  1694   if( nArg!=3 ) return 1; |  | 
|  1695   zTable = azArg[0]; |  | 
|  1696   zType = azArg[1]; |  | 
|  1697   zSql = azArg[2]; |  | 
|  1698    |  | 
|  1699   if( strcmp(zTable, "sqlite_sequence")==0 ){ |  | 
|  1700     zPrepStmt = "DELETE FROM sqlite_sequence;\n"; |  | 
|  1701   }else if( strcmp(zTable, "sqlite_stat1")==0 ){ |  | 
|  1702     fprintf(p->out, "ANALYZE sqlite_master;\n"); |  | 
|  1703   }else if( strncmp(zTable, "sqlite_", 7)==0 ){ |  | 
|  1704     return 0; |  | 
|  1705   }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ |  | 
|  1706     char *zIns; |  | 
|  1707     if( !p->writableSchema ){ |  | 
|  1708       fprintf(p->out, "PRAGMA writable_schema=ON;\n"); |  | 
|  1709       p->writableSchema = 1; |  | 
|  1710     } |  | 
|  1711     zIns = sqlite3_mprintf( |  | 
|  1712        "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" |  | 
|  1713        "VALUES('table','%q','%q',0,'%q');", |  | 
|  1714        zTable, zTable, zSql); |  | 
|  1715     fprintf(p->out, "%s\n", zIns); |  | 
|  1716     sqlite3_free(zIns); |  | 
|  1717     return 0; |  | 
|  1718   }else{ |  | 
|  1719     fprintf(p->out, "%s;\n", zSql); |  | 
|  1720   } |  | 
|  1721  |  | 
|  1722   if( strcmp(zType, "table")==0 ){ |  | 
|  1723     sqlite3_stmt *pTableInfo = 0; |  | 
|  1724     char *zSelect = 0; |  | 
|  1725     char *zTableInfo = 0; |  | 
|  1726     char *zTmp = 0; |  | 
|  1727     int nRow = 0; |  | 
|  1728     |  | 
|  1729     zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0); |  | 
|  1730     zTableInfo = appendText(zTableInfo, zTable, '"'); |  | 
|  1731     zTableInfo = appendText(zTableInfo, ");", 0); |  | 
|  1732  |  | 
|  1733     rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0); |  | 
|  1734     free(zTableInfo); |  | 
|  1735     if( rc!=SQLITE_OK || !pTableInfo ){ |  | 
|  1736       return 1; |  | 
|  1737     } |  | 
|  1738  |  | 
|  1739     zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0); |  | 
|  1740     zTmp = appendText(zTmp, zTable, '"'); |  | 
|  1741     if( zTmp ){ |  | 
|  1742       zSelect = appendText(zSelect, zTmp, '\''); |  | 
|  1743     } |  | 
|  1744     zSelect = appendText(zSelect, " || ' VALUES(' || ", 0); |  | 
|  1745     rc = sqlite3_step(pTableInfo); |  | 
|  1746     while( rc==SQLITE_ROW ){ |  | 
|  1747       const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1); |  | 
|  1748       zSelect = appendText(zSelect, "quote(", 0); |  | 
|  1749       zSelect = appendText(zSelect, zText, '"'); |  | 
|  1750       rc = sqlite3_step(pTableInfo); |  | 
|  1751       if( rc==SQLITE_ROW ){ |  | 
|  1752         zSelect = appendText(zSelect, ") || ',' || ", 0); |  | 
|  1753       }else{ |  | 
|  1754         zSelect = appendText(zSelect, ") ", 0); |  | 
|  1755       } |  | 
|  1756       nRow++; |  | 
|  1757     } |  | 
|  1758     rc = sqlite3_finalize(pTableInfo); |  | 
|  1759     if( rc!=SQLITE_OK || nRow==0 ){ |  | 
|  1760       free(zSelect); |  | 
|  1761       return 1; |  | 
|  1762     } |  | 
|  1763     zSelect = appendText(zSelect, "|| ')' FROM  ", 0); |  | 
|  1764     zSelect = appendText(zSelect, zTable, '"'); |  | 
|  1765  |  | 
|  1766     rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt); |  | 
|  1767     if( rc==SQLITE_CORRUPT ){ |  | 
|  1768       zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0); |  | 
|  1769       rc = run_table_dump_query(p->out, p->db, zSelect, 0); |  | 
|  1770     } |  | 
|  1771     if( zSelect ) free(zSelect); |  | 
|  1772   } |  | 
|  1773   return 0; |  | 
|  1774 } |  | 
|  1775  |  | 
|  1776 /* |  | 
|  1777 ** Run zQuery.  Use dump_callback() as the callback routine so that |  | 
|  1778 ** the contents of the query are output as SQL statements. |  | 
|  1779 ** |  | 
|  1780 ** If we get a SQLITE_CORRUPT error, rerun the query after appending |  | 
|  1781 ** "ORDER BY rowid DESC" to the end. |  | 
|  1782 */ |  | 
|  1783 static int run_schema_dump_query( |  | 
|  1784   struct callback_data *p,  |  | 
|  1785   const char *zQuery, |  | 
|  1786   char **pzErrMsg |  | 
|  1787 ){ |  | 
|  1788   int rc; |  | 
|  1789   rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg); |  | 
|  1790   if( rc==SQLITE_CORRUPT ){ |  | 
|  1791     char *zQ2; |  | 
|  1792     int len = strlen30(zQuery); |  | 
|  1793     if( pzErrMsg ) sqlite3_free(*pzErrMsg); |  | 
|  1794     zQ2 = malloc( len+100 ); |  | 
|  1795     if( zQ2==0 ) return rc; |  | 
|  1796     sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery); |  | 
|  1797     rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg); |  | 
|  1798     free(zQ2); |  | 
|  1799   } |  | 
|  1800   return rc; |  | 
|  1801 } |  | 
|  1802  |  | 
|  1803 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY) |  | 
|  1804 struct GenfkeyCmd { |  | 
|  1805   sqlite3 *db;                   /* Database handle */ |  | 
|  1806   struct callback_data *pCb;     /* Callback data */ |  | 
|  1807   int isIgnoreErrors;            /* True for --ignore-errors */ |  | 
|  1808   int isExec;                    /* True for --exec */ |  | 
|  1809   int isNoDrop;                  /* True for --no-drop */ |  | 
|  1810   int nErr;                      /* Number of errors seen so far */ |  | 
|  1811 }; |  | 
|  1812 typedef struct GenfkeyCmd GenfkeyCmd; |  | 
|  1813  |  | 
|  1814 static int genfkeyParseArgs(GenfkeyCmd *p, char **azArg, int nArg){ |  | 
|  1815   int ii; |  | 
|  1816   memset(p, 0, sizeof(GenfkeyCmd)); |  | 
|  1817  |  | 
|  1818   for(ii=0; ii<nArg; ii++){ |  | 
|  1819     int n = strlen30(azArg[ii]); |  | 
|  1820  |  | 
|  1821     if( n>2 && n<10 && 0==strncmp(azArg[ii], "--no-drop", n) ){ |  | 
|  1822       p->isNoDrop = 1; |  | 
|  1823     }else if( n>2 && n<16 && 0==strncmp(azArg[ii], "--ignore-errors", n) ){ |  | 
|  1824       p->isIgnoreErrors = 1; |  | 
|  1825     }else if( n>2 && n<7 && 0==strncmp(azArg[ii], "--exec", n) ){ |  | 
|  1826       p->isExec = 1; |  | 
|  1827     }else{ |  | 
|  1828       fprintf(stderr, "unknown option: %s\n", azArg[ii]); |  | 
|  1829       return -1; |  | 
|  1830     } |  | 
|  1831   } |  | 
|  1832  |  | 
|  1833   return SQLITE_OK; |  | 
|  1834 } |  | 
|  1835  |  | 
|  1836 static int genfkeyCmdCb(void *pCtx, int eType, const char *z){ |  | 
|  1837   GenfkeyCmd *p = (GenfkeyCmd *)pCtx; |  | 
|  1838   if( eType==GENFKEY_ERROR && !p->isIgnoreErrors ){ |  | 
|  1839     p->nErr++; |  | 
|  1840     fprintf(stderr, "%s\n", z); |  | 
|  1841   }  |  | 
|  1842  |  | 
|  1843   if( p->nErr==0 && ( |  | 
|  1844         (eType==GENFKEY_CREATETRIGGER) |  | 
|  1845      || (eType==GENFKEY_DROPTRIGGER && !p->isNoDrop) |  | 
|  1846   )){ |  | 
|  1847     if( p->isExec ){ |  | 
|  1848       sqlite3_exec(p->db, z, 0, 0, 0); |  | 
|  1849     }else{ |  | 
|  1850       char *zCol = "sql"; |  | 
|  1851       callback((void *)p->pCb, 1, (char **)&z, (char **)&zCol); |  | 
|  1852     } |  | 
|  1853   } |  | 
|  1854  |  | 
|  1855   return SQLITE_OK; |  | 
|  1856 } |  | 
|  1857 #endif |  | 
|  1858  |  | 
|  1859 /* |  | 
|  1860 ** Text of a help message |  | 
|  1861 */ |  | 
|  1862 static char zHelp[] = |  | 
|  1863   ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n" |  | 
|  1864   ".bail ON|OFF           Stop after hitting an error.  Default OFF\n" |  | 
|  1865   ".databases             List names and files of attached databases\n" |  | 
|  1866   ".dump ?TABLE? ...      Dump the database in an SQL text format\n" |  | 
|  1867   ".echo ON|OFF           Turn command echo on or off\n" |  | 
|  1868   ".exit                  Exit this program\n" |  | 
|  1869   ".explain ON|OFF        Turn output mode suitable for EXPLAIN on or off.\n" |  | 
|  1870 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY) |  | 
|  1871   ".genfkey ?OPTIONS?     Options are:\n" |  | 
|  1872   "                         --no-drop: Do not drop old fkey triggers.\n" |  | 
|  1873   "                         --ignore-errors: Ignore tables with fkey errors\n" |  | 
|  1874   "                         --exec: Execute generated SQL immediately\n" |  | 
|  1875   "                       See file tool/genfkey.README in the source \n" |  | 
|  1876   "                       distribution for further information.\n" |  | 
|  1877 #endif |  | 
|  1878   ".header(s) ON|OFF      Turn display of headers on or off\n" |  | 
|  1879   ".help                  Show this message\n" |  | 
|  1880   ".import FILE TABLE     Import data from FILE into TABLE\n" |  | 
|  1881   ".indices TABLE         Show names of all indices on TABLE\n" |  | 
|  1882 #ifdef SQLITE_ENABLE_IOTRACE |  | 
|  1883   ".iotrace FILE          Enable I/O diagnostic logging to FILE\n" |  | 
|  1884 #endif |  | 
|  1885 #ifndef SQLITE_OMIT_LOAD_EXTENSION |  | 
|  1886   ".load FILE ?ENTRY?     Load an extension library\n" |  | 
|  1887 #endif |  | 
|  1888   ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n" |  | 
|  1889   "                         csv      Comma-separated values\n" |  | 
|  1890   "                         column   Left-aligned columns.  (See .width)\n" |  | 
|  1891   "                         html     HTML <table> code\n" |  | 
|  1892   "                         insert   SQL insert statements for TABLE\n" |  | 
|  1893   "                         line     One value per line\n" |  | 
|  1894   "                         list     Values delimited by .separator string\n" |  | 
|  1895   "                         tabs     Tab-separated values\n" |  | 
|  1896   "                         tcl      TCL list elements\n" |  | 
|  1897   ".nullvalue STRING      Print STRING in place of NULL values\n" |  | 
|  1898   ".output FILENAME       Send output to FILENAME\n" |  | 
|  1899   ".output stdout         Send output to the screen\n" |  | 
|  1900   ".prompt MAIN CONTINUE  Replace the standard prompts\n" |  | 
|  1901   ".quit                  Exit this program\n" |  | 
|  1902   ".read FILENAME         Execute SQL in FILENAME\n" |  | 
|  1903   ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n" |  | 
|  1904   ".schema ?TABLE?        Show the CREATE statements\n" |  | 
|  1905   ".separator STRING      Change separator used by output mode and .import\n" |  | 
|  1906   ".show                  Show the current values for various settings\n" |  | 
|  1907   ".tables ?PATTERN?      List names of tables matching a LIKE pattern\n" |  | 
|  1908   ".timeout MS            Try opening locked tables for MS milliseconds\n" |  | 
|  1909 #if HAS_TIMER |  | 
|  1910   ".timer ON|OFF          Turn the CPU timer measurement on or off\n" |  | 
|  1911 #endif |  | 
|  1912   ".width NUM NUM ...     Set column widths for \"column\" mode\n" |  | 
|  1913 ; |  | 
|  1914  |  | 
|  1915 /* Forward reference */ |  | 
|  1916 static int process_input(struct callback_data *p, FILE *in); |  | 
|  1917  |  | 
|  1918 /* |  | 
|  1919 ** Make sure the database is open.  If it is not, then open it.  If |  | 
|  1920 ** the database fails to open, print an error message and exit. |  | 
|  1921 */ |  | 
|  1922 static void open_db(struct callback_data *p){ |  | 
|  1923   if( p->db==0 ){ |  | 
|  1924     sqlite3_open(p->zDbFilename, &p->db); |  | 
|  1925     db = p->db; |  | 
|  1926     if( db && sqlite3_errcode(db)==SQLITE_OK ){ |  | 
|  1927       sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0, |  | 
|  1928           shellstaticFunc, 0, 0); |  | 
|  1929     } |  | 
|  1930     if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){ |  | 
|  1931       fprintf(stderr,"Unable to open database \"%s\": %s\n",  |  | 
|  1932           p->zDbFilename, sqlite3_errmsg(db)); |  | 
|  1933       exit(1); |  | 
|  1934     } |  | 
|  1935 #ifndef SQLITE_OMIT_LOAD_EXTENSION |  | 
|  1936     sqlite3_enable_load_extension(p->db, 1); |  | 
|  1937 #endif |  | 
|  1938   } |  | 
|  1939 } |  | 
|  1940  |  | 
|  1941 /* |  | 
|  1942 ** Do C-language style dequoting. |  | 
|  1943 ** |  | 
|  1944 **    \t    -> tab |  | 
|  1945 **    \n    -> newline |  | 
|  1946 **    \r    -> carriage return |  | 
|  1947 **    \NNN  -> ascii character NNN in octal |  | 
|  1948 **    \\    -> backslash |  | 
|  1949 */ |  | 
|  1950 static void resolve_backslashes(char *z){ |  | 
|  1951   int i, j; |  | 
|  1952   char c; |  | 
|  1953   for(i=j=0; (c = z[i])!=0; i++, j++){ |  | 
|  1954     if( c=='\\' ){ |  | 
|  1955       c = z[++i]; |  | 
|  1956       if( c=='n' ){ |  | 
|  1957         c = '\n'; |  | 
|  1958       }else if( c=='t' ){ |  | 
|  1959         c = '\t'; |  | 
|  1960       }else if( c=='r' ){ |  | 
|  1961         c = '\r'; |  | 
|  1962       }else if( c>='0' && c<='7' ){ |  | 
|  1963         c -= '0'; |  | 
|  1964         if( z[i+1]>='0' && z[i+1]<='7' ){ |  | 
|  1965           i++; |  | 
|  1966           c = (c<<3) + z[i] - '0'; |  | 
|  1967           if( z[i+1]>='0' && z[i+1]<='7' ){ |  | 
|  1968             i++; |  | 
|  1969             c = (c<<3) + z[i] - '0'; |  | 
|  1970           } |  | 
|  1971         } |  | 
|  1972       } |  | 
|  1973     } |  | 
|  1974     z[j] = c; |  | 
|  1975   } |  | 
|  1976   z[j] = 0; |  | 
|  1977 } |  | 
|  1978  |  | 
|  1979 /* |  | 
|  1980 ** Interpret zArg as a boolean value.  Return either 0 or 1. |  | 
|  1981 */ |  | 
|  1982 static int booleanValue(char *zArg){ |  | 
|  1983   int val = atoi(zArg); |  | 
|  1984   int j; |  | 
|  1985   for(j=0; zArg[j]; j++){ |  | 
|  1986     zArg[j] = (char)tolower(zArg[j]); |  | 
|  1987   } |  | 
|  1988   if( strcmp(zArg,"on")==0 ){ |  | 
|  1989     val = 1; |  | 
|  1990   }else if( strcmp(zArg,"yes")==0 ){ |  | 
|  1991     val = 1; |  | 
|  1992   } |  | 
|  1993   return val; |  | 
|  1994 } |  | 
|  1995  |  | 
|  1996 /* |  | 
|  1997 ** If an input line begins with "." then invoke this routine to |  | 
|  1998 ** process that line. |  | 
|  1999 ** |  | 
|  2000 ** Return 1 on error, 2 to exit, and 0 otherwise. |  | 
|  2001 */ |  | 
|  2002 static int do_meta_command(char *zLine, struct callback_data *p){ |  | 
|  2003   int i = 1; |  | 
|  2004   int nArg = 0; |  | 
|  2005   int n, c; |  | 
|  2006   int rc = 0; |  | 
|  2007   char *azArg[50]; |  | 
|  2008  |  | 
|  2009   /* Parse the input line into tokens. |  | 
|  2010   */ |  | 
|  2011   while( zLine[i] && nArg<ArraySize(azArg) ){ |  | 
|  2012     while( isspace((unsigned char)zLine[i]) ){ i++; } |  | 
|  2013     if( zLine[i]==0 ) break; |  | 
|  2014     if( zLine[i]=='\'' || zLine[i]=='"' ){ |  | 
|  2015       int delim = zLine[i++]; |  | 
|  2016       azArg[nArg++] = &zLine[i]; |  | 
|  2017       while( zLine[i] && zLine[i]!=delim ){ i++; } |  | 
|  2018       if( zLine[i]==delim ){ |  | 
|  2019         zLine[i++] = 0; |  | 
|  2020       } |  | 
|  2021       if( delim=='"' ) resolve_backslashes(azArg[nArg-1]); |  | 
|  2022     }else{ |  | 
|  2023       azArg[nArg++] = &zLine[i]; |  | 
|  2024       while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; } |  | 
|  2025       if( zLine[i] ) zLine[i++] = 0; |  | 
|  2026       resolve_backslashes(azArg[nArg-1]); |  | 
|  2027     } |  | 
|  2028   } |  | 
|  2029  |  | 
|  2030   /* Process the input line. |  | 
|  2031   */ |  | 
|  2032   if( nArg==0 ) return rc; |  | 
|  2033   n = strlen30(azArg[0]); |  | 
|  2034   c = azArg[0][0]; |  | 
|  2035   if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 ){ |  | 
|  2036     const char *zDestFile; |  | 
|  2037     const char *zDb; |  | 
|  2038     sqlite3 *pDest; |  | 
|  2039     sqlite3_backup *pBackup; |  | 
|  2040     int rc; |  | 
|  2041     if( nArg==2 ){ |  | 
|  2042       zDestFile = azArg[1]; |  | 
|  2043       zDb = "main"; |  | 
|  2044     }else{ |  | 
|  2045       zDestFile = azArg[2]; |  | 
|  2046       zDb = azArg[1]; |  | 
|  2047     } |  | 
|  2048     rc = sqlite3_open(zDestFile, &pDest); |  | 
|  2049     if( rc!=SQLITE_OK ){ |  | 
|  2050       fprintf(stderr, "Error: cannot open %s\n", zDestFile); |  | 
|  2051       sqlite3_close(pDest); |  | 
|  2052       return 1; |  | 
|  2053     } |  | 
|  2054     open_db(p); |  | 
|  2055     pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb); |  | 
|  2056     if( pBackup==0 ){ |  | 
|  2057       fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); |  | 
|  2058       sqlite3_close(pDest); |  | 
|  2059       return 1; |  | 
|  2060     } |  | 
|  2061     while(  (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} |  | 
|  2062     sqlite3_backup_finish(pBackup); |  | 
|  2063     if( rc==SQLITE_DONE ){ |  | 
|  2064       rc = SQLITE_OK; |  | 
|  2065     }else{ |  | 
|  2066       fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest)); |  | 
|  2067     } |  | 
|  2068     sqlite3_close(pDest); |  | 
|  2069   }else |  | 
|  2070  |  | 
|  2071   if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 ){ |  | 
|  2072     bail_on_error = booleanValue(azArg[1]); |  | 
|  2073   }else |  | 
|  2074  |  | 
|  2075   if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){ |  | 
|  2076     struct callback_data data; |  | 
|  2077     char *zErrMsg = 0; |  | 
|  2078     open_db(p); |  | 
|  2079     memcpy(&data, p, sizeof(data)); |  | 
|  2080     data.showHeader = 1; |  | 
|  2081     data.mode = MODE_Column; |  | 
|  2082     data.colWidth[0] = 3; |  | 
|  2083     data.colWidth[1] = 15; |  | 
|  2084     data.colWidth[2] = 58; |  | 
|  2085     data.cnt = 0; |  | 
|  2086     sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); |  | 
|  2087     if( zErrMsg ){ |  | 
|  2088       fprintf(stderr,"Error: %s\n", zErrMsg); |  | 
|  2089       sqlite3_free(zErrMsg); |  | 
|  2090     } |  | 
|  2091   }else |  | 
|  2092  |  | 
|  2093   if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ |  | 
|  2094     char *zErrMsg = 0; |  | 
|  2095     open_db(p); |  | 
|  2096     fprintf(p->out, "BEGIN TRANSACTION;\n"); |  | 
|  2097     p->writableSchema = 0; |  | 
|  2098     sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0); |  | 
|  2099     if( nArg==1 ){ |  | 
|  2100       run_schema_dump_query(p,  |  | 
|  2101         "SELECT name, type, sql FROM sqlite_master " |  | 
|  2102         "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0 |  | 
|  2103       ); |  | 
|  2104       run_schema_dump_query(p,  |  | 
|  2105         "SELECT name, type, sql FROM sqlite_master " |  | 
|  2106         "WHERE name=='sqlite_sequence'", 0 |  | 
|  2107       ); |  | 
|  2108       run_table_dump_query(p->out, p->db, |  | 
|  2109         "SELECT sql FROM sqlite_master " |  | 
|  2110         "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 |  | 
|  2111       ); |  | 
|  2112     }else{ |  | 
|  2113       int i; |  | 
|  2114       for(i=1; i<nArg; i++){ |  | 
|  2115         zShellStatic = azArg[i]; |  | 
|  2116         run_schema_dump_query(p, |  | 
|  2117           "SELECT name, type, sql FROM sqlite_master " |  | 
|  2118           "WHERE tbl_name LIKE shellstatic() AND type=='table'" |  | 
|  2119           "  AND sql NOT NULL", 0); |  | 
|  2120         run_table_dump_query(p->out, p->db, |  | 
|  2121           "SELECT sql FROM sqlite_master " |  | 
|  2122           "WHERE sql NOT NULL" |  | 
|  2123           "  AND type IN ('index','trigger','view')" |  | 
|  2124           "  AND tbl_name LIKE shellstatic()", 0 |  | 
|  2125         ); |  | 
|  2126         zShellStatic = 0; |  | 
|  2127       } |  | 
|  2128     } |  | 
|  2129     if( p->writableSchema ){ |  | 
|  2130       fprintf(p->out, "PRAGMA writable_schema=OFF;\n"); |  | 
|  2131       p->writableSchema = 0; |  | 
|  2132     } |  | 
|  2133     sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0); |  | 
|  2134     if( zErrMsg ){ |  | 
|  2135       fprintf(stderr,"Error: %s\n", zErrMsg); |  | 
|  2136       sqlite3_free(zErrMsg); |  | 
|  2137     }else{ |  | 
|  2138       fprintf(p->out, "COMMIT;\n"); |  | 
|  2139     } |  | 
|  2140   }else |  | 
|  2141  |  | 
|  2142   if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){ |  | 
|  2143     p->echoOn = booleanValue(azArg[1]); |  | 
|  2144   }else |  | 
|  2145  |  | 
|  2146   if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ |  | 
|  2147     rc = 2; |  | 
|  2148   }else |  | 
|  2149  |  | 
|  2150   if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){ |  | 
|  2151     int val = nArg>=2 ? booleanValue(azArg[1]) : 1; |  | 
|  2152     if(val == 1) { |  | 
|  2153       if(!p->explainPrev.valid) { |  | 
|  2154         p->explainPrev.valid = 1; |  | 
|  2155         p->explainPrev.mode = p->mode; |  | 
|  2156         p->explainPrev.showHeader = p->showHeader; |  | 
|  2157         memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth)); |  | 
|  2158       } |  | 
|  2159       /* We could put this code under the !p->explainValid |  | 
|  2160       ** condition so that it does not execute if we are already in |  | 
|  2161       ** explain mode. However, always executing it allows us an easy |  | 
|  2162       ** was to reset to explain mode in case the user previously |  | 
|  2163       ** did an .explain followed by a .width, .mode or .header |  | 
|  2164       ** command. |  | 
|  2165       */ |  | 
|  2166       p->mode = MODE_Explain; |  | 
|  2167       p->showHeader = 1; |  | 
|  2168       memset(p->colWidth,0,ArraySize(p->colWidth)); |  | 
|  2169       p->colWidth[0] = 4;                  /* addr */ |  | 
|  2170       p->colWidth[1] = 13;                 /* opcode */ |  | 
|  2171       p->colWidth[2] = 4;                  /* P1 */ |  | 
|  2172       p->colWidth[3] = 4;                  /* P2 */ |  | 
|  2173       p->colWidth[4] = 4;                  /* P3 */ |  | 
|  2174       p->colWidth[5] = 13;                 /* P4 */ |  | 
|  2175       p->colWidth[6] = 2;                  /* P5 */ |  | 
|  2176       p->colWidth[7] = 13;                  /* Comment */ |  | 
|  2177     }else if (p->explainPrev.valid) { |  | 
|  2178       p->explainPrev.valid = 0; |  | 
|  2179       p->mode = p->explainPrev.mode; |  | 
|  2180       p->showHeader = p->explainPrev.showHeader; |  | 
|  2181       memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth)); |  | 
|  2182     } |  | 
|  2183   }else |  | 
|  2184  |  | 
|  2185 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_SUBQUERY) |  | 
|  2186   if( c=='g' && strncmp(azArg[0], "genfkey", n)==0 ){ |  | 
|  2187     GenfkeyCmd cmd; |  | 
|  2188     if( 0==genfkeyParseArgs(&cmd, &azArg[1], nArg-1) ){ |  | 
|  2189       cmd.db = p->db; |  | 
|  2190       cmd.pCb = p; |  | 
|  2191       genfkey_create_triggers(p->db, "main", (void *)&cmd, genfkeyCmdCb); |  | 
|  2192     } |  | 
|  2193   }else |  | 
|  2194 #endif |  | 
|  2195  |  | 
|  2196   if( c=='h' && (strncmp(azArg[0], "header", n)==0 || |  | 
|  2197                  strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){ |  | 
|  2198     p->showHeader = booleanValue(azArg[1]); |  | 
|  2199   }else |  | 
|  2200  |  | 
|  2201   if( c=='h' && strncmp(azArg[0], "help", n)==0 ){ |  | 
|  2202     fprintf(stderr,"%s",zHelp); |  | 
|  2203   }else |  | 
|  2204  |  | 
|  2205   if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg>=3 ){ |  | 
|  2206     char *zTable = azArg[2];    /* Insert data into this table */ |  | 
|  2207     char *zFile = azArg[1];     /* The file from which to extract data */ |  | 
|  2208     sqlite3_stmt *pStmt;        /* A statement */ |  | 
|  2209     int rc;                     /* Result code */ |  | 
|  2210     int nCol;                   /* Number of columns in the table */ |  | 
|  2211     int nByte;                  /* Number of bytes in an SQL string */ |  | 
|  2212     int i, j;                   /* Loop counters */ |  | 
|  2213     int nSep;                   /* Number of bytes in p->separator[] */ |  | 
|  2214     char *zSql;                 /* An SQL statement */ |  | 
|  2215     char *zLine;                /* A single line of input from the file */ |  | 
|  2216     char **azCol;               /* zLine[] broken up into columns */ |  | 
|  2217     char *zCommit;              /* How to commit changes */    |  | 
|  2218     FILE *in;                   /* The input file */ |  | 
|  2219     int lineno = 0;             /* Line number of input file */ |  | 
|  2220  |  | 
|  2221     open_db(p); |  | 
|  2222     nSep = strlen30(p->separator); |  | 
|  2223     if( nSep==0 ){ |  | 
|  2224       fprintf(stderr, "non-null separator required for import\n"); |  | 
|  2225       return 0; |  | 
|  2226     } |  | 
|  2227     zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); |  | 
|  2228     if( zSql==0 ) return 0; |  | 
|  2229     nByte = strlen30(zSql); |  | 
|  2230     rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); |  | 
|  2231     sqlite3_free(zSql); |  | 
|  2232     if( rc ){ |  | 
|  2233       fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); |  | 
|  2234       nCol = 0; |  | 
|  2235       rc = 1; |  | 
|  2236     }else{ |  | 
|  2237       nCol = sqlite3_column_count(pStmt); |  | 
|  2238     } |  | 
|  2239     sqlite3_finalize(pStmt); |  | 
|  2240     if( nCol==0 ) return 0; |  | 
|  2241     zSql = malloc( nByte + 20 + nCol*2 ); |  | 
|  2242     if( zSql==0 ) return 0; |  | 
|  2243     sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable); |  | 
|  2244     j = strlen30(zSql); |  | 
|  2245     for(i=1; i<nCol; i++){ |  | 
|  2246       zSql[j++] = ','; |  | 
|  2247       zSql[j++] = '?'; |  | 
|  2248     } |  | 
|  2249     zSql[j++] = ')'; |  | 
|  2250     zSql[j] = 0; |  | 
|  2251     rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); |  | 
|  2252     free(zSql); |  | 
|  2253     if( rc ){ |  | 
|  2254       fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); |  | 
|  2255       sqlite3_finalize(pStmt); |  | 
|  2256       return 1; |  | 
|  2257     } |  | 
|  2258     in = fopen(zFile, "rb"); |  | 
|  2259     if( in==0 ){ |  | 
|  2260       fprintf(stderr, "cannot open file: %s\n", zFile); |  | 
|  2261       sqlite3_finalize(pStmt); |  | 
|  2262       return 0; |  | 
|  2263     } |  | 
|  2264     azCol = malloc( sizeof(azCol[0])*(nCol+1) ); |  | 
|  2265     if( azCol==0 ){ |  | 
|  2266       fclose(in); |  | 
|  2267       return 0; |  | 
|  2268     } |  | 
|  2269     sqlite3_exec(p->db, "BEGIN", 0, 0, 0); |  | 
|  2270     zCommit = "COMMIT"; |  | 
|  2271     while( (zLine = local_getline(0, in))!=0 ){ |  | 
|  2272       char *z; |  | 
|  2273       i = 0; |  | 
|  2274       lineno++; |  | 
|  2275       azCol[0] = zLine; |  | 
|  2276       for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){ |  | 
|  2277         if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){ |  | 
|  2278           *z = 0; |  | 
|  2279           i++; |  | 
|  2280           if( i<nCol ){ |  | 
|  2281             azCol[i] = &z[nSep]; |  | 
|  2282             z += nSep-1; |  | 
|  2283           } |  | 
|  2284         } |  | 
|  2285       } |  | 
|  2286       *z = 0; |  | 
|  2287       if( i+1!=nCol ){ |  | 
|  2288         fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n", |  | 
|  2289            zFile, lineno, nCol, i+1); |  | 
|  2290         zCommit = "ROLLBACK"; |  | 
|  2291         free(zLine); |  | 
|  2292         break; |  | 
|  2293       } |  | 
|  2294       for(i=0; i<nCol; i++){ |  | 
|  2295         sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC); |  | 
|  2296       } |  | 
|  2297       sqlite3_step(pStmt); |  | 
|  2298       rc = sqlite3_reset(pStmt); |  | 
|  2299       free(zLine); |  | 
|  2300       if( rc!=SQLITE_OK ){ |  | 
|  2301         fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db)); |  | 
|  2302         zCommit = "ROLLBACK"; |  | 
|  2303         rc = 1; |  | 
|  2304         break; |  | 
|  2305       } |  | 
|  2306     } |  | 
|  2307     free(azCol); |  | 
|  2308     fclose(in); |  | 
|  2309     sqlite3_finalize(pStmt); |  | 
|  2310     sqlite3_exec(p->db, zCommit, 0, 0, 0); |  | 
|  2311   }else |  | 
|  2312  |  | 
|  2313   if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){ |  | 
|  2314     struct callback_data data; |  | 
|  2315     char *zErrMsg = 0; |  | 
|  2316     open_db(p); |  | 
|  2317     memcpy(&data, p, sizeof(data)); |  | 
|  2318     data.showHeader = 0; |  | 
|  2319     data.mode = MODE_List; |  | 
|  2320     zShellStatic = azArg[1]; |  | 
|  2321     sqlite3_exec(p->db, |  | 
|  2322       "SELECT name FROM sqlite_master " |  | 
|  2323       "WHERE type='index' AND tbl_name LIKE shellstatic() " |  | 
|  2324       "UNION ALL " |  | 
|  2325       "SELECT name FROM sqlite_temp_master " |  | 
|  2326       "WHERE type='index' AND tbl_name LIKE shellstatic() " |  | 
|  2327       "ORDER BY 1", |  | 
|  2328       callback, &data, &zErrMsg |  | 
|  2329     ); |  | 
|  2330     zShellStatic = 0; |  | 
|  2331     if( zErrMsg ){ |  | 
|  2332       fprintf(stderr,"Error: %s\n", zErrMsg); |  | 
|  2333       sqlite3_free(zErrMsg); |  | 
|  2334     } |  | 
|  2335   }else |  | 
|  2336  |  | 
|  2337 #ifdef SQLITE_ENABLE_IOTRACE |  | 
|  2338   if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){ |  | 
|  2339     extern void (*sqlite3IoTrace)(const char*, ...); |  | 
|  2340     if( iotrace && iotrace!=stdout ) fclose(iotrace); |  | 
|  2341     iotrace = 0; |  | 
|  2342     if( nArg<2 ){ |  | 
|  2343       sqlite3IoTrace = 0; |  | 
|  2344     }else if( strcmp(azArg[1], "-")==0 ){ |  | 
|  2345       sqlite3IoTrace = iotracePrintf; |  | 
|  2346       iotrace = stdout; |  | 
|  2347     }else{ |  | 
|  2348       iotrace = fopen(azArg[1], "w"); |  | 
|  2349       if( iotrace==0 ){ |  | 
|  2350         fprintf(stderr, "cannot open \"%s\"\n", azArg[1]); |  | 
|  2351         sqlite3IoTrace = 0; |  | 
|  2352       }else{ |  | 
|  2353         sqlite3IoTrace = iotracePrintf; |  | 
|  2354       } |  | 
|  2355     } |  | 
|  2356   }else |  | 
|  2357 #endif |  | 
|  2358  |  | 
|  2359 #ifndef SQLITE_OMIT_LOAD_EXTENSION |  | 
|  2360   if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){ |  | 
|  2361     const char *zFile, *zProc; |  | 
|  2362     char *zErrMsg = 0; |  | 
|  2363     int rc; |  | 
|  2364     zFile = azArg[1]; |  | 
|  2365     zProc = nArg>=3 ? azArg[2] : 0; |  | 
|  2366     open_db(p); |  | 
|  2367     rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); |  | 
|  2368     if( rc!=SQLITE_OK ){ |  | 
|  2369       fprintf(stderr, "%s\n", zErrMsg); |  | 
|  2370       sqlite3_free(zErrMsg); |  | 
|  2371       rc = 1; |  | 
|  2372     } |  | 
|  2373   }else |  | 
|  2374 #endif |  | 
|  2375  |  | 
|  2376   if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){ |  | 
|  2377     int n2 = strlen30(azArg[1]); |  | 
|  2378     if( strncmp(azArg[1],"line",n2)==0 |  | 
|  2379         || |  | 
|  2380         strncmp(azArg[1],"lines",n2)==0 ){ |  | 
|  2381       p->mode = MODE_Line; |  | 
|  2382     }else if( strncmp(azArg[1],"column",n2)==0 |  | 
|  2383               || |  | 
|  2384               strncmp(azArg[1],"columns",n2)==0 ){ |  | 
|  2385       p->mode = MODE_Column; |  | 
|  2386     }else if( strncmp(azArg[1],"list",n2)==0 ){ |  | 
|  2387       p->mode = MODE_List; |  | 
|  2388     }else if( strncmp(azArg[1],"html",n2)==0 ){ |  | 
|  2389       p->mode = MODE_Html; |  | 
|  2390     }else if( strncmp(azArg[1],"tcl",n2)==0 ){ |  | 
|  2391       p->mode = MODE_Tcl; |  | 
|  2392     }else if( strncmp(azArg[1],"csv",n2)==0 ){ |  | 
|  2393       p->mode = MODE_Csv; |  | 
|  2394       sqlite3_snprintf(sizeof(p->separator), p->separator, ","); |  | 
|  2395     }else if( strncmp(azArg[1],"tabs",n2)==0 ){ |  | 
|  2396       p->mode = MODE_List; |  | 
|  2397       sqlite3_snprintf(sizeof(p->separator), p->separator, "\t"); |  | 
|  2398     }else if( strncmp(azArg[1],"insert",n2)==0 ){ |  | 
|  2399       p->mode = MODE_Insert; |  | 
|  2400       if( nArg>=3 ){ |  | 
|  2401         set_table_name(p, azArg[2]); |  | 
|  2402       }else{ |  | 
|  2403         set_table_name(p, "table"); |  | 
|  2404       } |  | 
|  2405     }else { |  | 
|  2406       fprintf(stderr,"mode should be one of: " |  | 
|  2407          "column csv html insert line list tabs tcl\n"); |  | 
|  2408     } |  | 
|  2409   }else |  | 
|  2410  |  | 
|  2411   if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) { |  | 
|  2412     sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue, |  | 
|  2413                      "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]); |  | 
|  2414   }else |  | 
|  2415  |  | 
|  2416   if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){ |  | 
|  2417     if( p->out!=stdout ){ |  | 
|  2418       fclose(p->out); |  | 
|  2419     } |  | 
|  2420     if( strcmp(azArg[1],"stdout")==0 ){ |  | 
|  2421       p->out = stdout; |  | 
|  2422       sqlite3_snprintf(sizeof(p->outfile), p->outfile, "stdout"); |  | 
|  2423     }else{ |  | 
|  2424       p->out = fopen(azArg[1], "wb"); |  | 
|  2425       if( p->out==0 ){ |  | 
|  2426         fprintf(stderr,"can't write to \"%s\"\n", azArg[1]); |  | 
|  2427         p->out = stdout; |  | 
|  2428       } else { |  | 
|  2429          sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]); |  | 
|  2430       } |  | 
|  2431     } |  | 
|  2432   }else |  | 
|  2433  |  | 
|  2434   if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){ |  | 
|  2435     if( nArg >= 2) { |  | 
|  2436       strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); |  | 
|  2437     } |  | 
|  2438     if( nArg >= 3) { |  | 
|  2439       strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1); |  | 
|  2440     } |  | 
|  2441   }else |  | 
|  2442  |  | 
|  2443   if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ |  | 
|  2444     rc = 2; |  | 
|  2445   }else |  | 
|  2446  |  | 
|  2447   if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){ |  | 
|  2448     FILE *alt = fopen(azArg[1], "rb"); |  | 
|  2449     if( alt==0 ){ |  | 
|  2450       fprintf(stderr,"can't open \"%s\"\n", azArg[1]); |  | 
|  2451     }else{ |  | 
|  2452       process_input(p, alt); |  | 
|  2453       fclose(alt); |  | 
|  2454     } |  | 
|  2455   }else |  | 
|  2456  |  | 
|  2457   if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 ){ |  | 
|  2458     const char *zSrcFile; |  | 
|  2459     const char *zDb; |  | 
|  2460     sqlite3 *pSrc; |  | 
|  2461     sqlite3_backup *pBackup; |  | 
|  2462     int rc; |  | 
|  2463     int nTimeout = 0; |  | 
|  2464  |  | 
|  2465     if( nArg==2 ){ |  | 
|  2466       zSrcFile = azArg[1]; |  | 
|  2467       zDb = "main"; |  | 
|  2468     }else{ |  | 
|  2469       zSrcFile = azArg[2]; |  | 
|  2470       zDb = azArg[1]; |  | 
|  2471     } |  | 
|  2472     rc = sqlite3_open(zSrcFile, &pSrc); |  | 
|  2473     if( rc!=SQLITE_OK ){ |  | 
|  2474       fprintf(stderr, "Error: cannot open %s\n", zSrcFile); |  | 
|  2475       sqlite3_close(pSrc); |  | 
|  2476       return 1; |  | 
|  2477     } |  | 
|  2478     open_db(p); |  | 
|  2479     pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); |  | 
|  2480     if( pBackup==0 ){ |  | 
|  2481       fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); |  | 
|  2482       sqlite3_close(pSrc); |  | 
|  2483       return 1; |  | 
|  2484     } |  | 
|  2485     while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK |  | 
|  2486           || rc==SQLITE_BUSY  ){ |  | 
|  2487       if( rc==SQLITE_BUSY ){ |  | 
|  2488         if( nTimeout++ >= 3 ) break; |  | 
|  2489         sqlite3_sleep(100); |  | 
|  2490       } |  | 
|  2491     } |  | 
|  2492     sqlite3_backup_finish(pBackup); |  | 
|  2493     if( rc==SQLITE_DONE ){ |  | 
|  2494       rc = SQLITE_OK; |  | 
|  2495     }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ |  | 
|  2496       fprintf(stderr, "source database is busy\n"); |  | 
|  2497     }else{ |  | 
|  2498       fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db)); |  | 
|  2499     } |  | 
|  2500     sqlite3_close(pSrc); |  | 
|  2501   }else |  | 
|  2502  |  | 
|  2503   if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){ |  | 
|  2504     struct callback_data data; |  | 
|  2505     char *zErrMsg = 0; |  | 
|  2506     open_db(p); |  | 
|  2507     memcpy(&data, p, sizeof(data)); |  | 
|  2508     data.showHeader = 0; |  | 
|  2509     data.mode = MODE_Semi; |  | 
|  2510     if( nArg>1 ){ |  | 
|  2511       int i; |  | 
|  2512       for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]); |  | 
|  2513       if( strcmp(azArg[1],"sqlite_master")==0 ){ |  | 
|  2514         char *new_argv[2], *new_colv[2]; |  | 
|  2515         new_argv[0] = "CREATE TABLE sqlite_master (\n" |  | 
|  2516                       "  type text,\n" |  | 
|  2517                       "  name text,\n" |  | 
|  2518                       "  tbl_name text,\n" |  | 
|  2519                       "  rootpage integer,\n" |  | 
|  2520                       "  sql text\n" |  | 
|  2521                       ")"; |  | 
|  2522         new_argv[1] = 0; |  | 
|  2523         new_colv[0] = "sql"; |  | 
|  2524         new_colv[1] = 0; |  | 
|  2525         callback(&data, 1, new_argv, new_colv); |  | 
|  2526       }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){ |  | 
|  2527         char *new_argv[2], *new_colv[2]; |  | 
|  2528         new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n" |  | 
|  2529                       "  type text,\n" |  | 
|  2530                       "  name text,\n" |  | 
|  2531                       "  tbl_name text,\n" |  | 
|  2532                       "  rootpage integer,\n" |  | 
|  2533                       "  sql text\n" |  | 
|  2534                       ")"; |  | 
|  2535         new_argv[1] = 0; |  | 
|  2536         new_colv[0] = "sql"; |  | 
|  2537         new_colv[1] = 0; |  | 
|  2538         callback(&data, 1, new_argv, new_colv); |  | 
|  2539       }else{ |  | 
|  2540         zShellStatic = azArg[1]; |  | 
|  2541         sqlite3_exec(p->db, |  | 
|  2542           "SELECT sql FROM " |  | 
|  2543           "  (SELECT sql sql, type type, tbl_name tbl_name, name name" |  | 
|  2544           "     FROM sqlite_master UNION ALL" |  | 
|  2545           "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) " |  | 
|  2546           "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL " |  | 
|  2547           "ORDER BY substr(type,2,1), name", |  | 
|  2548           callback, &data, &zErrMsg); |  | 
|  2549         zShellStatic = 0; |  | 
|  2550       } |  | 
|  2551     }else{ |  | 
|  2552       sqlite3_exec(p->db, |  | 
|  2553          "SELECT sql FROM " |  | 
|  2554          "  (SELECT sql sql, type type, tbl_name tbl_name, name name" |  | 
|  2555          "     FROM sqlite_master UNION ALL" |  | 
|  2556          "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) " |  | 
|  2557          "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" |  | 
|  2558          "ORDER BY substr(type,2,1), name", |  | 
|  2559          callback, &data, &zErrMsg |  | 
|  2560       ); |  | 
|  2561     } |  | 
|  2562     if( zErrMsg ){ |  | 
|  2563       fprintf(stderr,"Error: %s\n", zErrMsg); |  | 
|  2564       sqlite3_free(zErrMsg); |  | 
|  2565     } |  | 
|  2566   }else |  | 
|  2567  |  | 
|  2568   if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){ |  | 
|  2569     sqlite3_snprintf(sizeof(p->separator), p->separator, |  | 
|  2570                      "%.*s", (int)sizeof(p->separator)-1, azArg[1]); |  | 
|  2571   }else |  | 
|  2572  |  | 
|  2573   if( c=='s' && strncmp(azArg[0], "show", n)==0){ |  | 
|  2574     int i; |  | 
|  2575     fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off"); |  | 
|  2576     fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off"); |  | 
|  2577     fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off"); |  | 
|  2578     fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]); |  | 
|  2579     fprintf(p->out,"%9.9s: ", "nullvalue"); |  | 
|  2580       output_c_string(p->out, p->nullvalue); |  | 
|  2581       fprintf(p->out, "\n"); |  | 
|  2582     fprintf(p->out,"%9.9s: %s\n","output", |  | 
|  2583             strlen30(p->outfile) ? p->outfile : "stdout"); |  | 
|  2584     fprintf(p->out,"%9.9s: ", "separator"); |  | 
|  2585       output_c_string(p->out, p->separator); |  | 
|  2586       fprintf(p->out, "\n"); |  | 
|  2587     fprintf(p->out,"%9.9s: ","width"); |  | 
|  2588     for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) { |  | 
|  2589       fprintf(p->out,"%d ",p->colWidth[i]); |  | 
|  2590     } |  | 
|  2591     fprintf(p->out,"\n"); |  | 
|  2592   }else |  | 
|  2593  |  | 
|  2594   if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){ |  | 
|  2595     char **azResult; |  | 
|  2596     int nRow, rc; |  | 
|  2597     char *zErrMsg; |  | 
|  2598     open_db(p); |  | 
|  2599     if( nArg==1 ){ |  | 
|  2600       rc = sqlite3_get_table(p->db, |  | 
|  2601         "SELECT name FROM sqlite_master " |  | 
|  2602         "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'" |  | 
|  2603         "UNION ALL " |  | 
|  2604         "SELECT name FROM sqlite_temp_master " |  | 
|  2605         "WHERE type IN ('table','view') " |  | 
|  2606         "ORDER BY 1", |  | 
|  2607         &azResult, &nRow, 0, &zErrMsg |  | 
|  2608       ); |  | 
|  2609     }else{ |  | 
|  2610       zShellStatic = azArg[1]; |  | 
|  2611       rc = sqlite3_get_table(p->db, |  | 
|  2612         "SELECT name FROM sqlite_master " |  | 
|  2613         "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' " |  | 
|  2614         "UNION ALL " |  | 
|  2615         "SELECT name FROM sqlite_temp_master " |  | 
|  2616         "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' " |  | 
|  2617         "ORDER BY 1", |  | 
|  2618         &azResult, &nRow, 0, &zErrMsg |  | 
|  2619       ); |  | 
|  2620       zShellStatic = 0; |  | 
|  2621     } |  | 
|  2622     if( zErrMsg ){ |  | 
|  2623       fprintf(stderr,"Error: %s\n", zErrMsg); |  | 
|  2624       sqlite3_free(zErrMsg); |  | 
|  2625     } |  | 
|  2626     if( rc==SQLITE_OK ){ |  | 
|  2627       int len, maxlen = 0; |  | 
|  2628       int i, j; |  | 
|  2629       int nPrintCol, nPrintRow; |  | 
|  2630       for(i=1; i<=nRow; i++){ |  | 
|  2631         if( azResult[i]==0 ) continue; |  | 
|  2632         len = strlen30(azResult[i]); |  | 
|  2633         if( len>maxlen ) maxlen = len; |  | 
|  2634       } |  | 
|  2635       nPrintCol = 80/(maxlen+2); |  | 
|  2636       if( nPrintCol<1 ) nPrintCol = 1; |  | 
|  2637       nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; |  | 
|  2638       for(i=0; i<nPrintRow; i++){ |  | 
|  2639         for(j=i+1; j<=nRow; j+=nPrintRow){ |  | 
|  2640           char *zSp = j<=nPrintRow ? "" : "  "; |  | 
|  2641           printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : ""); |  | 
|  2642         } |  | 
|  2643         printf("\n"); |  | 
|  2644       } |  | 
|  2645     }else{ |  | 
|  2646       rc = 1; |  | 
|  2647     } |  | 
|  2648     sqlite3_free_table(azResult); |  | 
|  2649   }else |  | 
|  2650  |  | 
|  2651   if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){ |  | 
|  2652     open_db(p); |  | 
|  2653     sqlite3_busy_timeout(p->db, atoi(azArg[1])); |  | 
|  2654   }else |  | 
|  2655    |  | 
|  2656 #if HAS_TIMER   |  | 
|  2657   if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg>1 ){ |  | 
|  2658     enableTimer = booleanValue(azArg[1]); |  | 
|  2659   }else |  | 
|  2660 #endif |  | 
|  2661  |  | 
|  2662   if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ |  | 
|  2663     int j; |  | 
|  2664     assert( nArg<=ArraySize(azArg) ); |  | 
|  2665     for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){ |  | 
|  2666       p->colWidth[j-1] = atoi(azArg[j]); |  | 
|  2667     } |  | 
|  2668   }else |  | 
|  2669  |  | 
|  2670  |  | 
|  2671   { |  | 
|  2672     fprintf(stderr, "unknown command or invalid arguments: " |  | 
|  2673       " \"%s\". Enter \".help\" for help\n", azArg[0]); |  | 
|  2674   } |  | 
|  2675  |  | 
|  2676   return rc; |  | 
|  2677 } |  | 
|  2678  |  | 
|  2679 /* |  | 
|  2680 ** Return TRUE if a semicolon occurs anywhere in the first N characters |  | 
|  2681 ** of string z[]. |  | 
|  2682 */ |  | 
|  2683 static int _contains_semicolon(const char *z, int N){ |  | 
|  2684   int i; |  | 
|  2685   for(i=0; i<N; i++){  if( z[i]==';' ) return 1; } |  | 
|  2686   return 0; |  | 
|  2687 } |  | 
|  2688  |  | 
|  2689 /* |  | 
|  2690 ** Test to see if a line consists entirely of whitespace. |  | 
|  2691 */ |  | 
|  2692 static int _all_whitespace(const char *z){ |  | 
|  2693   for(; *z; z++){ |  | 
|  2694     if( isspace(*(unsigned char*)z) ) continue; |  | 
|  2695     if( *z=='/' && z[1]=='*' ){ |  | 
|  2696       z += 2; |  | 
|  2697       while( *z && (*z!='*' || z[1]!='/') ){ z++; } |  | 
|  2698       if( *z==0 ) return 0; |  | 
|  2699       z++; |  | 
|  2700       continue; |  | 
|  2701     } |  | 
|  2702     if( *z=='-' && z[1]=='-' ){ |  | 
|  2703       z += 2; |  | 
|  2704       while( *z && *z!='\n' ){ z++; } |  | 
|  2705       if( *z==0 ) return 1; |  | 
|  2706       continue; |  | 
|  2707     } |  | 
|  2708     return 0; |  | 
|  2709   } |  | 
|  2710   return 1; |  | 
|  2711 } |  | 
|  2712  |  | 
|  2713 /* |  | 
|  2714 ** Return TRUE if the line typed in is an SQL command terminator other |  | 
|  2715 ** than a semi-colon.  The SQL Server style "go" command is understood |  | 
|  2716 ** as is the Oracle "/". |  | 
|  2717 */ |  | 
|  2718 static int _is_command_terminator(const char *zLine){ |  | 
|  2719   while( isspace(*(unsigned char*)zLine) ){ zLine++; }; |  | 
|  2720   if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){ |  | 
|  2721     return 1;  /* Oracle */ |  | 
|  2722   } |  | 
|  2723   if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o' |  | 
|  2724          && _all_whitespace(&zLine[2]) ){ |  | 
|  2725     return 1;  /* SQL Server */ |  | 
|  2726   } |  | 
|  2727   return 0; |  | 
|  2728 } |  | 
|  2729  |  | 
|  2730 /* |  | 
|  2731 ** Return true if zSql is a complete SQL statement.  Return false if it |  | 
|  2732 ** ends in the middle of a string literal or C-style comment. |  | 
|  2733 */ |  | 
|  2734 static int _is_complete(char *zSql, int nSql){ |  | 
|  2735   int rc; |  | 
|  2736   if( zSql==0 ) return 1; |  | 
|  2737   zSql[nSql] = ';'; |  | 
|  2738   zSql[nSql+1] = 0; |  | 
|  2739   rc = sqlite3_complete(zSql); |  | 
|  2740   zSql[nSql] = 0; |  | 
|  2741   return rc; |  | 
|  2742 } |  | 
|  2743  |  | 
|  2744 /* |  | 
|  2745 ** Read input from *in and process it.  If *in==0 then input |  | 
|  2746 ** is interactive - the user is typing it it.  Otherwise, input |  | 
|  2747 ** is coming from a file or device.  A prompt is issued and history |  | 
|  2748 ** is saved only if input is interactive.  An interrupt signal will |  | 
|  2749 ** cause this routine to exit immediately, unless input is interactive. |  | 
|  2750 ** |  | 
|  2751 ** Return the number of errors. |  | 
|  2752 */ |  | 
|  2753 static int process_input(struct callback_data *p, FILE *in){ |  | 
|  2754   char *zLine = 0; |  | 
|  2755   char *zSql = 0; |  | 
|  2756   int nSql = 0; |  | 
|  2757   int nSqlPrior = 0; |  | 
|  2758   char *zErrMsg; |  | 
|  2759   int rc; |  | 
|  2760   int errCnt = 0; |  | 
|  2761   int lineno = 0; |  | 
|  2762   int startline = 0; |  | 
|  2763  |  | 
|  2764   while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){ |  | 
|  2765     fflush(p->out); |  | 
|  2766     free(zLine); |  | 
|  2767     zLine = one_input_line(zSql, in); |  | 
|  2768     if( zLine==0 ){ |  | 
|  2769       break;  /* We have reached EOF */ |  | 
|  2770     } |  | 
|  2771     if( seenInterrupt ){ |  | 
|  2772       if( in!=0 ) break; |  | 
|  2773       seenInterrupt = 0; |  | 
|  2774     } |  | 
|  2775     lineno++; |  | 
|  2776     if( p->echoOn ) printf("%s\n", zLine); |  | 
|  2777     if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue; |  | 
|  2778     if( zLine && zLine[0]=='.' && nSql==0 ){ |  | 
|  2779       rc = do_meta_command(zLine, p); |  | 
|  2780       if( rc==2 ){ |  | 
|  2781         break; |  | 
|  2782       }else if( rc ){ |  | 
|  2783         errCnt++; |  | 
|  2784       } |  | 
|  2785       continue; |  | 
|  2786     } |  | 
|  2787     if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){ |  | 
|  2788       memcpy(zLine,";",2); |  | 
|  2789     } |  | 
|  2790     nSqlPrior = nSql; |  | 
|  2791     if( zSql==0 ){ |  | 
|  2792       int i; |  | 
|  2793       for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){} |  | 
|  2794       if( zLine[i]!=0 ){ |  | 
|  2795         nSql = strlen30(zLine); |  | 
|  2796         zSql = malloc( nSql+3 ); |  | 
|  2797         if( zSql==0 ){ |  | 
|  2798           fprintf(stderr, "out of memory\n"); |  | 
|  2799           exit(1); |  | 
|  2800         } |  | 
|  2801         memcpy(zSql, zLine, nSql+1); |  | 
|  2802         startline = lineno; |  | 
|  2803       } |  | 
|  2804     }else{ |  | 
|  2805       int len = strlen30(zLine); |  | 
|  2806       zSql = realloc( zSql, nSql + len + 4 ); |  | 
|  2807       if( zSql==0 ){ |  | 
|  2808         fprintf(stderr,"%s: out of memory!\n", Argv0); |  | 
|  2809         exit(1); |  | 
|  2810       } |  | 
|  2811       zSql[nSql++] = '\n'; |  | 
|  2812       memcpy(&zSql[nSql], zLine, len+1); |  | 
|  2813       nSql += len; |  | 
|  2814     } |  | 
|  2815     if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) |  | 
|  2816                 && sqlite3_complete(zSql) ){ |  | 
|  2817       p->cnt = 0; |  | 
|  2818       open_db(p); |  | 
|  2819       BEGIN_TIMER; |  | 
|  2820       rc = sqlite3_exec(p->db, zSql, callback, p, &zErrMsg); |  | 
|  2821       END_TIMER; |  | 
|  2822       if( rc || zErrMsg ){ |  | 
|  2823         char zPrefix[100]; |  | 
|  2824         if( in!=0 || !stdin_is_interactive ){ |  | 
|  2825           sqlite3_snprintf(sizeof(zPrefix), zPrefix,  |  | 
|  2826                            "SQL error near line %d:", startline); |  | 
|  2827         }else{ |  | 
|  2828           sqlite3_snprintf(sizeof(zPrefix), zPrefix, "SQL error:"); |  | 
|  2829         } |  | 
|  2830         if( zErrMsg!=0 ){ |  | 
|  2831           printf("%s %s\n", zPrefix, zErrMsg); |  | 
|  2832           sqlite3_free(zErrMsg); |  | 
|  2833           zErrMsg = 0; |  | 
|  2834         }else{ |  | 
|  2835           printf("%s %s\n", zPrefix, sqlite3_errmsg(p->db)); |  | 
|  2836         } |  | 
|  2837         errCnt++; |  | 
|  2838       } |  | 
|  2839       free(zSql); |  | 
|  2840       zSql = 0; |  | 
|  2841       nSql = 0; |  | 
|  2842     } |  | 
|  2843   } |  | 
|  2844   if( zSql ){ |  | 
|  2845     if( !_all_whitespace(zSql) ) fprintf(stderr, "Incomplete SQL: %s\n", zSql); |  | 
|  2846     free(zSql); |  | 
|  2847   } |  | 
|  2848   free(zLine); |  | 
|  2849   return errCnt; |  | 
|  2850 } |  | 
|  2851  |  | 
|  2852 /* |  | 
|  2853 ** Return a pathname which is the user's home directory.  A |  | 
|  2854 ** 0 return indicates an error of some kind.  Space to hold the |  | 
|  2855 ** resulting string is obtained from malloc().  The calling |  | 
|  2856 ** function should free the result. |  | 
|  2857 */ |  | 
|  2858 static char *find_home_dir(void){ |  | 
|  2859   char *home_dir = NULL; |  | 
|  2860  |  | 
|  2861 #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_
      WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL) |  | 
|  2862   struct passwd *pwent; |  | 
|  2863   uid_t uid = getuid(); |  | 
|  2864   if( (pwent=getpwuid(uid)) != NULL) { |  | 
|  2865     home_dir = pwent->pw_dir; |  | 
|  2866   } |  | 
|  2867 #endif |  | 
|  2868  |  | 
|  2869 #if defined(_WIN32_WCE) |  | 
|  2870   /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() |  | 
|  2871    */ |  | 
|  2872   home_dir = strdup("/"); |  | 
|  2873 #else |  | 
|  2874  |  | 
|  2875 #if defined(_WIN32) || defined(WIN32) || defined(__OS2__) |  | 
|  2876   if (!home_dir) { |  | 
|  2877     home_dir = getenv("USERPROFILE"); |  | 
|  2878   } |  | 
|  2879 #endif |  | 
|  2880  |  | 
|  2881   if (!home_dir) { |  | 
|  2882     home_dir = getenv("HOME"); |  | 
|  2883   } |  | 
|  2884  |  | 
|  2885 #if defined(_WIN32) || defined(WIN32) || defined(__OS2__) |  | 
|  2886   if (!home_dir) { |  | 
|  2887     char *zDrive, *zPath; |  | 
|  2888     int n; |  | 
|  2889     zDrive = getenv("HOMEDRIVE"); |  | 
|  2890     zPath = getenv("HOMEPATH"); |  | 
|  2891     if( zDrive && zPath ){ |  | 
|  2892       n = strlen30(zDrive) + strlen30(zPath) + 1; |  | 
|  2893       home_dir = malloc( n ); |  | 
|  2894       if( home_dir==0 ) return 0; |  | 
|  2895       sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath); |  | 
|  2896       return home_dir; |  | 
|  2897     } |  | 
|  2898     home_dir = "c:\\"; |  | 
|  2899   } |  | 
|  2900 #endif |  | 
|  2901  |  | 
|  2902 #endif /* !_WIN32_WCE */ |  | 
|  2903  |  | 
|  2904   if( home_dir ){ |  | 
|  2905     int n = strlen30(home_dir) + 1; |  | 
|  2906     char *z = malloc( n ); |  | 
|  2907     if( z ) memcpy(z, home_dir, n); |  | 
|  2908     home_dir = z; |  | 
|  2909   } |  | 
|  2910  |  | 
|  2911   return home_dir; |  | 
|  2912 } |  | 
|  2913  |  | 
|  2914 /* |  | 
|  2915 ** Read input from the file given by sqliterc_override.  Or if that |  | 
|  2916 ** parameter is NULL, take input from ~/.sqliterc |  | 
|  2917 */ |  | 
|  2918 static void process_sqliterc( |  | 
|  2919   struct callback_data *p,        /* Configuration data */ |  | 
|  2920   const char *sqliterc_override   /* Name of config file. NULL to use default */ |  | 
|  2921 ){ |  | 
|  2922   char *home_dir = NULL; |  | 
|  2923   const char *sqliterc = sqliterc_override; |  | 
|  2924   char *zBuf = 0; |  | 
|  2925   FILE *in = NULL; |  | 
|  2926   int nBuf; |  | 
|  2927  |  | 
|  2928   if (sqliterc == NULL) { |  | 
|  2929     home_dir = find_home_dir(); |  | 
|  2930     if( home_dir==0 ){ |  | 
|  2931 #if !defined(__RTP__) && !defined(_WRS_KERNEL) |  | 
|  2932       fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0); |  | 
|  2933 #endif |  | 
|  2934       return; |  | 
|  2935     } |  | 
|  2936     nBuf = strlen30(home_dir) + 16; |  | 
|  2937     zBuf = malloc( nBuf ); |  | 
|  2938     if( zBuf==0 ){ |  | 
|  2939       fprintf(stderr,"%s: out of memory!\n", Argv0); |  | 
|  2940       exit(1); |  | 
|  2941     } |  | 
|  2942     sqlite3_snprintf(nBuf, zBuf,"%s/.sqliterc",home_dir); |  | 
|  2943     free(home_dir); |  | 
|  2944     sqliterc = (const char*)zBuf; |  | 
|  2945   } |  | 
|  2946   in = fopen(sqliterc,"rb"); |  | 
|  2947   if( in ){ |  | 
|  2948     if( stdin_is_interactive ){ |  | 
|  2949       printf("-- Loading resources from %s\n",sqliterc); |  | 
|  2950     } |  | 
|  2951     process_input(p,in); |  | 
|  2952     fclose(in); |  | 
|  2953   } |  | 
|  2954   free(zBuf); |  | 
|  2955   return; |  | 
|  2956 } |  | 
|  2957  |  | 
|  2958 /* |  | 
|  2959 ** Show available command line options |  | 
|  2960 */ |  | 
|  2961 static const char zOptions[] =  |  | 
|  2962   "   -init filename       read/process named file\n" |  | 
|  2963   "   -echo                print commands before execution\n" |  | 
|  2964   "   -[no]header          turn headers on or off\n" |  | 
|  2965   "   -bail                stop after hitting an error\n" |  | 
|  2966   "   -interactive         force interactive I/O\n" |  | 
|  2967   "   -batch               force batch I/O\n" |  | 
|  2968   "   -column              set output mode to 'column'\n" |  | 
|  2969   "   -csv                 set output mode to 'csv'\n" |  | 
|  2970   "   -html                set output mode to HTML\n" |  | 
|  2971   "   -line                set output mode to 'line'\n" |  | 
|  2972   "   -list                set output mode to 'list'\n" |  | 
|  2973   "   -separator 'x'       set output field separator (|)\n" |  | 
|  2974   "   -nullvalue 'text'    set text string for NULL values\n" |  | 
|  2975   "   -version             show SQLite version\n" |  | 
|  2976 ; |  | 
|  2977 static void usage(int showDetail){ |  | 
|  2978   fprintf(stderr, |  | 
|  2979       "Usage: %s [OPTIONS] FILENAME [SQL]\n"   |  | 
|  2980       "FILENAME is the name of an SQLite database. A new database is created\n" |  | 
|  2981       "if the file does not previously exist.\n", Argv0); |  | 
|  2982   if( showDetail ){ |  | 
|  2983     fprintf(stderr, "OPTIONS include:\n%s", zOptions); |  | 
|  2984   }else{ |  | 
|  2985     fprintf(stderr, "Use the -help option for additional information\n"); |  | 
|  2986   } |  | 
|  2987   exit(1); |  | 
|  2988 } |  | 
|  2989  |  | 
|  2990 /* |  | 
|  2991 ** Initialize the state information in data |  | 
|  2992 */ |  | 
|  2993 static void main_init(struct callback_data *data) { |  | 
|  2994   memset(data, 0, sizeof(*data)); |  | 
|  2995   data->mode = MODE_List; |  | 
|  2996   memcpy(data->separator,"|", 2); |  | 
|  2997   data->showHeader = 0; |  | 
|  2998   sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); |  | 
|  2999   sqlite3_snprintf(sizeof(continuePrompt), continuePrompt,"   ...> "); |  | 
|  3000 } |  | 
|  3001  |  | 
|  3002 int main(int argc, char **argv){ |  | 
|  3003   char *zErrMsg = 0; |  | 
|  3004   struct callback_data data; |  | 
|  3005   const char *zInitFile = 0; |  | 
|  3006   char *zFirstCmd = 0; |  | 
|  3007   int i; |  | 
|  3008   int rc = 0; |  | 
|  3009  |  | 
|  3010   /* Begin evanm patch. */ |  | 
|  3011 #ifdef SQLITE_GEARS_DISABLE_SHELL_ICU |  | 
|  3012   /* Gears doesn't use this. */ |  | 
|  3013 #else |  | 
|  3014   extern int sqlite_shell_init_icu(); |  | 
|  3015   if( !sqlite_shell_init_icu() ){ |  | 
|  3016     fprintf(stderr, "%s: warning: couldn't find icudt38.dll; " |  | 
|  3017                     "queries against ICU FTS tables will fail.\n", argv[0]); |  | 
|  3018   } |  | 
|  3019 #endif |  | 
|  3020   /* End evanm patch. */ |  | 
|  3021  |  | 
|  3022   Argv0 = argv[0]; |  | 
|  3023   main_init(&data); |  | 
|  3024   stdin_is_interactive = isatty(0); |  | 
|  3025  |  | 
|  3026   /* Make sure we have a valid signal handler early, before anything |  | 
|  3027   ** else is done. |  | 
|  3028   */ |  | 
|  3029 #ifdef SIGINT |  | 
|  3030   signal(SIGINT, interrupt_handler); |  | 
|  3031 #endif |  | 
|  3032  |  | 
|  3033   /* Do an initial pass through the command-line argument to locate |  | 
|  3034   ** the name of the database file, the name of the initialization file, |  | 
|  3035   ** and the first command to execute. |  | 
|  3036   */ |  | 
|  3037   for(i=1; i<argc-1; i++){ |  | 
|  3038     char *z; |  | 
|  3039     if( argv[i][0]!='-' ) break; |  | 
|  3040     z = argv[i]; |  | 
|  3041     if( z[0]=='-' && z[1]=='-' ) z++; |  | 
|  3042     if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){ |  | 
|  3043       i++; |  | 
|  3044     }else if( strcmp(argv[i],"-init")==0 ){ |  | 
|  3045       i++; |  | 
|  3046       zInitFile = argv[i]; |  | 
|  3047     } |  | 
|  3048   } |  | 
|  3049   if( i<argc ){ |  | 
|  3050 #if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2 |  | 
|  3051     data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] ); |  | 
|  3052 #else |  | 
|  3053     data.zDbFilename = argv[i++]; |  | 
|  3054 #endif |  | 
|  3055   }else{ |  | 
|  3056 #ifndef SQLITE_OMIT_MEMORYDB |  | 
|  3057     data.zDbFilename = ":memory:"; |  | 
|  3058 #else |  | 
|  3059     data.zDbFilename = 0; |  | 
|  3060 #endif |  | 
|  3061   } |  | 
|  3062   if( i<argc ){ |  | 
|  3063     zFirstCmd = argv[i++]; |  | 
|  3064   } |  | 
|  3065   data.out = stdout; |  | 
|  3066  |  | 
|  3067 #ifdef SQLITE_OMIT_MEMORYDB |  | 
|  3068   if( data.zDbFilename==0 ){ |  | 
|  3069     fprintf(stderr,"%s: no database filename specified\n", argv[0]); |  | 
|  3070     exit(1); |  | 
|  3071   } |  | 
|  3072 #endif |  | 
|  3073  |  | 
|  3074   /* Go ahead and open the database file if it already exists.  If the |  | 
|  3075   ** file does not exist, delay opening it.  This prevents empty database |  | 
|  3076   ** files from being created if a user mistypes the database name argument |  | 
|  3077   ** to the sqlite command-line tool. |  | 
|  3078   */ |  | 
|  3079   if( access(data.zDbFilename, 0)==0 ){ |  | 
|  3080     open_db(&data); |  | 
|  3081   } |  | 
|  3082  |  | 
|  3083   /* Process the initialization file if there is one.  If no -init option |  | 
|  3084   ** is given on the command line, look for a file named ~/.sqliterc and |  | 
|  3085   ** try to process it. |  | 
|  3086   */ |  | 
|  3087   process_sqliterc(&data,zInitFile); |  | 
|  3088  |  | 
|  3089   /* Make a second pass through the command-line argument and set |  | 
|  3090   ** options.  This second pass is delayed until after the initialization |  | 
|  3091   ** file is processed so that the command-line arguments will override |  | 
|  3092   ** settings in the initialization file. |  | 
|  3093   */ |  | 
|  3094   for(i=1; i<argc && argv[i][0]=='-'; i++){ |  | 
|  3095     char *z = argv[i]; |  | 
|  3096     if( z[1]=='-' ){ z++; } |  | 
|  3097     if( strcmp(z,"-init")==0 ){ |  | 
|  3098       i++; |  | 
|  3099     }else if( strcmp(z,"-html")==0 ){ |  | 
|  3100       data.mode = MODE_Html; |  | 
|  3101     }else if( strcmp(z,"-list")==0 ){ |  | 
|  3102       data.mode = MODE_List; |  | 
|  3103     }else if( strcmp(z,"-line")==0 ){ |  | 
|  3104       data.mode = MODE_Line; |  | 
|  3105     }else if( strcmp(z,"-column")==0 ){ |  | 
|  3106       data.mode = MODE_Column; |  | 
|  3107     }else if( strcmp(z,"-csv")==0 ){ |  | 
|  3108       data.mode = MODE_Csv; |  | 
|  3109       memcpy(data.separator,",",2); |  | 
|  3110     }else if( strcmp(z,"-separator")==0 ){ |  | 
|  3111       i++; |  | 
|  3112       sqlite3_snprintf(sizeof(data.separator), data.separator, |  | 
|  3113                        "%.*s",(int)sizeof(data.separator)-1,argv[i]); |  | 
|  3114     }else if( strcmp(z,"-nullvalue")==0 ){ |  | 
|  3115       i++; |  | 
|  3116       sqlite3_snprintf(sizeof(data.nullvalue), data.nullvalue, |  | 
|  3117                        "%.*s",(int)sizeof(data.nullvalue)-1,argv[i]); |  | 
|  3118     }else if( strcmp(z,"-header")==0 ){ |  | 
|  3119       data.showHeader = 1; |  | 
|  3120     }else if( strcmp(z,"-noheader")==0 ){ |  | 
|  3121       data.showHeader = 0; |  | 
|  3122     }else if( strcmp(z,"-echo")==0 ){ |  | 
|  3123       data.echoOn = 1; |  | 
|  3124     }else if( strcmp(z,"-bail")==0 ){ |  | 
|  3125       bail_on_error = 1; |  | 
|  3126     }else if( strcmp(z,"-version")==0 ){ |  | 
|  3127       printf("%s\n", sqlite3_libversion()); |  | 
|  3128       return 0; |  | 
|  3129     }else if( strcmp(z,"-interactive")==0 ){ |  | 
|  3130       stdin_is_interactive = 1; |  | 
|  3131     }else if( strcmp(z,"-batch")==0 ){ |  | 
|  3132       stdin_is_interactive = 0; |  | 
|  3133     }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){ |  | 
|  3134       usage(1); |  | 
|  3135     }else{ |  | 
|  3136       fprintf(stderr,"%s: unknown option: %s\n", Argv0, z); |  | 
|  3137       fprintf(stderr,"Use -help for a list of options.\n"); |  | 
|  3138       return 1; |  | 
|  3139     } |  | 
|  3140   } |  | 
|  3141  |  | 
|  3142   if( zFirstCmd ){ |  | 
|  3143     /* Run just the command that follows the database name |  | 
|  3144     */ |  | 
|  3145     if( zFirstCmd[0]=='.' ){ |  | 
|  3146       do_meta_command(zFirstCmd, &data); |  | 
|  3147       exit(0); |  | 
|  3148     }else{ |  | 
|  3149       int rc; |  | 
|  3150       open_db(&data); |  | 
|  3151       rc = sqlite3_exec(data.db, zFirstCmd, callback, &data, &zErrMsg); |  | 
|  3152       if( rc!=0 && zErrMsg!=0 ){ |  | 
|  3153         fprintf(stderr,"SQL error: %s\n", zErrMsg); |  | 
|  3154         exit(1); |  | 
|  3155       } |  | 
|  3156     } |  | 
|  3157   }else{ |  | 
|  3158     /* Run commands received from standard input |  | 
|  3159     */ |  | 
|  3160     if( stdin_is_interactive ){ |  | 
|  3161       char *zHome; |  | 
|  3162       char *zHistory = 0; |  | 
|  3163       int nHistory; |  | 
|  3164       printf( |  | 
|  3165         "SQLite version %s\n" |  | 
|  3166         "Enter \".help\" for instructions\n" |  | 
|  3167         "Enter SQL statements terminated with a \";\"\n", |  | 
|  3168         sqlite3_libversion() |  | 
|  3169       ); |  | 
|  3170       zHome = find_home_dir(); |  | 
|  3171       if( zHome ){ |  | 
|  3172         nHistory = strlen30(zHome) + 20; |  | 
|  3173         if( (zHistory = malloc(nHistory))!=0 ){ |  | 
|  3174           sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); |  | 
|  3175         } |  | 
|  3176       } |  | 
|  3177 #if defined(HAVE_READLINE) && HAVE_READLINE==1 |  | 
|  3178       if( zHistory ) read_history(zHistory); |  | 
|  3179 #endif |  | 
|  3180       rc = process_input(&data, 0); |  | 
|  3181       if( zHistory ){ |  | 
|  3182         stifle_history(100); |  | 
|  3183         write_history(zHistory); |  | 
|  3184         free(zHistory); |  | 
|  3185       } |  | 
|  3186       free(zHome); |  | 
|  3187     }else{ |  | 
|  3188       rc = process_input(&data, stdin); |  | 
|  3189     } |  | 
|  3190   } |  | 
|  3191   set_table_name(&data, 0); |  | 
|  3192   if( db ){ |  | 
|  3193     if( sqlite3_close(db)!=SQLITE_OK ){ |  | 
|  3194       fprintf(stderr,"error closing database: %s\n", sqlite3_errmsg(db)); |  | 
|  3195     } |  | 
|  3196   } |  | 
|  3197   return rc; |  | 
|  3198 } |  | 
| OLD | NEW |