~ubuntu-branches/ubuntu/intrepid/digikam/intrepid

« back to all changes in this revision

Viewing changes to digikam/libs/sqlite2/shell.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2008-07-17 20:25:39 UTC
  • mfrom: (1.3.2 upstream) (37 hardy)
  • mto: This revision was merged to the branch mainline in revision 39.
  • Revision ID: james.westby@ubuntu.com-20080717202539-1bw3w3nrsso7yj4z
* New upstream release
  - digiKam 0.9.4 Release Plan (KDE3) ~ 13 July 08 (Closes: #490144)
* DEB_CONFIGURE_EXTRA_FLAGS := --without-included-sqlite3
* Debhelper compatibility level V7
* Install pixmaps in debian/*.install
* Add debian/digikam.lintian-overrides

Show diffs side-by-side

added added

removed removed

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