blob: f1fc9f58c0659a34a9d720864911b1060fb02cca [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
2** Copyright (c) 1999, 2000 D. Richard Hipp
3**
4** This program is free software; you can redistribute it and/or
5** modify it under the terms of the GNU General Public
6** License as published by the Free Software Foundation; either
7** version 2 of the License, or (at your option) any later version.
8**
9** This program is distributed in the hope that it will be useful,
10** but WITHOUT ANY WARRANTY; without even the implied warranty of
11** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12** General Public License for more details.
13**
14** You should have received a copy of the GNU General Public
15** License along with this library; if not, write to the
16** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17** Boston, MA 02111-1307, USA.
18**
19** Author contact information:
20** drh@hwaci.com
21** http://www.hwaci.com/drh/
22**
23*************************************************************************
24** This file contains code to implement the "sqlite" command line
25** utility for accessing SQLite databases.
26**
drh28bd4bc2000-06-15 15:57:22 +000027** $Id: shell.c,v 1.13 2000/06/15 15:57:23 drh Exp $
drh75897232000-05-29 14:26:00 +000028*/
29#include <stdlib.h>
30#include <string.h>
31#include <stdio.h>
32#include "sqlite.h"
33#include <unistd.h>
34#include <ctype.h>
35
36#if !defined(NO_READLINE)
drh8e7e7a22000-05-30 18:45:23 +000037# include <readline/readline.h>
38# include <readline/history.h>
39#else
40# define readline getline
41# define add_history(X)
drh75897232000-05-29 14:26:00 +000042#endif
43
44/*
drh8e7e7a22000-05-30 18:45:23 +000045** This routine reads a line of text from standard input, stores
46** the text in memory obtained from malloc() and returns a pointer
47** to the text. NULL is returned at end of file, or if malloc()
48** fails.
49**
50** The interface is like "readline" but no command-line editing
51** is done.
52*/
53static char *getline(char *zPrompt){
54 char *zLine;
55 int nLine;
drh8e7e7a22000-05-30 18:45:23 +000056 int n;
57 int eol;
58
59 if( zPrompt && *zPrompt ){
60 printf("%s",zPrompt);
61 fflush(stdout);
62 }
63 nLine = 100;
64 zLine = malloc( nLine );
65 if( zLine==0 ) return 0;
66 n = 0;
67 eol = 0;
68 while( !eol ){
69 if( n+100>nLine ){
70 nLine = nLine*2 + 100;
71 zLine = realloc(zLine, nLine);
72 if( zLine==0 ) return 0;
73 }
74 if( fgets(&zLine[n], nLine - n, stdin)==0 ){
75 if( n==0 ){
76 free(zLine);
77 return 0;
78 }
79 zLine[n] = 0;
80 eol = 1;
81 break;
82 }
83 while( zLine[n] ){ n++; }
84 if( n>0 && zLine[n-1]=='\n' ){
85 n--;
86 zLine[n] = 0;
87 eol = 1;
88 }
89 }
90 zLine = realloc( zLine, n+1 );
91 return zLine;
92}
93
94/*
95** Retrieve a single line of input text. "isatty" is true if text
96** is coming from a terminal. In that case, we issue a prompt and
97** attempt to use "readline" for command-line editing. If "isatty"
98** is false, use "getline" instead of "readline" and issue to prompt.
99**
100** zPrior is a string of prior text retrieved. If not the empty
101** string, then issue a continuation prompt.
102*/
103static char *one_input_line(const char *zPrior, int isatty){
104 char *zPrompt;
105 char *zResult;
106 if( !isatty ){
107 return getline(0);
108 }
109 if( zPrior && zPrior[0] ){
110 zPrompt = " ...> ";
111 }else{
112 zPrompt = "sqlite> ";
113 }
114 zResult = readline(zPrompt);
115 add_history(zResult);
116 return zResult;
117}
118
119/*
drh75897232000-05-29 14:26:00 +0000120** An pointer to an instance of this structure is passed from
121** the main program to the callback. This is used to communicate
122** state and mode information.
123*/
124struct callback_data {
drh28bd4bc2000-06-15 15:57:22 +0000125 sqlite *db; /* The database */
126 int cnt; /* Number of records displayed so far */
127 FILE *out; /* Write results here */
128 int mode; /* An output mode setting */
129 int showHeader; /* True to show column names in List or Column mode */
130 int escape; /* Escape this character when in MODE_List */
131 char zDestTable[250]; /* Name of destination table when MODE_Insert */
132 char separator[20]; /* Separator character for MODE_List */
133 int colWidth[30]; /* Width of each column when in column mode */
drh75897232000-05-29 14:26:00 +0000134};
135
136/*
137** These are the allowed modes.
138*/
139#define MODE_Line 0 /* One field per line. Blank line between records */
140#define MODE_Column 1 /* One record per line in neat columns */
141#define MODE_List 2 /* One record per line with a separator */
drh1e5d0e92000-05-31 23:33:17 +0000142#define MODE_Html 3 /* Generate an XHTML table */
drh28bd4bc2000-06-15 15:57:22 +0000143#define MODE_Insert 4 /* Generate SQL "insert" statements */
drh75897232000-05-29 14:26:00 +0000144
145/*
146** Number of elements in an array
147*/
148#define ArraySize(X) (sizeof(X)/sizeof(X[0]))
149
150/*
drh28bd4bc2000-06-15 15:57:22 +0000151** Return TRUE if the string supplied is a number of some kinds.
152*/
153static int is_numeric(const char *z){
154 int seen_digit = 0;
155 if( *z=='-' || *z=='+' ){
156 z++;
157 }
158 while( isdigit(*z) ){
159 seen_digit = 1;
160 z++;
161 }
162 if( seen_digit && *z=='.' ){
163 z++;
164 while( isdigit(*z) ){ z++; }
165 }
166 if( seen_digit && (*z=='e' || *z=='E')
167 && (isdigit(z[1]) || ((z[1]=='-' || z[1]=='+') && isdigit(z[2])))
168 ){
169 z+=2;
170 while( isdigit(*z) ){ z++; }
171 }
172 return seen_digit && *z==0;
173}
174
175/*
176** Output the given string as a quoted string using SQL quoting conventions.
177*/
178static void output_quoted_string(FILE *out, const char *z){
179 int i;
180 int nSingle = 0;
181 int nDouble = 0;
182 for(i=0; z[i]; i++){
183 if( z[i]=='\'' ) nSingle++;
184 else if( z[i]=='"' ) nDouble++;
185 }
186 if( nSingle==0 ){
187 fprintf(out,"'%s'",z);
188 }else if( nDouble==0 ){
189 fprintf(out,"\"%s\"",z);
190 }else{
191 fprintf(out,"'");
192 while( *z ){
193 for(i=0; z[i] && z[i]!='\''; i++){}
194 if( i==0 ){
195 fprintf(out,"''");
196 z++;
197 }else if( z[i]=='\'' ){
198 fprintf(out,"%.*s''",i,z);
199 z += i+1;
200 }else{
201 fprintf(out,"%s'",z);
202 break;
203 }
204 }
205 }
206}
207
208/*
drh75897232000-05-29 14:26:00 +0000209** This is the callback routine that the SQLite library
210** invokes for each row of a query result.
211*/
212static int callback(void *pArg, int nArg, char **azArg, char **azCol){
213 int i;
214 struct callback_data *p = (struct callback_data*)pArg;
215 switch( p->mode ){
216 case MODE_Line: {
217 if( p->cnt++>0 ) fprintf(p->out,"\n");
218 for(i=0; i<nArg; i++){
drhc61053b2000-06-04 12:58:36 +0000219 fprintf(p->out,"%s = %s\n", azCol[i], azArg[i] ? azArg[i] : 0);
drh75897232000-05-29 14:26:00 +0000220 }
221 break;
222 }
223 case MODE_Column: {
224 if( p->cnt++==0 && p->showHeader ){
225 for(i=0; i<nArg; i++){
226 int w;
227 if( i<ArraySize(p->colWidth) && p->colWidth[i]>0 ){
228 w = p->colWidth[i];
229 }else{
230 w = 10;
231 }
232 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
233 }
234 for(i=0; i<nArg; i++){
235 int w;
236 if( i<ArraySize(p->colWidth) && p->colWidth[i]>0 ){
237 w = p->colWidth[i];
238 }else{
239 w = 10;
240 }
drh1e5d0e92000-05-31 23:33:17 +0000241 fprintf(p->out,"%-*.*s%s",w,w,"-------------------------------------"
242 "------------------------------------------------------------",
drh75897232000-05-29 14:26:00 +0000243 i==nArg-1 ? "\n": " ");
244 }
245 }
246 for(i=0; i<nArg; i++){
247 int w;
248 if( i<ArraySize(p->colWidth) && p->colWidth[i]>0 ){
249 w = p->colWidth[i];
250 }else{
251 w = 10;
252 }
drhc61053b2000-06-04 12:58:36 +0000253 fprintf(p->out,"%-*.*s%s",w,w,
254 azArg[i] ? azArg[i] : "", i==nArg-1 ? "\n": " ");
drh75897232000-05-29 14:26:00 +0000255 }
256 break;
257 }
258 case MODE_List: {
259 if( p->cnt++==0 && p->showHeader ){
260 for(i=0; i<nArg; i++){
261 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
262 }
263 }
264 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000265 char *z = azArg[i];
266 if( z==0 ) z = "";
267 while( *z ){
268 int j;
269 for(j=0; z[j] && z[j]!=p->escape && z[j]!='\\'; j++){}
270 if( j>0 ){
271 fprintf(p->out, "%.*s", j, z);
272 }
273 if( z[j] ){
274 fprintf(p->out, "\\%c", z[j]);
drh670f74f2000-06-07 02:04:22 +0000275 z++;
drh4c653a02000-06-07 01:27:47 +0000276 }
drh73755922000-06-07 01:33:42 +0000277 z += j;
drh4c653a02000-06-07 01:27:47 +0000278 }
279 fprintf(p->out, "%s", i==nArg-1 ? "\n" : p->separator);
drh75897232000-05-29 14:26:00 +0000280 }
281 break;
282 }
drh1e5d0e92000-05-31 23:33:17 +0000283 case MODE_Html: {
284 if( p->cnt++==0 && p->showHeader ){
285 fprintf(p->out,"<TR>");
286 for(i=0; i<nArg; i++){
287 fprintf(p->out,"<TH>%s</TH>",azCol[i]);
288 }
289 fprintf(p->out,"</TR>\n");
290 }
drh28bd4bc2000-06-15 15:57:22 +0000291 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000292 for(i=0; i<nArg; i++){
drh28bd4bc2000-06-15 15:57:22 +0000293 fprintf(p->out,"<TD>%s</TD>",azArg[i] ? azArg[i] : "");
drh1e5d0e92000-05-31 23:33:17 +0000294 }
drh28bd4bc2000-06-15 15:57:22 +0000295 fprintf(p->out,"</TD></TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000296 break;
297 }
drh28bd4bc2000-06-15 15:57:22 +0000298 case MODE_Insert: {
299 fprintf(p->out,"INSERT INTO '%s' VALUES(",p->zDestTable);
300 for(i=0; i<nArg; i++){
301 char *zSep = i>0 ? ",": "";
302 if( azArg[i]==0 ){
303 fprintf(p->out,"%sNULL",zSep);
304 }else if( is_numeric(azArg[i]) ){
305 fprintf(p->out,"%s%s",zSep, azArg[i]);
306 }else{
307 if( zSep[0] ) fprintf(p->out,"%s",zSep);
308 output_quoted_string(p->out, azArg[i]);
309 }
310 }
311 fprintf(p->out,");\n");
312 }
drh75897232000-05-29 14:26:00 +0000313 }
314 return 0;
315}
316
317/*
drh4c653a02000-06-07 01:27:47 +0000318** This is a different callback routine used for dumping the database.
319** Each row received by this callback consists of a table name,
320** the table type ("index" or "table") and SQL to create the table.
321** This routine should print text sufficient to recreate the table.
322*/
323static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
324 struct callback_data *pData = (struct callback_data *)pArg;
325 if( nArg!=3 ) return 1;
326 fprintf(pData->out, "%s;\n", azArg[2]);
327 if( strcmp(azArg[1],"table")==0 ){
328 struct callback_data d2;
329 char zSql[1000];
330 d2 = *pData;
331 d2.mode = MODE_List;
drh670f74f2000-06-07 02:04:22 +0000332 d2.escape = '\t';
drh4c653a02000-06-07 01:27:47 +0000333 strcpy(d2.separator,"\t");
334 fprintf(pData->out, "COPY '%s' FROM STDIN;\n", azArg[0]);
335 sprintf(zSql, "SELECT * FROM '%s'", azArg[0]);
336 sqlite_exec(pData->db, zSql, callback, &d2, 0);
337 fprintf(pData->out, "\\.\n");
338 }
drh73755922000-06-07 01:33:42 +0000339 fprintf(pData->out, "VACUUM '%s';\n", azArg[0]);
drh4c653a02000-06-07 01:27:47 +0000340 return 0;
341}
342
343/*
drh75897232000-05-29 14:26:00 +0000344** Text of a help message
345*/
346static char zHelp[] =
drh4c653a02000-06-07 01:27:47 +0000347 ".dump ?TABLE? ... Dump the database in an text format\n"
drh75897232000-05-29 14:26:00 +0000348 ".exit Exit this program\n"
349 ".explain Set output mode suitable for EXPLAIN\n"
350 ".header ON|OFF Turn display of headers on or off\n"
351 ".help Show this message\n"
352 ".indices TABLE Show names of all indices on TABLE\n"
drh1e5d0e92000-05-31 23:33:17 +0000353 ".mode MODE Set mode to one of \"line\", \"column\", "
354 "\"list\", or \"html\"\n"
drh75897232000-05-29 14:26:00 +0000355 ".output FILENAME Send output to FILENAME\n"
356 ".output stdout Send output to the screen\n"
357 ".schema ?TABLE? Show the CREATE statements\n"
358 ".separator STRING Change separator string for \"list\" mode\n"
359 ".tables List names all tables in the database\n"
360 ".width NUM NUM ... Set column widths for \"column\" mode\n"
361;
362
363/*
364** If an input line begins with "." then invoke this routine to
365** process that line.
366*/
367static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
368 int i = 1;
369 int nArg = 0;
370 int n, c;
371 char *azArg[50];
372
373 /* Parse the input line into tokens.
374 */
375 while( zLine[i] && nArg<ArraySize(azArg) ){
376 while( isspace(zLine[i]) ){ i++; }
377 if( zLine[i]=='\'' || zLine[i]=='"' ){
378 int delim = zLine[i++];
379 azArg[nArg++] = &zLine[i];
380 while( zLine[i] && zLine[i]!=delim ){ i++; }
381 if( zLine[i]==delim ){
382 zLine[i++] = 0;
383 }
384 }else{
385 azArg[nArg++] = &zLine[i];
386 while( zLine[i] && !isspace(zLine[i]) ){ i++; }
387 if( zLine[i] ) zLine[i++] = 0;
388 }
389 }
390
391 /* Process the input line.
392 */
393 if( nArg==0 ) return;
394 n = strlen(azArg[0]);
395 c = azArg[0][0];
drh4c653a02000-06-07 01:27:47 +0000396
397 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
398 char *zErrMsg = 0;
399 char zSql[1000];
400 if( nArg==1 ){
401 sprintf(zSql, "SELECT name, type, sql FROM sqlite_master "
402 "ORDER BY tbl_name, type DESC, name");
403 sqlite_exec(db, zSql, dump_callback, p, &zErrMsg);
404 }else{
405 int i;
406 for(i=1; i<nArg && zErrMsg==0; i++){
407 sprintf(zSql, "SELECT name, type, sql FROM sqlite_master "
408 "WHERE tbl_name LIKE '%.800s'"
409 "ORDER BY type DESC, name", azArg[i]);
410 sqlite_exec(db, zSql, dump_callback, p, &zErrMsg);
411
412 }
413 }
414 if( zErrMsg ){
415 fprintf(stderr,"Error: %s\n", zErrMsg);
416 free(zErrMsg);
417 }
418 }else
drh75897232000-05-29 14:26:00 +0000419
420 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
421 exit(0);
422 }else
423
424 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
425 p->mode = MODE_Column;
426 p->showHeader = 1;
427 p->colWidth[0] = 4;
428 p->colWidth[1] = 12;
429 p->colWidth[2] = 5;
430 p->colWidth[3] = 5;
431 p->colWidth[4] = 40;
432 }else
433
434 if( c=='h' && strncmp(azArg[0], "header", n)==0 && nArg>1 ){
435 int j;
436 char *z = azArg[1];
437 int val = atoi(azArg[1]);
438 for(j=0; z[j]; j++){
439 if( isupper(z[j]) ) z[j] = tolower(z[j]);
440 }
441 if( strcmp(z,"on")==0 ){
442 val = 1;
443 }else if( strcmp(z,"yes")==0 ){
444 val = 1;
445 }
446 p->showHeader = val;
447 }else
448
449 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
450 fprintf(stderr,zHelp);
451 }else
452
453 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
454 struct callback_data data;
455 char *zErrMsg = 0;
456 char zSql[1000];
457 memcpy(&data, p, sizeof(data));
458 data.showHeader = 0;
459 data.mode = MODE_List;
460 sprintf(zSql, "SELECT name FROM sqlite_master "
drh4c653a02000-06-07 01:27:47 +0000461 "WHERE type='index' AND tbl_name LIKE '%.800s' "
drh305cea62000-05-29 17:44:25 +0000462 "ORDER BY name", azArg[1]);
drh75897232000-05-29 14:26:00 +0000463 sqlite_exec(db, zSql, callback, &data, &zErrMsg);
464 if( zErrMsg ){
465 fprintf(stderr,"Error: %s\n", zErrMsg);
466 free(zErrMsg);
467 }
468 }else
469
drh28bd4bc2000-06-15 15:57:22 +0000470 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
drh75897232000-05-29 14:26:00 +0000471 int n2 = strlen(azArg[1]);
472 if( strncmp(azArg[1],"line",n2)==0 ){
473 p->mode = MODE_Line;
474 }else if( strncmp(azArg[1],"column",n2)==0 ){
475 p->mode = MODE_Column;
476 }else if( strncmp(azArg[1],"list",n2)==0 ){
477 p->mode = MODE_List;
drh1e5d0e92000-05-31 23:33:17 +0000478 }else if( strncmp(azArg[1],"html",n2)==0 ){
479 p->mode = MODE_Html;
drh28bd4bc2000-06-15 15:57:22 +0000480 }else if( strncmp(azArg[1],"insert",n2)==0 ){
481 p->mode = MODE_Insert;
482 if( nArg>=3 ){
483 sprintf(p->zDestTable,"%.*s", (int)(sizeof(p->zDestTable)-1), azArg[2]);
484 }else{
485 sprintf(p->zDestTable,"table");
486 }
drh75897232000-05-29 14:26:00 +0000487 }
488 }else
489
490 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
491 if( p->out!=stdout ){
492 fclose(p->out);
493 }
494 if( strcmp(azArg[1],"stdout")==0 ){
495 p->out = stdout;
496 }else{
497 p->out = fopen(azArg[1], "w");
498 if( p->out==0 ){
499 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
500 p->out = stdout;
501 }
502 }
503 }else
504
505 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
506 struct callback_data data;
507 char *zErrMsg = 0;
508 char zSql[1000];
509 memcpy(&data, p, sizeof(data));
510 data.showHeader = 0;
511 data.mode = MODE_List;
512 if( nArg>1 ){
drh59692542000-06-07 00:12:24 +0000513 sprintf(zSql, "SELECT sql FROM sqlite_master "
514 "WHERE tbl_name LIKE '%.800s'"
515 "ORDER BY type DESC, name",
drh75897232000-05-29 14:26:00 +0000516 azArg[1]);
517 }else{
518 sprintf(zSql, "SELECT sql FROM sqlite_master "
519 "ORDER BY tbl_name, type DESC, name");
520 }
521 sqlite_exec(db, zSql, callback, &data, &zErrMsg);
522 if( zErrMsg ){
523 fprintf(stderr,"Error: %s\n", zErrMsg);
524 free(zErrMsg);
525 }
526 }else
527
528 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
529 sprintf(p->separator, "%.*s", (int)ArraySize(p->separator)-1, azArg[1]);
530 }else
531
532 if( c=='t' && strncmp(azArg[0], "tables", n)==0 ){
533 struct callback_data data;
534 char *zErrMsg = 0;
drh305cea62000-05-29 17:44:25 +0000535 static char zSql[] =
536 "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
drh75897232000-05-29 14:26:00 +0000537 memcpy(&data, p, sizeof(data));
538 data.showHeader = 0;
539 data.mode = MODE_List;
540 sqlite_exec(db, zSql, callback, &data, &zErrMsg);
541 if( zErrMsg ){
542 fprintf(stderr,"Error: %s\n", zErrMsg);
543 free(zErrMsg);
544 }
545 }else
546
547 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
548 int j;
549 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
550 p->colWidth[j-1] = atoi(azArg[j]);
551 }
552 }else
553
554 {
555 fprintf(stderr, "unknown command: \"%s\". Enter \".help\" for help\n",
556 azArg[0]);
557 }
558}
559
560int main(int argc, char **argv){
561 sqlite *db;
562 char *zErrMsg = 0;
drh1e5d0e92000-05-31 23:33:17 +0000563 char *argv0 = argv[0];
drh75897232000-05-29 14:26:00 +0000564 struct callback_data data;
565
drh1e5d0e92000-05-31 23:33:17 +0000566 memset(&data, 0, sizeof(data));
567 data.mode = MODE_List;
568 strcpy(data.separator,"|");
569 data.showHeader = 0;
570 while( argc>=2 && argv[1][0]=='-' ){
571 if( strcmp(argv[1],"-html")==0 ){
572 data.mode = MODE_Html;
573 argc--;
574 argv++;
575 }else if( strcmp(argv[1],"-list")==0 ){
576 data.mode = MODE_List;
577 argc--;
578 argv++;
579 }else if( strcmp(argv[1],"-line")==0 ){
580 data.mode = MODE_Line;
581 argc--;
582 argv++;
583 }else if( argc>=3 && strcmp(argv[0],"-separator")==0 ){
drhbed86902000-06-02 13:27:59 +0000584 sprintf(data.separator,"%.*s",(int)sizeof(data.separator)-1,argv[2]);
drh1e5d0e92000-05-31 23:33:17 +0000585 argc -= 2;
586 argv += 2;
587 }else if( strcmp(argv[1],"-header")==0 ){
588 data.showHeader = 1;
589 argc--;
590 argv++;
591 }else if( strcmp(argv[1],"-noheader")==0 ){
592 data.showHeader = 0;
593 argc--;
594 argv++;
595 }else{
596 fprintf(stderr,"%s: unknown option: %s\n", argv0, argv[1]);
597 return 1;
598 }
599 }
drh75897232000-05-29 14:26:00 +0000600 if( argc!=2 && argc!=3 ){
drh1e5d0e92000-05-31 23:33:17 +0000601 fprintf(stderr,"Usage: %s ?OPTIONS? FILENAME ?SQL?\n", argv0);
drh75897232000-05-29 14:26:00 +0000602 exit(1);
603 }
drh4c653a02000-06-07 01:27:47 +0000604 data.db = db = sqlite_open(argv[1], 0666, &zErrMsg);
drh75897232000-05-29 14:26:00 +0000605 if( db==0 ){
drhd1dedb82000-06-05 02:07:04 +0000606 if( zErrMsg ){
607 fprintf(stderr,"Unable to open database \"%s\": %s\n", argv[1], zErrMsg);
608 }else{
609 fprintf(stderr,"Unable to open database %s\n", argv[1]);
610 }
drh75897232000-05-29 14:26:00 +0000611 exit(1);
612 }
drh75897232000-05-29 14:26:00 +0000613 data.out = stdout;
614 if( argc==3 ){
drh75897232000-05-29 14:26:00 +0000615 if( sqlite_exec(db, argv[2], callback, &data, &zErrMsg)!=0 && zErrMsg!=0 ){
616 fprintf(stderr,"SQL error: %s\n", zErrMsg);
617 exit(1);
618 }
619 }else{
620 char *zLine;
621 char *zSql = 0;
622 int nSql = 0;
623 int istty = isatty(0);
drh75897232000-05-29 14:26:00 +0000624 if( istty ){
625 printf(
626 "Enter \".help\" for instructions\n"
627 );
628 }
drh8e7e7a22000-05-30 18:45:23 +0000629 while( (zLine = one_input_line(zSql, istty))!=0 ){
drh75897232000-05-29 14:26:00 +0000630 if( zLine && zLine[0]=='.' ){
631 do_meta_command(zLine, db, &data);
632 free(zLine);
633 continue;
634 }
635 if( zSql==0 ){
636 nSql = strlen(zLine);
637 zSql = malloc( nSql+1 );
638 strcpy(zSql, zLine);
639 }else{
640 int len = strlen(zLine);
641 zSql = realloc( zSql, nSql + len + 2 );
642 if( zSql==0 ){
drh1e5d0e92000-05-31 23:33:17 +0000643 fprintf(stderr,"%s: out of memory!\n", argv0);
drh75897232000-05-29 14:26:00 +0000644 exit(1);
645 }
646 strcpy(&zSql[nSql++], "\n");
647 strcpy(&zSql[nSql], zLine);
648 nSql += len;
649 }
650 free(zLine);
651 if( sqlite_complete(zSql) ){
652 data.cnt = 0;
653 if( sqlite_exec(db, zSql, callback, &data, &zErrMsg)!=0
654 && zErrMsg!=0 ){
655 printf("SQL error: %s\n", zErrMsg);
656 free(zErrMsg);
657 zErrMsg = 0;
658 }
659 free(zSql);
660 zSql = 0;
661 nSql = 0;
662 }
663 }
664 }
665 sqlite_close(db);
666 return 0;
667}