xref: /illumos-gate/usr/src/cmd/sqlite/shell.c (revision 8119dad84d6416f13557b0ba8e2aaf9064cbcfd3)
1 /*
2  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7 ** 2001 September 15
8 **
9 ** The author disclaims copyright to this source code.  In place of
10 ** a legal notice, here is a blessing:
11 **
12 **    May you do good and not evil.
13 **    May you find forgiveness for yourself and forgive others.
14 **    May you share freely, never taking more than you give.
15 **
16 *************************************************************************
17 ** This file contains code to implement the "sqlite" command line
18 ** utility for accessing SQLite databases.
19 **
20 ** $Id: shell.c,v 1.93 2004/03/17 23:42:13 drh Exp $
21 */
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include "sqlite.h"
26 #include "sqlite-misc.h"				/* SUNW addition */
27 #include <ctype.h>
28 
29 #if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)
30 # include <signal.h>
31 # include <pwd.h>
32 # include <unistd.h>
33 # include <sys/types.h>
34 #endif
35 
36 #ifdef __MACOS__
37 # include <console.h>
38 # include <signal.h>
39 # include <unistd.h>
40 # include <extras.h>
41 # include <Files.h>
42 # include <Folders.h>
43 #endif
44 
45 #if defined(HAVE_READLINE) && HAVE_READLINE==1
46 # include <readline/readline.h>
47 # include <readline/history.h>
48 #else
49 # define readline(p) local_getline(p,stdin)
50 # define add_history(X)
51 # define read_history(X)
52 # define write_history(X)
53 # define stifle_history(X)
54 #endif
55 
56 /* Make sure isatty() has a prototype.
57 */
58 extern int isatty();
59 
60 /*
61 ** The following is the open SQLite database.  We make a pointer
62 ** to this database a static variable so that it can be accessed
63 ** by the SIGINT handler to interrupt database processing.
64 */
65 static sqlite *db = 0;
66 
67 /*
68 ** True if an interrupt (Control-C) has been received.
69 */
70 static int seenInterrupt = 0;
71 
72 /*
73 ** This is the name of our program. It is set in main(), used
74 ** in a number of other places, mostly for error messages.
75 */
76 static char *Argv0;
77 
78 /*
79 ** Prompt strings. Initialized in main. Settable with
80 **   .prompt main continue
81 */
82 static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
83 static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */
84 
85 
86 /*
87 ** Determines if a string is a number of not.
88 */
89 extern int sqliteIsNumber(const char*);
90 
91 /*
92 ** This routine reads a line of text from standard input, stores
93 ** the text in memory obtained from malloc() and returns a pointer
94 ** to the text.  NULL is returned at end of file, or if malloc()
95 ** fails.
96 **
97 ** The interface is like "readline" but no command-line editing
98 ** is done.
99 */
100 static char *local_getline(char *zPrompt, FILE *in){
101   char *zLine;
102   int nLine;
103   int n;
104   int eol;
105 
106   if( zPrompt && *zPrompt ){
107     printf("%s",zPrompt);
108     fflush(stdout);
109   }
110   nLine = 100;
111   zLine = malloc( nLine );
112   if( zLine==0 ) return 0;
113   n = 0;
114   eol = 0;
115   while( !eol ){
116     if( n+100>nLine ){
117       nLine = nLine*2 + 100;
118       zLine = realloc(zLine, nLine);
119       if( zLine==0 ) return 0;
120     }
121     if( fgets(&zLine[n], nLine - n, in)==0 ){
122       if( n==0 ){
123         free(zLine);
124         return 0;
125       }
126       zLine[n] = 0;
127       eol = 1;
128       break;
129     }
130     while( zLine[n] ){ n++; }
131     if( n>0 && zLine[n-1]=='\n' ){
132       n--;
133       zLine[n] = 0;
134       eol = 1;
135     }
136   }
137   zLine = realloc( zLine, n+1 );
138   return zLine;
139 }
140 
141 /*
142 ** Retrieve a single line of input text.  "isatty" is true if text
143 ** is coming from a terminal.  In that case, we issue a prompt and
144 ** attempt to use "readline" for command-line editing.  If "isatty"
145 ** is false, use "local_getline" instead of "readline" and issue no prompt.
146 **
147 ** zPrior is a string of prior text retrieved.  If not the empty
148 ** string, then issue a continuation prompt.
149 */
150 static char *one_input_line(const char *zPrior, FILE *in){
151   char *zPrompt;
152   char *zResult;
153   if( in!=0 ){
154     return local_getline(0, in);
155   }
156   if( zPrior && zPrior[0] ){
157     zPrompt = continuePrompt;
158   }else{
159     zPrompt = mainPrompt;
160   }
161   zResult = readline(zPrompt);
162   if( zResult ) add_history(zResult);
163   return zResult;
164 }
165 
166 struct previous_mode_data {
167   int valid;        /* Is there legit data in here? */
168   int mode;
169   int showHeader;
170   int colWidth[100];
171 };
172 /*
173 ** An pointer to an instance of this structure is passed from
174 ** the main program to the callback.  This is used to communicate
175 ** state and mode information.
176 */
177 struct callback_data {
178   sqlite *db;            /* The database */
179   int echoOn;            /* True to echo input commands */
180   int cnt;               /* Number of records displayed so far */
181   FILE *out;             /* Write results here */
182   int mode;              /* An output mode setting */
183   int showHeader;        /* True to show column names in List or Column mode */
184   char *zDestTable;      /* Name of destination table when MODE_Insert */
185   char separator[20];    /* Separator character for MODE_List */
186   int colWidth[100];     /* Requested width of each column when in column mode*/
187   int actualWidth[100];  /* Actual width of each column */
188   char nullvalue[20];    /* The text to print when a NULL comes back from
189                          ** the database */
190   struct previous_mode_data explainPrev;
191                          /* Holds the mode information just before
192                          ** .explain ON */
193   char outfile[FILENAME_MAX]; /* Filename for *out */
194   const char *zDbFilename;    /* name of the database file */
195   char *zKey;                 /* Encryption key */
196 };
197 
198 /*
199 ** These are the allowed modes.
200 */
201 #define MODE_Line     0  /* One column per line.  Blank line between records */
202 #define MODE_Column   1  /* One record per line in neat columns */
203 #define MODE_List     2  /* One record per line with a separator */
204 #define MODE_Semi     3  /* Same as MODE_List but append ";" to each line */
205 #define MODE_Html     4  /* Generate an XHTML table */
206 #define MODE_Insert   5  /* Generate SQL "insert" statements */
207 #define MODE_NUM_OF   6  /* The number of modes (not a mode itself) */
208 
209 char *modeDescr[MODE_NUM_OF] = {
210   "line",
211   "column",
212   "list",
213   "semi",
214   "html",
215   "insert"
216 };
217 
218 /*
219 ** Number of elements in an array
220 */
221 #define ArraySize(X)  (sizeof(X)/sizeof(X[0]))
222 
223 /*
224 ** Output the given string as a quoted string using SQL quoting conventions.
225 */
226 static void output_quoted_string(FILE *out, const char *z){
227   int i;
228   int nSingle = 0;
229   for(i=0; z[i]; i++){
230     if( z[i]=='\'' ) nSingle++;
231   }
232   if( nSingle==0 ){
233     fprintf(out,"'%s'",z);
234   }else{
235     fprintf(out,"'");
236     while( *z ){
237       for(i=0; z[i] && z[i]!='\''; i++){}
238       if( i==0 ){
239         fprintf(out,"''");
240         z++;
241       }else if( z[i]=='\'' ){
242         fprintf(out,"%.*s''",i,z);
243         z += i+1;
244       }else{
245         fprintf(out,"%s",z);
246         break;
247       }
248     }
249     fprintf(out,"'");
250   }
251 }
252 
253 /*
254 ** Output the given string with characters that are special to
255 ** HTML escaped.
256 */
257 static void output_html_string(FILE *out, const char *z){
258   int i;
259   while( *z ){
260     for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
261     if( i>0 ){
262       fprintf(out,"%.*s",i,z);
263     }
264     if( z[i]=='<' ){
265       fprintf(out,"&lt;");
266     }else if( z[i]=='&' ){
267       fprintf(out,"&amp;");
268     }else{
269       break;
270     }
271     z += i + 1;
272   }
273 }
274 
275 /*
276 ** This routine runs when the user presses Ctrl-C
277 */
278 static void interrupt_handler(int NotUsed){
279   seenInterrupt = 1;
280   if( db ) sqlite_interrupt(db);
281 }
282 
283 /*
284 ** This is the callback routine that the SQLite library
285 ** invokes for each row of a query result.
286 */
287 static int callback(void *pArg, int nArg, char **azArg, char **azCol){
288   int i;
289   struct callback_data *p = (struct callback_data*)pArg;
290   switch( p->mode ){
291     case MODE_Line: {
292       int w = 5;
293       if( azArg==0 ) break;
294       for(i=0; i<nArg; i++){
295         int len = strlen(azCol[i]);
296         if( len>w ) w = len;
297       }
298       if( p->cnt++>0 ) fprintf(p->out,"\n");
299       for(i=0; i<nArg; i++){
300         fprintf(p->out,"%*s = %s\n", w, azCol[i],
301                 azArg[i] ? azArg[i] : p->nullvalue);
302       }
303       break;
304     }
305     case MODE_Column: {
306       if( p->cnt++==0 ){
307         for(i=0; i<nArg; i++){
308           int w, n;
309           if( i<ArraySize(p->colWidth) ){
310              w = p->colWidth[i];
311           }else{
312              w = 0;
313           }
314           if( w<=0 ){
315             w = strlen(azCol[i] ? azCol[i] : "");
316             if( w<10 ) w = 10;
317             n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue);
318             if( w<n ) w = n;
319           }
320           if( i<ArraySize(p->actualWidth) ){
321             p->actualWidth[i] = w;
322           }
323           if( p->showHeader ){
324             fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": "  ");
325           }
326         }
327         if( p->showHeader ){
328           for(i=0; i<nArg; i++){
329             int w;
330             if( i<ArraySize(p->actualWidth) ){
331                w = p->actualWidth[i];
332             }else{
333                w = 10;
334             }
335             fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
336                    "----------------------------------------------------------",
337                     i==nArg-1 ? "\n": "  ");
338           }
339         }
340       }
341       if( azArg==0 ) break;
342       for(i=0; i<nArg; i++){
343         int w;
344         if( i<ArraySize(p->actualWidth) ){
345            w = p->actualWidth[i];
346         }else{
347            w = 10;
348         }
349         fprintf(p->out,"%-*.*s%s",w,w,
350             azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");
351       }
352       break;
353     }
354     case MODE_Semi:
355     case MODE_List: {
356       if( p->cnt++==0 && p->showHeader ){
357         for(i=0; i<nArg; i++){
358           fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
359         }
360       }
361       if( azArg==0 ) break;
362       for(i=0; i<nArg; i++){
363         char *z = azArg[i];
364         if( z==0 ) z = p->nullvalue;
365         fprintf(p->out, "%s", z);
366         if( i<nArg-1 ){
367           fprintf(p->out, "%s", p->separator);
368         }else if( p->mode==MODE_Semi ){
369           fprintf(p->out, ";\n");
370         }else{
371           fprintf(p->out, "\n");
372         }
373       }
374       break;
375     }
376     case MODE_Html: {
377       if( p->cnt++==0 && p->showHeader ){
378         fprintf(p->out,"<TR>");
379         for(i=0; i<nArg; i++){
380           fprintf(p->out,"<TH>%s</TH>",azCol[i]);
381         }
382         fprintf(p->out,"</TR>\n");
383       }
384       if( azArg==0 ) break;
385       fprintf(p->out,"<TR>");
386       for(i=0; i<nArg; i++){
387         fprintf(p->out,"<TD>");
388         output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
389         fprintf(p->out,"</TD>\n");
390       }
391       fprintf(p->out,"</TR>\n");
392       break;
393     }
394     case MODE_Insert: {
395       if( azArg==0 ) break;
396       fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
397       for(i=0; i<nArg; i++){
398         char *zSep = i>0 ? ",": "";
399         if( azArg[i]==0 ){
400           fprintf(p->out,"%sNULL",zSep);
401         }else if( sqliteIsNumber(azArg[i]) ){
402           fprintf(p->out,"%s%s",zSep, azArg[i]);
403         }else{
404           if( zSep[0] ) fprintf(p->out,"%s",zSep);
405           output_quoted_string(p->out, azArg[i]);
406         }
407       }
408       fprintf(p->out,");\n");
409       break;
410     }
411   }
412   return 0;
413 }
414 
415 /*
416 ** Set the destination table field of the callback_data structure to
417 ** the name of the table given.  Escape any quote characters in the
418 ** table name.
419 */
420 static void set_table_name(struct callback_data *p, const char *zName){
421   int i, n;
422   int needQuote;
423   char *z;
424 
425   if( p->zDestTable ){
426     free(p->zDestTable);
427     p->zDestTable = 0;
428   }
429   if( zName==0 ) return;
430   needQuote = !isalpha(*zName) && *zName!='_';
431   for(i=n=0; zName[i]; i++, n++){
432     if( !isalnum(zName[i]) && zName[i]!='_' ){
433       needQuote = 1;
434       if( zName[i]=='\'' ) n++;
435     }
436   }
437   if( needQuote ) n += 2;
438   z = p->zDestTable = malloc( n+1 );
439   if( z==0 ){
440     fprintf(stderr,"Out of memory!\n");
441     exit(1);
442   }
443   n = 0;
444   if( needQuote ) z[n++] = '\'';
445   for(i=0; zName[i]; i++){
446     z[n++] = zName[i];
447     if( zName[i]=='\'' ) z[n++] = '\'';
448   }
449   if( needQuote ) z[n++] = '\'';
450   z[n] = 0;
451 }
452 
453 /*
454 ** This is a different callback routine used for dumping the database.
455 ** Each row received by this callback consists of a table name,
456 ** the table type ("index" or "table") and SQL to create the table.
457 ** This routine should print text sufficient to recreate the table.
458 */
459 static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
460   struct callback_data *p = (struct callback_data *)pArg;
461   if( nArg!=3 ) return 1;
462   fprintf(p->out, "%s;\n", azArg[2]);
463   if( strcmp(azArg[1],"table")==0 ){
464     struct callback_data d2;
465     d2 = *p;
466     d2.mode = MODE_Insert;
467     d2.zDestTable = 0;
468     set_table_name(&d2, azArg[0]);
469     sqlite_exec_printf(p->db,
470        "SELECT * FROM '%q'",
471        callback, &d2, 0, azArg[0]
472     );
473     set_table_name(&d2, 0);
474   }
475   return 0;
476 }
477 
478 /*
479 ** Text of a help message
480 */
481 static char zHelp[] =
482   ".databases             List names and files of attached databases\n"
483   ".dump ?TABLE? ...      Dump the database in a text format\n"
484   ".echo ON|OFF           Turn command echo on or off\n"
485   ".exit                  Exit this program\n"
486   ".explain ON|OFF        Turn output mode suitable for EXPLAIN on or off.\n"
487   ".header(s) ON|OFF      Turn display of headers on or off\n"
488   ".help                  Show this message\n"
489   ".indices TABLE         Show names of all indices on TABLE\n"
490   ".mode MODE             Set mode to one of \"line(s)\", \"column(s)\", \n"
491   "                       \"insert\", \"list\", or \"html\"\n"
492   ".mode insert TABLE     Generate SQL insert statements for TABLE\n"
493   ".nullvalue STRING      Print STRING instead of nothing for NULL data\n"
494   ".output FILENAME       Send output to FILENAME\n"
495   ".output stdout         Send output to the screen\n"
496   ".prompt MAIN CONTINUE  Replace the standard prompts\n"
497   ".quit                  Exit this program\n"
498   ".read FILENAME         Execute SQL in FILENAME\n"
499 #ifdef SQLITE_HAS_CODEC
500   ".rekey OLD NEW NEW     Change the encryption key\n"
501 #endif
502   ".schema ?TABLE?        Show the CREATE statements\n"
503   ".separator STRING      Change separator string for \"list\" mode\n"
504   ".show                  Show the current values for various settings\n"
505   ".tables ?PATTERN?      List names of tables matching a pattern\n"
506   ".timeout MS            Try opening locked tables for MS milliseconds\n"
507   ".width NUM NUM ...     Set column widths for \"column\" mode\n"
508 ;
509 
510 /* Forward reference */
511 static void process_input(struct callback_data *p, FILE *in);
512 
513 /*
514 ** Make sure the database is open.  If it is not, then open it.  If
515 ** the database fails to open, print an error message and exit.
516 */
517 static void open_db(struct callback_data *p){
518   if( p->db==0 ){
519     char *zErrMsg = 0;
520 #ifdef SQLITE_HAS_CODEC
521     int n = p->zKey ? strlen(p->zKey) : 0;
522     db = p->db = sqlite_open_encrypted(p->zDbFilename, p->zKey, n, 0, &zErrMsg);
523 #else
524     db = p->db = sqlite_open(p->zDbFilename, 0, &zErrMsg);
525 #endif
526     if( p->db==0 ){
527       if( zErrMsg ){
528         fprintf(stderr,"Unable to open database \"%s\": %s\n",
529            p->zDbFilename, zErrMsg);
530       }else{
531         fprintf(stderr,"Unable to open database %s\n", p->zDbFilename);
532       }
533       exit(1);
534     }
535   }
536 }
537 
538 /*
539 ** If an input line begins with "." then invoke this routine to
540 ** process that line.
541 **
542 ** Return 1 to exit and 0 to continue.
543 */
544 static int do_meta_command(char *zLine, struct callback_data *p){
545   int i = 1;
546   int nArg = 0;
547   int n, c;
548   int rc = 0;
549   char *azArg[50];
550 
551   /* Parse the input line into tokens.
552   */
553   while( zLine[i] && nArg<ArraySize(azArg) ){
554     while( isspace(zLine[i]) ){ i++; }
555     if( zLine[i]==0 ) break;
556     if( zLine[i]=='\'' || zLine[i]=='"' ){
557       int delim = zLine[i++];
558       azArg[nArg++] = &zLine[i];
559       while( zLine[i] && zLine[i]!=delim ){ i++; }
560       if( zLine[i]==delim ){
561         zLine[i++] = 0;
562       }
563     }else{
564       azArg[nArg++] = &zLine[i];
565       while( zLine[i] && !isspace(zLine[i]) ){ i++; }
566       if( zLine[i] ) zLine[i++] = 0;
567     }
568   }
569 
570   /* Process the input line.
571   */
572   if( nArg==0 ) return rc;
573   n = strlen(azArg[0]);
574   c = azArg[0][0];
575   if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
576     struct callback_data data;
577     char *zErrMsg = 0;
578     open_db(p);
579     memcpy(&data, p, sizeof(data));
580     data.showHeader = 1;
581     data.mode = MODE_Column;
582     data.colWidth[0] = 3;
583     data.colWidth[1] = 15;
584     data.colWidth[2] = 58;
585     sqlite_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
586     if( zErrMsg ){
587       fprintf(stderr,"Error: %s\n", zErrMsg);
588       sqlite_freemem(zErrMsg);
589     }
590   }else
591 
592   if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
593     char *zErrMsg = 0;
594     open_db(p);
595     fprintf(p->out, "BEGIN TRANSACTION;\n");
596     if( nArg==1 ){
597       sqlite_exec(p->db,
598         "SELECT name, type, sql FROM sqlite_master "
599         "WHERE type!='meta' AND sql NOT NULL "
600         "ORDER BY substr(type,2,1), name",
601         dump_callback, p, &zErrMsg
602       );
603     }else{
604       int i;
605       for(i=1; i<nArg && zErrMsg==0; i++){
606         sqlite_exec_printf(p->db,
607           "SELECT name, type, sql FROM sqlite_master "
608           "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOT NULL "
609           "ORDER BY substr(type,2,1), name",
610           dump_callback, p, &zErrMsg, azArg[i]
611         );
612       }
613     }
614     if( zErrMsg ){
615       fprintf(stderr,"Error: %s\n", zErrMsg);
616       sqlite_freemem(zErrMsg);
617     }else{
618       fprintf(p->out, "COMMIT;\n");
619     }
620   }else
621 
622   if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
623     int j;
624     char *z = azArg[1];
625     int val = atoi(azArg[1]);
626     for(j=0; z[j]; j++){
627       if( isupper(z[j]) ) z[j] = tolower(z[j]);
628     }
629     if( strcmp(z,"on")==0 ){
630       val = 1;
631     }else if( strcmp(z,"yes")==0 ){
632       val = 1;
633     }
634     p->echoOn = val;
635   }else
636 
637   if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
638     rc = 1;
639   }else
640 
641   if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
642     int j;
643     char *z = nArg>=2 ? azArg[1] : "1";
644     int val = atoi(z);
645     for(j=0; z[j]; j++){
646       if( isupper(z[j]) ) z[j] = tolower(z[j]);
647     }
648     if( strcmp(z,"on")==0 ){
649       val = 1;
650     }else if( strcmp(z,"yes")==0 ){
651       val = 1;
652     }
653     if(val == 1) {
654       if(!p->explainPrev.valid) {
655         p->explainPrev.valid = 1;
656         p->explainPrev.mode = p->mode;
657         p->explainPrev.showHeader = p->showHeader;
658         memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
659       }
660       /* We could put this code under the !p->explainValid
661       ** condition so that it does not execute if we are already in
662       ** explain mode. However, always executing it allows us an easy
663       ** was to reset to explain mode in case the user previously
664       ** did an .explain followed by a .width, .mode or .header
665       ** command.
666       */
667       p->mode = MODE_Column;
668       p->showHeader = 1;
669       memset(p->colWidth,0,ArraySize(p->colWidth));
670       p->colWidth[0] = 4;
671       p->colWidth[1] = 12;
672       p->colWidth[2] = 10;
673       p->colWidth[3] = 10;
674       p->colWidth[4] = 35;
675     }else if (p->explainPrev.valid) {
676       p->explainPrev.valid = 0;
677       p->mode = p->explainPrev.mode;
678       p->showHeader = p->explainPrev.showHeader;
679       memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
680     }
681   }else
682 
683   if( c=='h' && (strncmp(azArg[0], "header", n)==0
684                  ||
685                  strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
686     int j;
687     char *z = azArg[1];
688     int val = atoi(azArg[1]);
689     for(j=0; z[j]; j++){
690       if( isupper(z[j]) ) z[j] = tolower(z[j]);
691     }
692     if( strcmp(z,"on")==0 ){
693       val = 1;
694     }else if( strcmp(z,"yes")==0 ){
695       val = 1;
696     }
697     p->showHeader = val;
698   }else
699 
700   if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
701     fprintf(stderr,zHelp);
702   }else
703 
704   if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
705     struct callback_data data;
706     char *zErrMsg = 0;
707     open_db(p);
708     memcpy(&data, p, sizeof(data));
709     data.showHeader = 0;
710     data.mode = MODE_List;
711     sqlite_exec_printf(p->db,
712       "SELECT name FROM sqlite_master "
713       "WHERE type='index' AND tbl_name LIKE '%q' "
714       "UNION ALL "
715       "SELECT name FROM sqlite_temp_master "
716       "WHERE type='index' AND tbl_name LIKE '%q' "
717       "ORDER BY 1",
718       callback, &data, &zErrMsg, azArg[1], azArg[1]
719     );
720     if( zErrMsg ){
721       fprintf(stderr,"Error: %s\n", zErrMsg);
722       sqlite_freemem(zErrMsg);
723     }
724   }else
725 
726   if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
727     int n2 = strlen(azArg[1]);
728     if( strncmp(azArg[1],"line",n2)==0
729         ||
730         strncmp(azArg[1],"lines",n2)==0 ){
731       p->mode = MODE_Line;
732     }else if( strncmp(azArg[1],"column",n2)==0
733               ||
734               strncmp(azArg[1],"columns",n2)==0 ){
735       p->mode = MODE_Column;
736     }else if( strncmp(azArg[1],"list",n2)==0 ){
737       p->mode = MODE_List;
738     }else if( strncmp(azArg[1],"html",n2)==0 ){
739       p->mode = MODE_Html;
740     }else if( strncmp(azArg[1],"insert",n2)==0 ){
741       p->mode = MODE_Insert;
742       if( nArg>=3 ){
743         set_table_name(p, azArg[2]);
744       }else{
745         set_table_name(p, "table");
746       }
747     }else {
748       fprintf(stderr,"mode should be on of: column html insert line list\n");
749     }
750   }else
751 
752   if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
753     sprintf(p->nullvalue, "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
754   }else
755 
756   if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
757     if( p->out!=stdout ){
758       fclose(p->out);
759     }
760     if( strcmp(azArg[1],"stdout")==0 ){
761       p->out = stdout;
762       strcpy(p->outfile,"stdout");
763     }else{
764       p->out = fopen(azArg[1], "wb");
765       if( p->out==0 ){
766         fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
767         p->out = stdout;
768       } else {
769          strcpy(p->outfile,azArg[1]);
770       }
771     }
772   }else
773 
774   if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
775     if( nArg >= 2) {
776       strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
777     }
778     if( nArg >= 3) {
779       strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
780     }
781   }else
782 
783   if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
784     rc = 1;
785   }else
786 
787   if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
788     FILE *alt = fopen(azArg[1], "rb");
789     if( alt==0 ){
790       fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
791     }else{
792       process_input(p, alt);
793       fclose(alt);
794     }
795   }else
796 
797 #ifdef SQLITE_HAS_CODEC
798   if( c=='r' && strncmp(azArg[0],"rekey", n)==0 && nArg==4 ){
799     char *zOld = p->zKey;
800     if( zOld==0 ) zOld = "";
801     if( strcmp(azArg[1],zOld) ){
802       fprintf(stderr,"old key is incorrect\n");
803     }else if( strcmp(azArg[2], azArg[3]) ){
804       fprintf(stderr,"2nd copy of new key does not match the 1st\n");
805     }else{
806       sqlite_freemem(p->zKey);
807       p->zKey = sqlite_mprintf("%s", azArg[2]);
808       sqlite_rekey(p->db, p->zKey, strlen(p->zKey));
809     }
810   }else
811 #endif
812 
813   if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
814     struct callback_data data;
815     char *zErrMsg = 0;
816     open_db(p);
817     memcpy(&data, p, sizeof(data));
818     data.showHeader = 0;
819     data.mode = MODE_Semi;
820     if( nArg>1 ){
821       extern int sqliteStrICmp(const char*,const char*);
822       if( sqliteStrICmp(azArg[1],"sqlite_master")==0 ){
823         char *new_argv[2], *new_colv[2];
824         new_argv[0] = "CREATE TABLE sqlite_master (\n"
825                       "  type text,\n"
826                       "  name text,\n"
827                       "  tbl_name text,\n"
828                       "  rootpage integer,\n"
829                       "  sql text\n"
830                       ")";
831         new_argv[1] = 0;
832         new_colv[0] = "sql";
833         new_colv[1] = 0;
834         callback(&data, 1, new_argv, new_colv);
835       }else if( sqliteStrICmp(azArg[1],"sqlite_temp_master")==0 ){
836         char *new_argv[2], *new_colv[2];
837         new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
838                       "  type text,\n"
839                       "  name text,\n"
840                       "  tbl_name text,\n"
841                       "  rootpage integer,\n"
842                       "  sql text\n"
843                       ")";
844         new_argv[1] = 0;
845         new_colv[0] = "sql";
846         new_colv[1] = 0;
847         callback(&data, 1, new_argv, new_colv);
848       }else{
849         sqlite_exec_printf(p->db,
850           "SELECT sql FROM "
851           "  (SELECT * FROM sqlite_master UNION ALL"
852           "   SELECT * FROM sqlite_temp_master) "
853           "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOTNULL "
854           "ORDER BY substr(type,2,1), name",
855           callback, &data, &zErrMsg, azArg[1]);
856       }
857     }else{
858       sqlite_exec(p->db,
859          "SELECT sql FROM "
860          "  (SELECT * FROM sqlite_master UNION ALL"
861          "   SELECT * FROM sqlite_temp_master) "
862          "WHERE type!='meta' AND sql NOTNULL "
863          "ORDER BY substr(type,2,1), name",
864          callback, &data, &zErrMsg
865       );
866     }
867     if( zErrMsg ){
868       fprintf(stderr,"Error: %s\n", zErrMsg);
869       sqlite_freemem(zErrMsg);
870     }
871   }else
872 
873   if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
874     sprintf(p->separator, "%.*s", (int)ArraySize(p->separator)-1, azArg[1]);
875   }else
876 
877   if( c=='s' && strncmp(azArg[0], "show", n)==0){
878     int i;
879     fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
880     fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
881     fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
882     fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
883     fprintf(p->out,"%9.9s: %s\n","nullvalue", p->nullvalue);
884     fprintf(p->out,"%9.9s: %s\n","output",
885                                  strlen(p->outfile) ? p->outfile : "stdout");
886     fprintf(p->out,"%9.9s: %s\n","separator", p->separator);
887     fprintf(p->out,"%9.9s: ","width");
888     for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
889         fprintf(p->out,"%d ",p->colWidth[i]);
890     }
891     fprintf(p->out,"\n\n");
892   }else
893 
894   if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
895     char **azResult;
896     int nRow, rc;
897     char *zErrMsg;
898     open_db(p);
899     if( nArg==1 ){
900       rc = sqlite_get_table(p->db,
901         "SELECT name FROM sqlite_master "
902         "WHERE type IN ('table','view') "
903         "UNION ALL "
904         "SELECT name FROM sqlite_temp_master "
905         "WHERE type IN ('table','view') "
906         "ORDER BY 1",
907         &azResult, &nRow, 0, &zErrMsg
908       );
909     }else{
910       rc = sqlite_get_table_printf(p->db,
911         "SELECT name FROM sqlite_master "
912         "WHERE type IN ('table','view') AND name LIKE '%%%q%%' "
913         "UNION ALL "
914         "SELECT name FROM sqlite_temp_master "
915         "WHERE type IN ('table','view') AND name LIKE '%%%q%%' "
916         "ORDER BY 1",
917         &azResult, &nRow, 0, &zErrMsg, azArg[1], azArg[1]
918       );
919     }
920     if( zErrMsg ){
921       fprintf(stderr,"Error: %s\n", zErrMsg);
922       sqlite_freemem(zErrMsg);
923     }
924     if( rc==SQLITE_OK ){
925       int len, maxlen = 0;
926       int i, j;
927       int nPrintCol, nPrintRow;
928       for(i=1; i<=nRow; i++){
929         if( azResult[i]==0 ) continue;
930         len = strlen(azResult[i]);
931         if( len>maxlen ) maxlen = len;
932       }
933       nPrintCol = 80/(maxlen+2);
934       if( nPrintCol<1 ) nPrintCol = 1;
935       nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
936       for(i=0; i<nPrintRow; i++){
937         for(j=i+1; j<=nRow; j+=nPrintRow){
938           char *zSp = j<=nPrintRow ? "" : "  ";
939           printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
940         }
941         printf("\n");
942       }
943     }
944     sqlite_free_table(azResult);
945   }else
946 
947   if( c=='t' && n>1 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
948     open_db(p);
949     sqlite_busy_timeout(p->db, atoi(azArg[1]));
950   }else
951 
952   if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
953     int j;
954     for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
955       p->colWidth[j-1] = atoi(azArg[j]);
956     }
957   }else
958 
959   {
960     fprintf(stderr, "unknown command or invalid arguments: "
961       " \"%s\". Enter \".help\" for help\n", azArg[0]);
962   }
963 
964   return rc;
965 }
966 
967 /*
968 ** Return TRUE if the last non-whitespace character in z[] is a semicolon.
969 ** z[] is N characters long.
970 */
971 static int _ends_with_semicolon(const char *z, int N){
972   while( N>0 && isspace(z[N-1]) ){ N--; }
973   return N>0 && z[N-1]==';';
974 }
975 
976 /*
977 ** Test to see if a line consists entirely of whitespace.
978 */
979 static int _all_whitespace(const char *z){
980   for(; *z; z++){
981     if( isspace(*z) ) continue;
982     if( *z=='/' && z[1]=='*' ){
983       z += 2;
984       while( *z && (*z!='*' || z[1]!='/') ){ z++; }
985       if( *z==0 ) return 0;
986       z++;
987       continue;
988     }
989     if( *z=='-' && z[1]=='-' ){
990       z += 2;
991       while( *z && *z!='\n' ){ z++; }
992       if( *z==0 ) return 1;
993       continue;
994     }
995     return 0;
996   }
997   return 1;
998 }
999 
1000 /*
1001 ** Return TRUE if the line typed in is an SQL command terminator other
1002 ** than a semi-colon.  The SQL Server style "go" command is understood
1003 ** as is the Oracle "/".
1004 */
1005 static int _is_command_terminator(const char *zLine){
1006   extern int sqliteStrNICmp(const char*,const char*,int);
1007   while( isspace(*zLine) ){ zLine++; };
1008   if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1;  /* Oracle */
1009   if( sqliteStrNICmp(zLine,"go",2)==0 && _all_whitespace(&zLine[2]) ){
1010     return 1;  /* SQL Server */
1011   }
1012   return 0;
1013 }
1014 
1015 /*
1016 ** Read input from *in and process it.  If *in==0 then input
1017 ** is interactive - the user is typing it it.  Otherwise, input
1018 ** is coming from a file or device.  A prompt is issued and history
1019 ** is saved only if input is interactive.  An interrupt signal will
1020 ** cause this routine to exit immediately, unless input is interactive.
1021 */
1022 static void process_input(struct callback_data *p, FILE *in){
1023   char *zLine;
1024   char *zSql = 0;
1025   int nSql = 0;
1026   char *zErrMsg;
1027   int rc;
1028   while( fflush(p->out), (zLine = one_input_line(zSql, in))!=0 ){
1029     if( seenInterrupt ){
1030       if( in!=0 ) break;
1031       seenInterrupt = 0;
1032     }
1033     if( p->echoOn ) printf("%s\n", zLine);
1034     if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
1035     if( zLine && zLine[0]=='.' && nSql==0 ){
1036       int rc = do_meta_command(zLine, p);
1037       free(zLine);
1038       if( rc ) break;
1039       continue;
1040     }
1041     if( _is_command_terminator(zLine) ){
1042       strcpy(zLine,";");
1043     }
1044     if( zSql==0 ){
1045       int i;
1046       for(i=0; zLine[i] && isspace(zLine[i]); i++){}
1047       if( zLine[i]!=0 ){
1048         nSql = strlen(zLine);
1049         zSql = malloc( nSql+1 );
1050         strcpy(zSql, zLine);
1051       }
1052     }else{
1053       int len = strlen(zLine);
1054       zSql = realloc( zSql, nSql + len + 2 );
1055       if( zSql==0 ){
1056         fprintf(stderr,"%s: out of memory!\n", Argv0);
1057         exit(1);
1058       }
1059       strcpy(&zSql[nSql++], "\n");
1060       strcpy(&zSql[nSql], zLine);
1061       nSql += len;
1062     }
1063     free(zLine);
1064     if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite_complete(zSql) ){
1065       p->cnt = 0;
1066       open_db(p);
1067       rc = sqlite_exec(p->db, zSql, callback, p, &zErrMsg);
1068       if( rc || zErrMsg ){
1069         if( in!=0 && !p->echoOn ) printf("%s\n",zSql);
1070         if( zErrMsg!=0 ){
1071           printf("SQL error: %s\n", zErrMsg);
1072           sqlite_freemem(zErrMsg);
1073           zErrMsg = 0;
1074         }else{
1075           printf("SQL error: %s\n", sqlite_error_string(rc));
1076         }
1077       }
1078       free(zSql);
1079       zSql = 0;
1080       nSql = 0;
1081     }
1082   }
1083   if( zSql ){
1084     if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
1085     free(zSql);
1086   }
1087 }
1088 
1089 /*
1090 ** Return a pathname which is the user's home directory.  A
1091 ** 0 return indicates an error of some kind.  Space to hold the
1092 ** resulting string is obtained from malloc().  The calling
1093 ** function should free the result.
1094 */
1095 static char *find_home_dir(void){
1096   char *home_dir = NULL;
1097 
1098 #if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)
1099   struct passwd *pwent;
1100   uid_t uid = getuid();
1101   if( (pwent=getpwuid(uid)) != NULL) {
1102     home_dir = pwent->pw_dir;
1103   }
1104 #endif
1105 
1106 #ifdef __MACOS__
1107   char home_path[_MAX_PATH+1];
1108   home_dir = getcwd(home_path, _MAX_PATH);
1109 #endif
1110 
1111   if (!home_dir) {
1112     home_dir = getenv("HOME");
1113     if (!home_dir) {
1114       home_dir = getenv("HOMEPATH"); /* Windows? */
1115     }
1116   }
1117 
1118 #if defined(_WIN32) || defined(WIN32)
1119   if (!home_dir) {
1120     home_dir = "c:";
1121   }
1122 #endif
1123 
1124   if( home_dir ){
1125     char *z = malloc( strlen(home_dir)+1 );
1126     if( z ) strcpy(z, home_dir);
1127     home_dir = z;
1128   }
1129 
1130   return home_dir;
1131 }
1132 
1133 /*
1134 ** Read input from the file given by sqliterc_override.  Or if that
1135 ** parameter is NULL, take input from ~/.sqliterc
1136 */
1137 static void process_sqliterc(
1138   struct callback_data *p,        /* Configuration data */
1139   const char *sqliterc_override   /* Name of config file. NULL to use default */
1140 ){
1141   char *home_dir = NULL;
1142   const char *sqliterc = sqliterc_override;
1143   char *zBuf;
1144   FILE *in = NULL;
1145 
1146   if (sqliterc == NULL) {
1147     home_dir = find_home_dir();
1148     if( home_dir==0 ){
1149       fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
1150       return;
1151     }
1152     zBuf = malloc(strlen(home_dir) + 15);
1153     if( zBuf==0 ){
1154       fprintf(stderr,"%s: out of memory!\n", Argv0);
1155       exit(1);
1156     }
1157     sprintf(zBuf,"%s/.sqliterc",home_dir);
1158     free(home_dir);
1159     sqliterc = (const char*)zBuf;
1160   }
1161   in = fopen(sqliterc,"rb");
1162   if( in ){
1163     if( isatty(fileno(stdout)) ){
1164       printf("Loading resources from %s\n",sqliterc);
1165     }
1166     process_input(p,in);
1167     fclose(in);
1168   }
1169   return;
1170 }
1171 
1172 /*
1173 ** Show available command line options
1174 */
1175 static const char zOptions[] =
1176   "   -init filename       read/process named file\n"
1177   "   -echo                print commands before execution\n"
1178   "   -[no]header          turn headers on or off\n"
1179   "   -column              set output mode to 'column'\n"
1180   "   -html                set output mode to HTML\n"
1181 #ifdef SQLITE_HAS_CODEC
1182   "   -key KEY             encryption key\n"
1183 #endif
1184   "   -line                set output mode to 'line'\n"
1185   "   -list                set output mode to 'list'\n"
1186   "   -separator 'x'       set output field separator (|)\n"
1187   "   -nullvalue 'text'    set text string for NULL values\n"
1188   "   -version             show SQLite version\n"
1189   "   -help                show this text, also show dot-commands\n"
1190 ;
1191 static void usage(int showDetail){
1192   fprintf(stderr, "Usage: %s [OPTIONS] FILENAME [SQL]\n", Argv0);
1193   if( showDetail ){
1194     fprintf(stderr, "Options are:\n%s", zOptions);
1195   }else{
1196     fprintf(stderr, "Use the -help option for additional information\n");
1197   }
1198   exit(1);
1199 }
1200 
1201 /*
1202 ** Initialize the state information in data
1203 */
1204 void main_init(struct callback_data *data) {
1205   memset(data, 0, sizeof(*data));
1206   data->mode = MODE_List;
1207   strcpy(data->separator,"|");
1208   data->showHeader = 0;
1209   strcpy(mainPrompt,"sqlite> ");
1210   strcpy(continuePrompt,"   ...> ");
1211 }
1212 
1213 int main(int argc, char **argv){
1214   char *zErrMsg = 0;
1215   struct callback_data data;
1216   const char *zInitFile = 0;
1217   char *zFirstCmd = 0;
1218   int i;
1219   extern int sqliteOsFileExists(const char*);
1220 
1221   sqlite_temp_directory = "/etc/svc/volatile";		/* SUNW addition */
1222 
1223 #ifdef __MACOS__
1224   argc = ccommand(&argv);
1225 #endif
1226 
1227   Argv0 = argv[0];
1228   main_init(&data);
1229 
1230   /* Make sure we have a valid signal handler early, before anything
1231   ** else is done.
1232   */
1233 #ifdef SIGINT
1234   signal(SIGINT, interrupt_handler);
1235 #endif
1236 
1237   /* Do an initial pass through the command-line argument to locate
1238   ** the name of the database file, the name of the initialization file,
1239   ** and the first command to execute.
1240   */
1241   for(i=1; i<argc-1; i++){
1242     if( argv[i][0]!='-' ) break;
1243     if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
1244       i++;
1245     }else if( strcmp(argv[i],"-init")==0 ){
1246       i++;
1247       zInitFile = argv[i];
1248     }else if( strcmp(argv[i],"-key")==0 ){
1249       i++;
1250       data.zKey = sqlite_mprintf("%s",argv[i]);
1251     }
1252   }
1253   if( i<argc ){
1254     data.zDbFilename = argv[i++];
1255   }else{
1256     data.zDbFilename = ":memory:";
1257   }
1258   if( i<argc ){
1259     zFirstCmd = argv[i++];
1260   }
1261   data.out = stdout;
1262 
1263   /* Go ahead and open the database file if it already exists.  If the
1264   ** file does not exist, delay opening it.  This prevents empty database
1265   ** files from being created if a user mistypes the database name argument
1266   ** to the sqlite command-line tool.
1267   */
1268   if( sqliteOsFileExists(data.zDbFilename) ){
1269     open_db(&data);
1270   }
1271 
1272   /* Process the initialization file if there is one.  If no -init option
1273   ** is given on the command line, look for a file named ~/.sqliterc and
1274   ** try to process it.
1275   */
1276   process_sqliterc(&data,zInitFile);
1277 
1278   /* Make a second pass through the command-line argument and set
1279   ** options.  This second pass is delayed until after the initialization
1280   ** file is processed so that the command-line arguments will override
1281   ** settings in the initialization file.
1282   */
1283   for(i=1; i<argc && argv[i][0]=='-'; i++){
1284     char *z = argv[i];
1285     if( strcmp(z,"-init")==0 || strcmp(z,"-key")==0 ){
1286       i++;
1287     }else if( strcmp(z,"-html")==0 ){
1288       data.mode = MODE_Html;
1289     }else if( strcmp(z,"-list")==0 ){
1290       data.mode = MODE_List;
1291     }else if( strcmp(z,"-line")==0 ){
1292       data.mode = MODE_Line;
1293     }else if( strcmp(z,"-column")==0 ){
1294       data.mode = MODE_Column;
1295     }else if( strcmp(z,"-separator")==0 ){
1296       i++;
1297       sprintf(data.separator,"%.*s",(int)sizeof(data.separator)-1,argv[i]);
1298     }else if( strcmp(z,"-nullvalue")==0 ){
1299       i++;
1300       sprintf(data.nullvalue,"%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
1301     }else if( strcmp(z,"-header")==0 ){
1302       data.showHeader = 1;
1303     }else if( strcmp(z,"-noheader")==0 ){
1304       data.showHeader = 0;
1305     }else if( strcmp(z,"-echo")==0 ){
1306       data.echoOn = 1;
1307     }else if( strcmp(z,"-version")==0 ){
1308       printf("%s\n", sqlite_version);
1309       return 1;
1310     }else if( strcmp(z,"-help")==0 ){
1311       usage(1);
1312     }else{
1313       fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
1314       fprintf(stderr,"Use -help for a list of options.\n");
1315       return 1;
1316     }
1317   }
1318 
1319   if( zFirstCmd ){
1320     /* Run just the command that follows the database name
1321     */
1322     if( zFirstCmd[0]=='.' ){
1323       do_meta_command(zFirstCmd, &data);
1324       exit(0);
1325     }else{
1326       int rc;
1327       open_db(&data);
1328       rc = sqlite_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
1329       if( rc!=0 && zErrMsg!=0 ){
1330         fprintf(stderr,"SQL error: %s\n", zErrMsg);
1331         exit(1);
1332       }
1333     }
1334   }else{
1335     /* Run commands received from standard input
1336     */
1337     if( isatty(fileno(stdout)) && isatty(fileno(stdin)) ){
1338       char *zHome;
1339       char *zHistory = 0;
1340       printf(
1341         "SQLite version %s\n"
1342         "Enter \".help\" for instructions\n",
1343         sqlite_version
1344       );
1345       zHome = find_home_dir();
1346       if( zHome && (zHistory = malloc(strlen(zHome)+20))!=0 ){
1347         sprintf(zHistory,"%s/.sqlite_history", zHome);
1348       }
1349       if( zHistory ) read_history(zHistory);
1350       process_input(&data, 0);
1351       if( zHistory ){
1352         stifle_history(100);
1353         write_history(zHistory);
1354       }
1355     }else{
1356       process_input(&data, stdin);
1357     }
1358   }
1359   set_table_name(&data, 0);
1360   if( db ) sqlite_close(db);
1361   return 0;
1362 }
1363