blob: b044ad46ea0a6080e67066097d5c9ee9d83b69e3 [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**
drh8e7e7a22000-05-30 18:45:23 +000027** $Id: shell.c,v 1.3 2000/05/30 18:45:24 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;
56 char *z;
57 int n;
58 int eol;
59
60 if( zPrompt && *zPrompt ){
61 printf("%s",zPrompt);
62 fflush(stdout);
63 }
64 nLine = 100;
65 zLine = malloc( nLine );
66 if( zLine==0 ) return 0;
67 n = 0;
68 eol = 0;
69 while( !eol ){
70 if( n+100>nLine ){
71 nLine = nLine*2 + 100;
72 zLine = realloc(zLine, nLine);
73 if( zLine==0 ) return 0;
74 }
75 if( fgets(&zLine[n], nLine - n, stdin)==0 ){
76 if( n==0 ){
77 free(zLine);
78 return 0;
79 }
80 zLine[n] = 0;
81 eol = 1;
82 break;
83 }
84 while( zLine[n] ){ n++; }
85 if( n>0 && zLine[n-1]=='\n' ){
86 n--;
87 zLine[n] = 0;
88 eol = 1;
89 }
90 }
91 zLine = realloc( zLine, n+1 );
92 return zLine;
93}
94
95/*
96** Retrieve a single line of input text. "isatty" is true if text
97** is coming from a terminal. In that case, we issue a prompt and
98** attempt to use "readline" for command-line editing. If "isatty"
99** is false, use "getline" instead of "readline" and issue to prompt.
100**
101** zPrior is a string of prior text retrieved. If not the empty
102** string, then issue a continuation prompt.
103*/
104static char *one_input_line(const char *zPrior, int isatty){
105 char *zPrompt;
106 char *zResult;
107 if( !isatty ){
108 return getline(0);
109 }
110 if( zPrior && zPrior[0] ){
111 zPrompt = " ...> ";
112 }else{
113 zPrompt = "sqlite> ";
114 }
115 zResult = readline(zPrompt);
116 add_history(zResult);
117 return zResult;
118}
119
120/*
drh75897232000-05-29 14:26:00 +0000121** An pointer to an instance of this structure is passed from
122** the main program to the callback. This is used to communicate
123** state and mode information.
124*/
125struct callback_data {
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 char separator[20];/* Separator character for MODE_List */
131 int colWidth[30]; /* Width of each column when in column mode */
132};
133
134/*
135** These are the allowed modes.
136*/
137#define MODE_Line 0 /* One field per line. Blank line between records */
138#define MODE_Column 1 /* One record per line in neat columns */
139#define MODE_List 2 /* One record per line with a separator */
140
141/*
142** Number of elements in an array
143*/
144#define ArraySize(X) (sizeof(X)/sizeof(X[0]))
145
146/*
147** This is the callback routine that the SQLite library
148** invokes for each row of a query result.
149*/
150static int callback(void *pArg, int nArg, char **azArg, char **azCol){
151 int i;
152 struct callback_data *p = (struct callback_data*)pArg;
153 switch( p->mode ){
154 case MODE_Line: {
155 if( p->cnt++>0 ) fprintf(p->out,"\n");
156 for(i=0; i<nArg; i++){
157 fprintf(p->out,"%s = %s\n", azCol[i], azArg[i]);
158 }
159 break;
160 }
161 case MODE_Column: {
162 if( p->cnt++==0 && p->showHeader ){
163 for(i=0; i<nArg; i++){
164 int w;
165 if( i<ArraySize(p->colWidth) && p->colWidth[i]>0 ){
166 w = p->colWidth[i];
167 }else{
168 w = 10;
169 }
170 fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
171 }
172 for(i=0; i<nArg; i++){
173 int w;
174 if( i<ArraySize(p->colWidth) && p->colWidth[i]>0 ){
175 w = p->colWidth[i];
176 }else{
177 w = 10;
178 }
179 fprintf(p->out,"%-*.*s%s",w,w,"-------------------------------------",
180 i==nArg-1 ? "\n": " ");
181 }
182 }
183 for(i=0; i<nArg; i++){
184 int w;
185 if( i<ArraySize(p->colWidth) && p->colWidth[i]>0 ){
186 w = p->colWidth[i];
187 }else{
188 w = 10;
189 }
190 fprintf(p->out,"%-*.*s%s",w,w,azArg[i], i==nArg-1 ? "\n": " ");
191 }
192 break;
193 }
194 case MODE_List: {
195 if( p->cnt++==0 && p->showHeader ){
196 for(i=0; i<nArg; i++){
197 fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
198 }
199 }
200 for(i=0; i<nArg; i++){
201 fprintf(p->out,"%s%s",azArg[i], i==nArg-1 ? "\n" : p->separator);
202 }
203 break;
204 }
205 }
206 return 0;
207}
208
209/*
210** Text of a help message
211*/
212static char zHelp[] =
213 ".exit Exit this program\n"
214 ".explain Set output mode suitable for EXPLAIN\n"
215 ".header ON|OFF Turn display of headers on or off\n"
216 ".help Show this message\n"
217 ".indices TABLE Show names of all indices on TABLE\n"
218 ".mode MODE Set mode to one of \"line\", \"column\", or"
219 " \"list\"\n"
220 ".output FILENAME Send output to FILENAME\n"
221 ".output stdout Send output to the screen\n"
222 ".schema ?TABLE? Show the CREATE statements\n"
223 ".separator STRING Change separator string for \"list\" mode\n"
224 ".tables List names all tables in the database\n"
225 ".width NUM NUM ... Set column widths for \"column\" mode\n"
226;
227
228/*
229** If an input line begins with "." then invoke this routine to
230** process that line.
231*/
232static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
233 int i = 1;
234 int nArg = 0;
235 int n, c;
236 char *azArg[50];
237
238 /* Parse the input line into tokens.
239 */
240 while( zLine[i] && nArg<ArraySize(azArg) ){
241 while( isspace(zLine[i]) ){ i++; }
242 if( zLine[i]=='\'' || zLine[i]=='"' ){
243 int delim = zLine[i++];
244 azArg[nArg++] = &zLine[i];
245 while( zLine[i] && zLine[i]!=delim ){ i++; }
246 if( zLine[i]==delim ){
247 zLine[i++] = 0;
248 }
249 }else{
250 azArg[nArg++] = &zLine[i];
251 while( zLine[i] && !isspace(zLine[i]) ){ i++; }
252 if( zLine[i] ) zLine[i++] = 0;
253 }
254 }
255
256 /* Process the input line.
257 */
258 if( nArg==0 ) return;
259 n = strlen(azArg[0]);
260 c = azArg[0][0];
261
262 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
263 exit(0);
264 }else
265
266 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
267 p->mode = MODE_Column;
268 p->showHeader = 1;
269 p->colWidth[0] = 4;
270 p->colWidth[1] = 12;
271 p->colWidth[2] = 5;
272 p->colWidth[3] = 5;
273 p->colWidth[4] = 40;
274 }else
275
276 if( c=='h' && strncmp(azArg[0], "header", n)==0 && nArg>1 ){
277 int j;
278 char *z = azArg[1];
279 int val = atoi(azArg[1]);
280 for(j=0; z[j]; j++){
281 if( isupper(z[j]) ) z[j] = tolower(z[j]);
282 }
283 if( strcmp(z,"on")==0 ){
284 val = 1;
285 }else if( strcmp(z,"yes")==0 ){
286 val = 1;
287 }
288 p->showHeader = val;
289 }else
290
291 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
292 fprintf(stderr,zHelp);
293 }else
294
295 if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
296 struct callback_data data;
297 char *zErrMsg = 0;
298 char zSql[1000];
299 memcpy(&data, p, sizeof(data));
300 data.showHeader = 0;
301 data.mode = MODE_List;
302 sprintf(zSql, "SELECT name FROM sqlite_master "
drh305cea62000-05-29 17:44:25 +0000303 "WHERE type='index' AND tbl_name='%.00s' "
304 "ORDER BY name", azArg[1]);
drh75897232000-05-29 14:26:00 +0000305 sqlite_exec(db, zSql, callback, &data, &zErrMsg);
306 if( zErrMsg ){
307 fprintf(stderr,"Error: %s\n", zErrMsg);
308 free(zErrMsg);
309 }
310 }else
311
312 if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
313 int n2 = strlen(azArg[1]);
314 if( strncmp(azArg[1],"line",n2)==0 ){
315 p->mode = MODE_Line;
316 }else if( strncmp(azArg[1],"column",n2)==0 ){
317 p->mode = MODE_Column;
318 }else if( strncmp(azArg[1],"list",n2)==0 ){
319 p->mode = MODE_List;
320 }
321 }else
322
323 if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
324 if( p->out!=stdout ){
325 fclose(p->out);
326 }
327 if( strcmp(azArg[1],"stdout")==0 ){
328 p->out = stdout;
329 }else{
330 p->out = fopen(azArg[1], "w");
331 if( p->out==0 ){
332 fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
333 p->out = stdout;
334 }
335 }
336 }else
337
338 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
339 struct callback_data data;
340 char *zErrMsg = 0;
341 char zSql[1000];
342 memcpy(&data, p, sizeof(data));
343 data.showHeader = 0;
344 data.mode = MODE_List;
345 if( nArg>1 ){
346 sprintf(zSql, "SELECT sql FROM sqlite_master WHERE name='%.900s'",
347 azArg[1]);
348 }else{
349 sprintf(zSql, "SELECT sql FROM sqlite_master "
350 "ORDER BY tbl_name, type DESC, name");
351 }
352 sqlite_exec(db, zSql, callback, &data, &zErrMsg);
353 if( zErrMsg ){
354 fprintf(stderr,"Error: %s\n", zErrMsg);
355 free(zErrMsg);
356 }
357 }else
358
359 if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
360 sprintf(p->separator, "%.*s", (int)ArraySize(p->separator)-1, azArg[1]);
361 }else
362
363 if( c=='t' && strncmp(azArg[0], "tables", n)==0 ){
364 struct callback_data data;
365 char *zErrMsg = 0;
drh305cea62000-05-29 17:44:25 +0000366 static char zSql[] =
367 "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
drh75897232000-05-29 14:26:00 +0000368 memcpy(&data, p, sizeof(data));
369 data.showHeader = 0;
370 data.mode = MODE_List;
371 sqlite_exec(db, zSql, callback, &data, &zErrMsg);
372 if( zErrMsg ){
373 fprintf(stderr,"Error: %s\n", zErrMsg);
374 free(zErrMsg);
375 }
376 }else
377
378 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
379 int j;
380 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
381 p->colWidth[j-1] = atoi(azArg[j]);
382 }
383 }else
384
385 {
386 fprintf(stderr, "unknown command: \"%s\". Enter \".help\" for help\n",
387 azArg[0]);
388 }
389}
390
391int main(int argc, char **argv){
392 sqlite *db;
393 char *zErrMsg = 0;
394 struct callback_data data;
395
396 if( argc!=2 && argc!=3 ){
397 fprintf(stderr,"Usage: %s FILENAME ?SQL?\n", *argv);
398 exit(1);
399 }
400 db = sqlite_open(argv[1], 0666, &zErrMsg);
401 if( db==0 ){
402 fprintf(stderr,"Unable to open database \"%s\": %s\n", argv[1], zErrMsg);
403 exit(1);
404 }
405 memset(&data, 0, sizeof(data));
406 data.out = stdout;
407 if( argc==3 ){
408 data.mode = MODE_List;
409 strcpy(data.separator,"|");
410 if( sqlite_exec(db, argv[2], callback, &data, &zErrMsg)!=0 && zErrMsg!=0 ){
411 fprintf(stderr,"SQL error: %s\n", zErrMsg);
412 exit(1);
413 }
414 }else{
415 char *zLine;
416 char *zSql = 0;
417 int nSql = 0;
418 int istty = isatty(0);
419 data.mode = MODE_Line;
420 strcpy(data.separator,"|");
421 data.showHeader = 0;
422 if( istty ){
423 printf(
424 "Enter \".help\" for instructions\n"
425 );
426 }
drh8e7e7a22000-05-30 18:45:23 +0000427 while( (zLine = one_input_line(zSql, istty))!=0 ){
drh75897232000-05-29 14:26:00 +0000428 if( zLine && zLine[0]=='.' ){
429 do_meta_command(zLine, db, &data);
430 free(zLine);
431 continue;
432 }
433 if( zSql==0 ){
434 nSql = strlen(zLine);
435 zSql = malloc( nSql+1 );
436 strcpy(zSql, zLine);
437 }else{
438 int len = strlen(zLine);
439 zSql = realloc( zSql, nSql + len + 2 );
440 if( zSql==0 ){
441 fprintf(stderr,"%s: out of memory!\n", *argv);
442 exit(1);
443 }
444 strcpy(&zSql[nSql++], "\n");
445 strcpy(&zSql[nSql], zLine);
446 nSql += len;
447 }
448 free(zLine);
449 if( sqlite_complete(zSql) ){
450 data.cnt = 0;
451 if( sqlite_exec(db, zSql, callback, &data, &zErrMsg)!=0
452 && zErrMsg!=0 ){
453 printf("SQL error: %s\n", zErrMsg);
454 free(zErrMsg);
455 zErrMsg = 0;
456 }
457 free(zSql);
458 zSql = 0;
459 nSql = 0;
460 }
461 }
462 }
463 sqlite_close(db);
464 return 0;
465}