xref: /aosp_15_r20/external/javasqlite/src/main/java/SQLite/Shell.java (revision fd76c71b147b98c03334ec0945352cee0b39aab1)
1*fd76c71bSTreehugger Robot package SQLite;
2*fd76c71bSTreehugger Robot 
3*fd76c71bSTreehugger Robot import SQLite.*;
4*fd76c71bSTreehugger Robot import java.io.*;
5*fd76c71bSTreehugger Robot import java.util.*;
6*fd76c71bSTreehugger Robot 
7*fd76c71bSTreehugger Robot /**
8*fd76c71bSTreehugger Robot  * SQLite command line shell. This is a partial reimplementaion
9*fd76c71bSTreehugger Robot  * of sqlite/src/shell.c and can be invoked by:<P>
10*fd76c71bSTreehugger Robot  *
11*fd76c71bSTreehugger Robot  * <verb>
12*fd76c71bSTreehugger Robot  *     java SQLite.Shell [OPTIONS] database [SHELLCMD]
13*fd76c71bSTreehugger Robot  * or
14*fd76c71bSTreehugger Robot  *     java -jar sqlite.jar [OPTIONS] database [SHELLCMD]
15*fd76c71bSTreehugger Robot  * </verb>
16*fd76c71bSTreehugger Robot  */
17*fd76c71bSTreehugger Robot 
18*fd76c71bSTreehugger Robot public class Shell implements Callback {
19*fd76c71bSTreehugger Robot     Database db;
20*fd76c71bSTreehugger Robot     boolean echo;
21*fd76c71bSTreehugger Robot     int count;
22*fd76c71bSTreehugger Robot     int mode;
23*fd76c71bSTreehugger Robot     boolean showHeader;
24*fd76c71bSTreehugger Robot     String tableName;
25*fd76c71bSTreehugger Robot     String sep;
26*fd76c71bSTreehugger Robot     String cols[];
27*fd76c71bSTreehugger Robot     int colwidth[];
28*fd76c71bSTreehugger Robot     String destTable;
29*fd76c71bSTreehugger Robot     PrintWriter pw;
30*fd76c71bSTreehugger Robot     PrintWriter err;
31*fd76c71bSTreehugger Robot 
32*fd76c71bSTreehugger Robot     static final int MODE_Line = 0;
33*fd76c71bSTreehugger Robot     static final int MODE_Column = 1;
34*fd76c71bSTreehugger Robot     static final int MODE_List = 2;
35*fd76c71bSTreehugger Robot     static final int MODE_Semi = 3;
36*fd76c71bSTreehugger Robot     static final int MODE_Html = 4;
37*fd76c71bSTreehugger Robot     static final int MODE_Insert = 5;
38*fd76c71bSTreehugger Robot     static final int MODE_Insert2 = 6;
39*fd76c71bSTreehugger Robot 
Shell(PrintWriter pw, PrintWriter err)40*fd76c71bSTreehugger Robot     public Shell(PrintWriter pw, PrintWriter err) {
41*fd76c71bSTreehugger Robot 	this.pw = pw;
42*fd76c71bSTreehugger Robot 	this.err = err;
43*fd76c71bSTreehugger Robot     }
44*fd76c71bSTreehugger Robot 
Shell(PrintStream ps, PrintStream errs)45*fd76c71bSTreehugger Robot     public Shell(PrintStream ps, PrintStream errs) {
46*fd76c71bSTreehugger Robot 	pw = new PrintWriter(ps);
47*fd76c71bSTreehugger Robot 	err = new PrintWriter(errs);
48*fd76c71bSTreehugger Robot     }
49*fd76c71bSTreehugger Robot 
clone()50*fd76c71bSTreehugger Robot     protected Object clone() {
51*fd76c71bSTreehugger Robot         Shell s = new Shell(this.pw, this.err);
52*fd76c71bSTreehugger Robot 	s.db = db;
53*fd76c71bSTreehugger Robot 	s.echo = echo;
54*fd76c71bSTreehugger Robot 	s.mode = mode;
55*fd76c71bSTreehugger Robot 	s.count = 0;
56*fd76c71bSTreehugger Robot 	s.showHeader = showHeader;
57*fd76c71bSTreehugger Robot 	s.tableName = tableName;
58*fd76c71bSTreehugger Robot 	s.sep = sep;
59*fd76c71bSTreehugger Robot 	s.colwidth = colwidth;
60*fd76c71bSTreehugger Robot 	return s;
61*fd76c71bSTreehugger Robot     }
62*fd76c71bSTreehugger Robot 
sql_quote_dbl(String str)63*fd76c71bSTreehugger Robot     static public String sql_quote_dbl(String str) {
64*fd76c71bSTreehugger Robot 	if (str == null) {
65*fd76c71bSTreehugger Robot 	    return "NULL";
66*fd76c71bSTreehugger Robot 	}
67*fd76c71bSTreehugger Robot 	int i, single = 0, dbl = 0;
68*fd76c71bSTreehugger Robot 	for (i = 0; i < str.length(); i++) {
69*fd76c71bSTreehugger Robot 	    if (str.charAt(i) == '\'') {
70*fd76c71bSTreehugger Robot 		single++;
71*fd76c71bSTreehugger Robot 	    } else if (str.charAt(i) == '"') {
72*fd76c71bSTreehugger Robot 		dbl++;
73*fd76c71bSTreehugger Robot 	    }
74*fd76c71bSTreehugger Robot 	}
75*fd76c71bSTreehugger Robot 	if (dbl == 0) {
76*fd76c71bSTreehugger Robot 	    return "\"" + str + "\"";
77*fd76c71bSTreehugger Robot 	}
78*fd76c71bSTreehugger Robot 	StringBuffer sb = new StringBuffer("\"");
79*fd76c71bSTreehugger Robot 	for (i = 0; i < str.length(); i++) {
80*fd76c71bSTreehugger Robot 	    char c = str.charAt(i);
81*fd76c71bSTreehugger Robot 	    if (c == '"') {
82*fd76c71bSTreehugger Robot 		sb.append("\"\"");
83*fd76c71bSTreehugger Robot 	    } else {
84*fd76c71bSTreehugger Robot 		sb.append(c);
85*fd76c71bSTreehugger Robot 	    }
86*fd76c71bSTreehugger Robot 	}
87*fd76c71bSTreehugger Robot 	return sb.toString();
88*fd76c71bSTreehugger Robot     }
89*fd76c71bSTreehugger Robot 
sql_quote(String str)90*fd76c71bSTreehugger Robot     static public String sql_quote(String str) {
91*fd76c71bSTreehugger Robot 	if (str == null) {
92*fd76c71bSTreehugger Robot 	    return "NULL";
93*fd76c71bSTreehugger Robot 	}
94*fd76c71bSTreehugger Robot 	int i, single = 0, dbl = 0;
95*fd76c71bSTreehugger Robot 	for (i = 0; i < str.length(); i++) {
96*fd76c71bSTreehugger Robot 	    if (str.charAt(i) == '\'') {
97*fd76c71bSTreehugger Robot 		single++;
98*fd76c71bSTreehugger Robot 	    } else if (str.charAt(i) == '"') {
99*fd76c71bSTreehugger Robot 		dbl++;
100*fd76c71bSTreehugger Robot 	    }
101*fd76c71bSTreehugger Robot 	}
102*fd76c71bSTreehugger Robot 	if (single == 0) {
103*fd76c71bSTreehugger Robot 	    return "'" + str + "'";
104*fd76c71bSTreehugger Robot 	}
105*fd76c71bSTreehugger Robot 	if (dbl == 0) {
106*fd76c71bSTreehugger Robot 	    return "\"" + str + "\"";
107*fd76c71bSTreehugger Robot 	}
108*fd76c71bSTreehugger Robot 	StringBuffer sb = new StringBuffer("'");
109*fd76c71bSTreehugger Robot 	for (i = 0; i < str.length(); i++) {
110*fd76c71bSTreehugger Robot 	    char c = str.charAt(i);
111*fd76c71bSTreehugger Robot 	    if (c == '\'') {
112*fd76c71bSTreehugger Robot 		sb.append("''");
113*fd76c71bSTreehugger Robot 	    } else {
114*fd76c71bSTreehugger Robot 		sb.append(c);
115*fd76c71bSTreehugger Robot 	    }
116*fd76c71bSTreehugger Robot 	}
117*fd76c71bSTreehugger Robot 	return sb.toString();
118*fd76c71bSTreehugger Robot     }
119*fd76c71bSTreehugger Robot 
html_quote(String str)120*fd76c71bSTreehugger Robot     static String html_quote(String str) {
121*fd76c71bSTreehugger Robot 	if (str == null) {
122*fd76c71bSTreehugger Robot 	    return "NULL";
123*fd76c71bSTreehugger Robot 	}
124*fd76c71bSTreehugger Robot 	StringBuffer sb = new StringBuffer();
125*fd76c71bSTreehugger Robot 	for (int i = 0; i < str.length(); i++) {
126*fd76c71bSTreehugger Robot 	    char c = str.charAt(i);
127*fd76c71bSTreehugger Robot 	    if (c == '<') {
128*fd76c71bSTreehugger Robot 		sb.append("&lt;");
129*fd76c71bSTreehugger Robot 	    } else if (c == '>') {
130*fd76c71bSTreehugger Robot 		sb.append("&gt;");
131*fd76c71bSTreehugger Robot 	    } else if (c == '&') {
132*fd76c71bSTreehugger Robot 		sb.append("&amp;");
133*fd76c71bSTreehugger Robot 	    } else {
134*fd76c71bSTreehugger Robot 		int x = c;
135*fd76c71bSTreehugger Robot 		if (x < 32 || x > 127) {
136*fd76c71bSTreehugger Robot 		    sb.append("&#" + x + ";");
137*fd76c71bSTreehugger Robot 		} else {
138*fd76c71bSTreehugger Robot 		    sb.append(c);
139*fd76c71bSTreehugger Robot 		}
140*fd76c71bSTreehugger Robot 	    }
141*fd76c71bSTreehugger Robot 	}
142*fd76c71bSTreehugger Robot 	return sb.toString();
143*fd76c71bSTreehugger Robot     }
144*fd76c71bSTreehugger Robot 
is_numeric(String str)145*fd76c71bSTreehugger Robot     static boolean is_numeric(String str) {
146*fd76c71bSTreehugger Robot 	try {
147*fd76c71bSTreehugger Robot 	    Double d = Double.valueOf(str);
148*fd76c71bSTreehugger Robot 	} catch (java.lang.Exception e) {
149*fd76c71bSTreehugger Robot 	    return false;
150*fd76c71bSTreehugger Robot 	}
151*fd76c71bSTreehugger Robot 	return true;
152*fd76c71bSTreehugger Robot     }
153*fd76c71bSTreehugger Robot 
set_table_name(String str)154*fd76c71bSTreehugger Robot     void set_table_name(String str) {
155*fd76c71bSTreehugger Robot 	if (str == null) {
156*fd76c71bSTreehugger Robot 	    tableName = "";
157*fd76c71bSTreehugger Robot 	    return;
158*fd76c71bSTreehugger Robot 	}
159*fd76c71bSTreehugger Robot 	if (db.is3()) {
160*fd76c71bSTreehugger Robot 	    tableName = Shell.sql_quote_dbl(str);
161*fd76c71bSTreehugger Robot 	} else {
162*fd76c71bSTreehugger Robot 	    tableName = Shell.sql_quote(str);
163*fd76c71bSTreehugger Robot 	}
164*fd76c71bSTreehugger Robot     }
165*fd76c71bSTreehugger Robot 
columns(String args[])166*fd76c71bSTreehugger Robot     public void columns(String args[]) {
167*fd76c71bSTreehugger Robot 	cols = args;
168*fd76c71bSTreehugger Robot     }
169*fd76c71bSTreehugger Robot 
types(String args[])170*fd76c71bSTreehugger Robot     public void types(String args[]) {
171*fd76c71bSTreehugger Robot 	/* Empty body to satisfy SQLite.Callback interface. */
172*fd76c71bSTreehugger Robot     }
173*fd76c71bSTreehugger Robot 
newrow(String args[])174*fd76c71bSTreehugger Robot     public boolean newrow(String args[]) {
175*fd76c71bSTreehugger Robot 	int i;
176*fd76c71bSTreehugger Robot 	String tname;
177*fd76c71bSTreehugger Robot 	switch (mode) {
178*fd76c71bSTreehugger Robot 	case Shell.MODE_Line:
179*fd76c71bSTreehugger Robot 	    if (args.length == 0) {
180*fd76c71bSTreehugger Robot 		break;
181*fd76c71bSTreehugger Robot 	    }
182*fd76c71bSTreehugger Robot 	    if (count++ > 0) {
183*fd76c71bSTreehugger Robot 		pw.println("");
184*fd76c71bSTreehugger Robot 	    }
185*fd76c71bSTreehugger Robot 	    for (i = 0; i < args.length; i++) {
186*fd76c71bSTreehugger Robot 		pw.println(cols[i] + " = " +
187*fd76c71bSTreehugger Robot 			   args[i] == null ? "NULL" : args[i]);
188*fd76c71bSTreehugger Robot 	    }
189*fd76c71bSTreehugger Robot 	    break;
190*fd76c71bSTreehugger Robot 	case Shell.MODE_Column:
191*fd76c71bSTreehugger Robot 	    String csep = "";
192*fd76c71bSTreehugger Robot 	    if (count++ == 0) {
193*fd76c71bSTreehugger Robot 		colwidth = new int[args.length];
194*fd76c71bSTreehugger Robot 		for (i = 0; i < args.length; i++) {
195*fd76c71bSTreehugger Robot 		    int w, n;
196*fd76c71bSTreehugger Robot 		    w = cols[i].length();
197*fd76c71bSTreehugger Robot 		    if (w < 10) {
198*fd76c71bSTreehugger Robot 			w = 10;
199*fd76c71bSTreehugger Robot 		    }
200*fd76c71bSTreehugger Robot 		    colwidth[i] = w;
201*fd76c71bSTreehugger Robot 		    if (showHeader) {
202*fd76c71bSTreehugger Robot 			pw.print(csep + cols[i]);
203*fd76c71bSTreehugger Robot 			csep = " ";
204*fd76c71bSTreehugger Robot 		    }
205*fd76c71bSTreehugger Robot 		}
206*fd76c71bSTreehugger Robot 		if (showHeader) {
207*fd76c71bSTreehugger Robot 		    pw.println("");
208*fd76c71bSTreehugger Robot 		}
209*fd76c71bSTreehugger Robot 	    }
210*fd76c71bSTreehugger Robot 	    if (args.length == 0) {
211*fd76c71bSTreehugger Robot 		break;
212*fd76c71bSTreehugger Robot 	    }
213*fd76c71bSTreehugger Robot 	    csep = "";
214*fd76c71bSTreehugger Robot 	    for (i = 0; i < args.length; i++) {
215*fd76c71bSTreehugger Robot 		pw.print(csep + (args[i] == null ? "NULL" : args[i]));
216*fd76c71bSTreehugger Robot 		csep = " ";
217*fd76c71bSTreehugger Robot 	    }
218*fd76c71bSTreehugger Robot 	    pw.println("");
219*fd76c71bSTreehugger Robot 	    break;
220*fd76c71bSTreehugger Robot 	case Shell.MODE_Semi:
221*fd76c71bSTreehugger Robot 	case Shell.MODE_List:
222*fd76c71bSTreehugger Robot 	    if (count++ == 0 && showHeader) {
223*fd76c71bSTreehugger Robot 		for (i = 0; i < args.length; i++) {
224*fd76c71bSTreehugger Robot 		    pw.print(cols[i] +
225*fd76c71bSTreehugger Robot 			     (i == args.length - 1 ? "\n" : sep));
226*fd76c71bSTreehugger Robot 		}
227*fd76c71bSTreehugger Robot 	    }
228*fd76c71bSTreehugger Robot 	    if (args.length == 0) {
229*fd76c71bSTreehugger Robot 		break;
230*fd76c71bSTreehugger Robot 	    }
231*fd76c71bSTreehugger Robot 	    for (i = 0; i < args.length; i++) {
232*fd76c71bSTreehugger Robot 		pw.print(args[i] == null ? "NULL" : args[i]);
233*fd76c71bSTreehugger Robot 		if (mode == Shell.MODE_Semi) {
234*fd76c71bSTreehugger Robot 		    pw.print(";");
235*fd76c71bSTreehugger Robot 		} else if (i < args.length - 1) {
236*fd76c71bSTreehugger Robot 		    pw.print(sep);
237*fd76c71bSTreehugger Robot 		}
238*fd76c71bSTreehugger Robot 	    }
239*fd76c71bSTreehugger Robot 	    pw.println("");
240*fd76c71bSTreehugger Robot 	    break;
241*fd76c71bSTreehugger Robot 	case MODE_Html:
242*fd76c71bSTreehugger Robot 	    if (count++ == 0 && showHeader) {
243*fd76c71bSTreehugger Robot 		pw.print("<TR>");
244*fd76c71bSTreehugger Robot 		for (i = 0; i < args.length; i++) {
245*fd76c71bSTreehugger Robot 		    pw.print("<TH>" + html_quote(cols[i]) + "</TH>");
246*fd76c71bSTreehugger Robot 		}
247*fd76c71bSTreehugger Robot 		pw.println("</TR>");
248*fd76c71bSTreehugger Robot 	    }
249*fd76c71bSTreehugger Robot 	    if (args.length == 0) {
250*fd76c71bSTreehugger Robot 		break;
251*fd76c71bSTreehugger Robot 	    }
252*fd76c71bSTreehugger Robot 	    pw.print("<TR>");
253*fd76c71bSTreehugger Robot 	    for (i = 0; i < args.length; i++) {
254*fd76c71bSTreehugger Robot 		pw.print("<TD>" + html_quote(args[i]) + "</TD>");
255*fd76c71bSTreehugger Robot 	    }
256*fd76c71bSTreehugger Robot 	    pw.println("</TR>");
257*fd76c71bSTreehugger Robot 	    break;
258*fd76c71bSTreehugger Robot 	case MODE_Insert:
259*fd76c71bSTreehugger Robot 	    if (args.length == 0) {
260*fd76c71bSTreehugger Robot 		break;
261*fd76c71bSTreehugger Robot 	    }
262*fd76c71bSTreehugger Robot 	    tname = tableName;
263*fd76c71bSTreehugger Robot 	    if (destTable != null) {
264*fd76c71bSTreehugger Robot 	        tname = destTable;
265*fd76c71bSTreehugger Robot 	    }
266*fd76c71bSTreehugger Robot 	    pw.print("INSERT INTO " + tname + " VALUES(");
267*fd76c71bSTreehugger Robot 	    for (i = 0; i < args.length; i++) {
268*fd76c71bSTreehugger Robot 	        String tsep = i > 0 ? "," : "";
269*fd76c71bSTreehugger Robot 		if (args[i] == null) {
270*fd76c71bSTreehugger Robot 		    pw.print(tsep + "NULL");
271*fd76c71bSTreehugger Robot 		} else if (is_numeric(args[i])) {
272*fd76c71bSTreehugger Robot 		    pw.print(tsep + args[i]);
273*fd76c71bSTreehugger Robot 		} else {
274*fd76c71bSTreehugger Robot 		    pw.print(tsep + sql_quote(args[i]));
275*fd76c71bSTreehugger Robot 		}
276*fd76c71bSTreehugger Robot 	    }
277*fd76c71bSTreehugger Robot 	    pw.println(");");
278*fd76c71bSTreehugger Robot 	    break;
279*fd76c71bSTreehugger Robot 	case MODE_Insert2:
280*fd76c71bSTreehugger Robot 	    if (args.length == 0) {
281*fd76c71bSTreehugger Robot 		break;
282*fd76c71bSTreehugger Robot 	    }
283*fd76c71bSTreehugger Robot 	    tname = tableName;
284*fd76c71bSTreehugger Robot 	    if (destTable != null) {
285*fd76c71bSTreehugger Robot 	        tname = destTable;
286*fd76c71bSTreehugger Robot 	    }
287*fd76c71bSTreehugger Robot 	    pw.print("INSERT INTO " + tname + " VALUES(");
288*fd76c71bSTreehugger Robot 	    for (i = 0; i < args.length; i++) {
289*fd76c71bSTreehugger Robot 	        String tsep = i > 0 ? "," : "";
290*fd76c71bSTreehugger Robot 		pw.print(tsep + args[i]);
291*fd76c71bSTreehugger Robot 	    }
292*fd76c71bSTreehugger Robot 	    pw.println(");");
293*fd76c71bSTreehugger Robot 	    break;
294*fd76c71bSTreehugger Robot 	}
295*fd76c71bSTreehugger Robot 	return false;
296*fd76c71bSTreehugger Robot     }
297*fd76c71bSTreehugger Robot 
do_meta(String line)298*fd76c71bSTreehugger Robot     void do_meta(String line) {
299*fd76c71bSTreehugger Robot         StringTokenizer st = new StringTokenizer(line.toLowerCase());
300*fd76c71bSTreehugger Robot 	int n = st.countTokens();
301*fd76c71bSTreehugger Robot 	if (n <= 0) {
302*fd76c71bSTreehugger Robot 	    return;
303*fd76c71bSTreehugger Robot 	}
304*fd76c71bSTreehugger Robot 	String cmd = st.nextToken();
305*fd76c71bSTreehugger Robot 	String args[] = new String[n - 1];
306*fd76c71bSTreehugger Robot 	int i = 0;
307*fd76c71bSTreehugger Robot 	while (st.hasMoreTokens()) {
308*fd76c71bSTreehugger Robot 	    args[i] = st.nextToken();
309*fd76c71bSTreehugger Robot 	    ++i;
310*fd76c71bSTreehugger Robot 	}
311*fd76c71bSTreehugger Robot 	if (cmd.compareTo(".dump") == 0) {
312*fd76c71bSTreehugger Robot 	    new DBDump(this, args);
313*fd76c71bSTreehugger Robot 	    return;
314*fd76c71bSTreehugger Robot 	}
315*fd76c71bSTreehugger Robot 	if (cmd.compareTo(".echo") == 0) {
316*fd76c71bSTreehugger Robot 	    if (args.length > 0 &&
317*fd76c71bSTreehugger Robot 		(args[0].startsWith("y") || args[0].startsWith("on"))) {
318*fd76c71bSTreehugger Robot 		echo = true;
319*fd76c71bSTreehugger Robot 	    }
320*fd76c71bSTreehugger Robot 	    return;
321*fd76c71bSTreehugger Robot 	}
322*fd76c71bSTreehugger Robot 	if (cmd.compareTo(".exit") == 0) {
323*fd76c71bSTreehugger Robot 	    try {
324*fd76c71bSTreehugger Robot 		db.close();
325*fd76c71bSTreehugger Robot 	    } catch (Exception e) {
326*fd76c71bSTreehugger Robot 	    }
327*fd76c71bSTreehugger Robot 	    System.exit(0);
328*fd76c71bSTreehugger Robot 	}
329*fd76c71bSTreehugger Robot 	if (cmd.compareTo(".header") == 0) {
330*fd76c71bSTreehugger Robot 	    if (args.length > 0 &&
331*fd76c71bSTreehugger Robot 		(args[0].startsWith("y") || args[0].startsWith("on"))) {
332*fd76c71bSTreehugger Robot 		showHeader = true;
333*fd76c71bSTreehugger Robot 	    }
334*fd76c71bSTreehugger Robot 	    return;
335*fd76c71bSTreehugger Robot 	}
336*fd76c71bSTreehugger Robot 	if (cmd.compareTo(".help") == 0) {
337*fd76c71bSTreehugger Robot 	    pw.println(".dump ?TABLE? ...  Dump database in text fmt");
338*fd76c71bSTreehugger Robot 	    pw.println(".echo ON|OFF       Command echo on or off");
339*fd76c71bSTreehugger Robot 	    pw.println(".enc ?NAME?        Change encoding");
340*fd76c71bSTreehugger Robot 	    pw.println(".exit              Exit program");
341*fd76c71bSTreehugger Robot 	    pw.println(".header ON|OFF     Display headers on or off");
342*fd76c71bSTreehugger Robot 	    pw.println(".help              This message");
343*fd76c71bSTreehugger Robot 	    pw.println(".mode MODE         Set output mode to\n" +
344*fd76c71bSTreehugger Robot 		       "                   line, column, insert\n" +
345*fd76c71bSTreehugger Robot 		       "                   list, or html");
346*fd76c71bSTreehugger Robot 	    pw.println(".mode insert TABLE Generate SQL insert stmts");
347*fd76c71bSTreehugger Robot 	    pw.println(".schema ?PATTERN?  List table schema");
348*fd76c71bSTreehugger Robot 	    pw.println(".separator STRING  Set separator string");
349*fd76c71bSTreehugger Robot 	    pw.println(".tables ?PATTERN?  List table names");
350*fd76c71bSTreehugger Robot 	    return;
351*fd76c71bSTreehugger Robot 	}
352*fd76c71bSTreehugger Robot 	if (cmd.compareTo(".mode") == 0) {
353*fd76c71bSTreehugger Robot 	    if (args.length > 0) {
354*fd76c71bSTreehugger Robot 		if (args[0].compareTo("line") == 0) {
355*fd76c71bSTreehugger Robot 		    mode = Shell.MODE_Line;
356*fd76c71bSTreehugger Robot 		} else if (args[0].compareTo("column") == 0) {
357*fd76c71bSTreehugger Robot 		    mode = Shell.MODE_Column;
358*fd76c71bSTreehugger Robot 		} else if (args[0].compareTo("list") == 0) {
359*fd76c71bSTreehugger Robot 		    mode = Shell.MODE_List;
360*fd76c71bSTreehugger Robot 		} else if (args[0].compareTo("html") == 0) {
361*fd76c71bSTreehugger Robot 		    mode = Shell.MODE_Html;
362*fd76c71bSTreehugger Robot 		} else if (args[0].compareTo("insert") == 0) {
363*fd76c71bSTreehugger Robot 		    mode = Shell.MODE_Insert;
364*fd76c71bSTreehugger Robot 		    if (args.length > 1) {
365*fd76c71bSTreehugger Robot 			destTable = args[1];
366*fd76c71bSTreehugger Robot 		    }
367*fd76c71bSTreehugger Robot 		}
368*fd76c71bSTreehugger Robot 	    }
369*fd76c71bSTreehugger Robot 	    return;
370*fd76c71bSTreehugger Robot 	}
371*fd76c71bSTreehugger Robot 	if (cmd.compareTo(".separator") == 0) {
372*fd76c71bSTreehugger Robot 	    if (args.length > 0) {
373*fd76c71bSTreehugger Robot 		sep = args[0];
374*fd76c71bSTreehugger Robot 	    }
375*fd76c71bSTreehugger Robot 	    return;
376*fd76c71bSTreehugger Robot 	}
377*fd76c71bSTreehugger Robot 	if (cmd.compareTo(".tables") == 0) {
378*fd76c71bSTreehugger Robot 	    TableResult t = null;
379*fd76c71bSTreehugger Robot 	    if (args.length > 0) {
380*fd76c71bSTreehugger Robot 		try {
381*fd76c71bSTreehugger Robot 		    String qarg[] = new String[1];
382*fd76c71bSTreehugger Robot 		    qarg[0] = args[0];
383*fd76c71bSTreehugger Robot 		    t = db.get_table("SELECT name FROM sqlite_master " +
384*fd76c71bSTreehugger Robot 				     "WHERE type='table' AND " +
385*fd76c71bSTreehugger Robot 				     "name LIKE '%%%q%%' " +
386*fd76c71bSTreehugger Robot 				     "ORDER BY name", qarg);
387*fd76c71bSTreehugger Robot 		} catch (Exception e) {
388*fd76c71bSTreehugger Robot 		    err.println("SQL Error: " + e);
389*fd76c71bSTreehugger Robot 		    err.flush();
390*fd76c71bSTreehugger Robot 		}
391*fd76c71bSTreehugger Robot 	    } else {
392*fd76c71bSTreehugger Robot 		try {
393*fd76c71bSTreehugger Robot 		    t = db.get_table("SELECT name FROM sqlite_master " +
394*fd76c71bSTreehugger Robot 				     "WHERE type='table' ORDER BY name");
395*fd76c71bSTreehugger Robot 		} catch (Exception e) {
396*fd76c71bSTreehugger Robot 		    err.println("SQL Error: " + e);
397*fd76c71bSTreehugger Robot 		    err.flush();
398*fd76c71bSTreehugger Robot 		}
399*fd76c71bSTreehugger Robot 	    }
400*fd76c71bSTreehugger Robot 	    if (t != null) {
401*fd76c71bSTreehugger Robot 		for (i = 0; i < t.nrows; i++) {
402*fd76c71bSTreehugger Robot 		    String tab = ((String[]) t.rows.elementAt(i))[0];
403*fd76c71bSTreehugger Robot 		    if (tab != null) {
404*fd76c71bSTreehugger Robot 			pw.println(tab);
405*fd76c71bSTreehugger Robot 		    }
406*fd76c71bSTreehugger Robot 		}
407*fd76c71bSTreehugger Robot 	    }
408*fd76c71bSTreehugger Robot 	    return;
409*fd76c71bSTreehugger Robot 	}
410*fd76c71bSTreehugger Robot 	if (cmd.compareTo(".schema") == 0) {
411*fd76c71bSTreehugger Robot 	    if (args.length > 0) {
412*fd76c71bSTreehugger Robot 		try {
413*fd76c71bSTreehugger Robot 		    String qarg[] = new String[1];
414*fd76c71bSTreehugger Robot 		    qarg[0] = args[0];
415*fd76c71bSTreehugger Robot 		    db.exec("SELECT sql FROM sqlite_master " +
416*fd76c71bSTreehugger Robot 			    "WHERE type!='meta' AND " +
417*fd76c71bSTreehugger Robot 			    "name LIKE '%%%q%%' AND " +
418*fd76c71bSTreehugger Robot 			    "sql NOTNULL " +
419*fd76c71bSTreehugger Robot 			    "ORDER BY type DESC, name",
420*fd76c71bSTreehugger Robot 			    this, qarg);
421*fd76c71bSTreehugger Robot 		} catch (Exception e) {
422*fd76c71bSTreehugger Robot 		    err.println("SQL Error: " + e);
423*fd76c71bSTreehugger Robot 		    err.flush();
424*fd76c71bSTreehugger Robot 		}
425*fd76c71bSTreehugger Robot 	    } else {
426*fd76c71bSTreehugger Robot 		try {
427*fd76c71bSTreehugger Robot 		    db.exec("SELECT sql FROM sqlite_master " +
428*fd76c71bSTreehugger Robot 			    "WHERE type!='meta' AND " +
429*fd76c71bSTreehugger Robot 			    "sql NOTNULL " +
430*fd76c71bSTreehugger Robot 			    "ORDER BY tbl_name, type DESC, name",
431*fd76c71bSTreehugger Robot 			    this);
432*fd76c71bSTreehugger Robot 		} catch (Exception e) {
433*fd76c71bSTreehugger Robot 		    err.println("SQL Error: " + e);
434*fd76c71bSTreehugger Robot 		    err.flush();
435*fd76c71bSTreehugger Robot 		}
436*fd76c71bSTreehugger Robot 	    }
437*fd76c71bSTreehugger Robot 	    return;
438*fd76c71bSTreehugger Robot 	}
439*fd76c71bSTreehugger Robot 	if (cmd.compareTo(".enc") == 0) {
440*fd76c71bSTreehugger Robot 	    try {
441*fd76c71bSTreehugger Robot 		db.set_encoding(args.length > 0 ? args[0] : null);
442*fd76c71bSTreehugger Robot 	    } catch (Exception e) {
443*fd76c71bSTreehugger Robot 		err.println("" + e);
444*fd76c71bSTreehugger Robot 		err.flush();
445*fd76c71bSTreehugger Robot 	    }
446*fd76c71bSTreehugger Robot 	    return;
447*fd76c71bSTreehugger Robot 	}
448*fd76c71bSTreehugger Robot 	if (cmd.compareTo(".rekey") == 0) {
449*fd76c71bSTreehugger Robot 	    try {
450*fd76c71bSTreehugger Robot 		db.rekey(args.length > 0 ? args[0] : null);
451*fd76c71bSTreehugger Robot 	    } catch (Exception e) {
452*fd76c71bSTreehugger Robot 		err.println("" + e);
453*fd76c71bSTreehugger Robot 		err.flush();
454*fd76c71bSTreehugger Robot 	    }
455*fd76c71bSTreehugger Robot 	    return;
456*fd76c71bSTreehugger Robot 	}
457*fd76c71bSTreehugger Robot 	err.println("Unknown command '" + cmd + "'");
458*fd76c71bSTreehugger Robot 	err.flush();
459*fd76c71bSTreehugger Robot     }
460*fd76c71bSTreehugger Robot 
read_line(BufferedReader is, String prompt)461*fd76c71bSTreehugger Robot     String read_line(BufferedReader is, String prompt) {
462*fd76c71bSTreehugger Robot 	try {
463*fd76c71bSTreehugger Robot 	    if (prompt != null) {
464*fd76c71bSTreehugger Robot 		pw.print(prompt);
465*fd76c71bSTreehugger Robot 		pw.flush();
466*fd76c71bSTreehugger Robot 	    }
467*fd76c71bSTreehugger Robot 	    String line = is.readLine();
468*fd76c71bSTreehugger Robot 	    return line;
469*fd76c71bSTreehugger Robot 	} catch (IOException e) {
470*fd76c71bSTreehugger Robot 	    return null;
471*fd76c71bSTreehugger Robot 	}
472*fd76c71bSTreehugger Robot     }
473*fd76c71bSTreehugger Robot 
do_input(BufferedReader is)474*fd76c71bSTreehugger Robot     void do_input(BufferedReader is) {
475*fd76c71bSTreehugger Robot 	String line, sql = null;
476*fd76c71bSTreehugger Robot 	String prompt = "SQLITE> ";
477*fd76c71bSTreehugger Robot 	while ((line = read_line(is, prompt)) != null) {
478*fd76c71bSTreehugger Robot 	    if (echo) {
479*fd76c71bSTreehugger Robot 		pw.println(line);
480*fd76c71bSTreehugger Robot 	    }
481*fd76c71bSTreehugger Robot 	    if (line.length() > 0 && line.charAt(0) == '.') {
482*fd76c71bSTreehugger Robot 	        do_meta(line);
483*fd76c71bSTreehugger Robot 	    } else {
484*fd76c71bSTreehugger Robot 		if (sql == null) {
485*fd76c71bSTreehugger Robot 		    sql = line;
486*fd76c71bSTreehugger Robot 		} else {
487*fd76c71bSTreehugger Robot 		    sql = sql + " " + line;
488*fd76c71bSTreehugger Robot 		}
489*fd76c71bSTreehugger Robot 		if (Database.complete(sql)) {
490*fd76c71bSTreehugger Robot 		    try {
491*fd76c71bSTreehugger Robot 			db.exec(sql, this);
492*fd76c71bSTreehugger Robot 		    } catch (Exception e) {
493*fd76c71bSTreehugger Robot 			if (!echo) {
494*fd76c71bSTreehugger Robot 			    err.println(sql);
495*fd76c71bSTreehugger Robot 			}
496*fd76c71bSTreehugger Robot 			err.println("SQL Error: " + e);
497*fd76c71bSTreehugger Robot 			err.flush();
498*fd76c71bSTreehugger Robot 		    }
499*fd76c71bSTreehugger Robot 		    sql = null;
500*fd76c71bSTreehugger Robot 		    prompt = "SQLITE> ";
501*fd76c71bSTreehugger Robot 		} else {
502*fd76c71bSTreehugger Robot 		    prompt = "SQLITE? ";
503*fd76c71bSTreehugger Robot 		}
504*fd76c71bSTreehugger Robot 	    }
505*fd76c71bSTreehugger Robot 	    pw.flush();
506*fd76c71bSTreehugger Robot 	}
507*fd76c71bSTreehugger Robot 	if (sql != null) {
508*fd76c71bSTreehugger Robot 	    err.println("Incomplete SQL: " + sql);
509*fd76c71bSTreehugger Robot 	    err.flush();
510*fd76c71bSTreehugger Robot 	}
511*fd76c71bSTreehugger Robot     }
512*fd76c71bSTreehugger Robot 
do_cmd(String sql)513*fd76c71bSTreehugger Robot     void do_cmd(String sql) {
514*fd76c71bSTreehugger Robot         if (db == null) {
515*fd76c71bSTreehugger Robot 	    return;
516*fd76c71bSTreehugger Robot 	}
517*fd76c71bSTreehugger Robot         if (sql.length() > 0 && sql.charAt(0) == '.') {
518*fd76c71bSTreehugger Robot 	    do_meta(sql);
519*fd76c71bSTreehugger Robot 	} else {
520*fd76c71bSTreehugger Robot 	    try {
521*fd76c71bSTreehugger Robot 	        db.exec(sql, this);
522*fd76c71bSTreehugger Robot 	    } catch (Exception e) {
523*fd76c71bSTreehugger Robot 		err.println("SQL Error: " + e);
524*fd76c71bSTreehugger Robot 		err.flush();
525*fd76c71bSTreehugger Robot 	    }
526*fd76c71bSTreehugger Robot 	}
527*fd76c71bSTreehugger Robot     }
528*fd76c71bSTreehugger Robot 
main(String args[])529*fd76c71bSTreehugger Robot     public static void main(String args[]) {
530*fd76c71bSTreehugger Robot 	String key = null;
531*fd76c71bSTreehugger Robot 	Shell s = new Shell(System.out, System.err);
532*fd76c71bSTreehugger Robot 	s.mode = Shell.MODE_List;
533*fd76c71bSTreehugger Robot 	s.sep = "|";
534*fd76c71bSTreehugger Robot 	s.showHeader = false;
535*fd76c71bSTreehugger Robot 	s.db = new Database();
536*fd76c71bSTreehugger Robot 	String dbname = null, sql = null;
537*fd76c71bSTreehugger Robot 	for (int i = 0; i < args.length; i++) {
538*fd76c71bSTreehugger Robot 	    if(args[i].compareTo("-html") ==0) {
539*fd76c71bSTreehugger Robot 		s.mode = Shell.MODE_Html;
540*fd76c71bSTreehugger Robot 	    } else if (args[i].compareTo("-list") == 0) {
541*fd76c71bSTreehugger Robot 		s.mode = Shell.MODE_List;
542*fd76c71bSTreehugger Robot 	    } else if (args[i].compareTo("-line") == 0) {
543*fd76c71bSTreehugger Robot 		s.mode = Shell.MODE_Line;
544*fd76c71bSTreehugger Robot 	    } else if (i < args.length - 1 &&
545*fd76c71bSTreehugger Robot 		       args[i].compareTo("-separator") == 0) {
546*fd76c71bSTreehugger Robot 		++i;
547*fd76c71bSTreehugger Robot 		s.sep = args[i];
548*fd76c71bSTreehugger Robot 	    } else if (args[i].compareTo("-header") == 0) {
549*fd76c71bSTreehugger Robot 		s.showHeader = true;
550*fd76c71bSTreehugger Robot 	    } else if (args[i].compareTo("-noheader") == 0) {
551*fd76c71bSTreehugger Robot 		s.showHeader = false;
552*fd76c71bSTreehugger Robot 	    } else if (args[i].compareTo("-echo") == 0) {
553*fd76c71bSTreehugger Robot 		s.echo = true;
554*fd76c71bSTreehugger Robot 	    } else if (args[i].compareTo("-key") == 0) {
555*fd76c71bSTreehugger Robot 		++i;
556*fd76c71bSTreehugger Robot 		key = args[i];
557*fd76c71bSTreehugger Robot 	    } else if (dbname == null) {
558*fd76c71bSTreehugger Robot 		dbname = args[i];
559*fd76c71bSTreehugger Robot 	    } else if (sql == null) {
560*fd76c71bSTreehugger Robot 		sql = args[i];
561*fd76c71bSTreehugger Robot 	    } else {
562*fd76c71bSTreehugger Robot 		System.err.println("Arguments: ?OPTIONS? FILENAME ?SQL?");
563*fd76c71bSTreehugger Robot 		System.exit(1);
564*fd76c71bSTreehugger Robot 	    }
565*fd76c71bSTreehugger Robot 	}
566*fd76c71bSTreehugger Robot 	if (dbname == null) {
567*fd76c71bSTreehugger Robot 	    System.err.println("No database file given");
568*fd76c71bSTreehugger Robot 	    System.exit(1);
569*fd76c71bSTreehugger Robot 	}
570*fd76c71bSTreehugger Robot 	try {
571*fd76c71bSTreehugger Robot 	    s.db.open(dbname, 0);
572*fd76c71bSTreehugger Robot 	} catch (Exception e) {
573*fd76c71bSTreehugger Robot 	    System.err.println("Unable to open database: " + e);
574*fd76c71bSTreehugger Robot 	    System.exit(1);
575*fd76c71bSTreehugger Robot 	}
576*fd76c71bSTreehugger Robot 	if (key != null) {
577*fd76c71bSTreehugger Robot 	    try {
578*fd76c71bSTreehugger Robot 		s.db.key(key);
579*fd76c71bSTreehugger Robot 	    } catch (Exception e) {
580*fd76c71bSTreehugger Robot 		System.err.println("Unable to set key: " + e);
581*fd76c71bSTreehugger Robot 		System.exit(1);
582*fd76c71bSTreehugger Robot 	    }
583*fd76c71bSTreehugger Robot 	}
584*fd76c71bSTreehugger Robot 	if (sql != null) {
585*fd76c71bSTreehugger Robot 	    s.do_cmd(sql);
586*fd76c71bSTreehugger Robot 	    s.pw.flush();
587*fd76c71bSTreehugger Robot 	} else {
588*fd76c71bSTreehugger Robot 	    BufferedReader is =
589*fd76c71bSTreehugger Robot 		new BufferedReader(new InputStreamReader(System.in));
590*fd76c71bSTreehugger Robot 	    s.do_input(is);
591*fd76c71bSTreehugger Robot 	    s.pw.flush();
592*fd76c71bSTreehugger Robot 	}
593*fd76c71bSTreehugger Robot 	try {
594*fd76c71bSTreehugger Robot 	    s.db.close();
595*fd76c71bSTreehugger Robot 	} catch (Exception ee) {
596*fd76c71bSTreehugger Robot 	}
597*fd76c71bSTreehugger Robot     }
598*fd76c71bSTreehugger Robot }
599*fd76c71bSTreehugger Robot 
600*fd76c71bSTreehugger Robot /**
601*fd76c71bSTreehugger Robot  * Internal class for dumping an entire database.
602*fd76c71bSTreehugger Robot  * It contains a special callback interface to traverse the
603*fd76c71bSTreehugger Robot  * tables of the current database and output create SQL statements
604*fd76c71bSTreehugger Robot  * and for the data insert SQL statements.
605*fd76c71bSTreehugger Robot  */
606*fd76c71bSTreehugger Robot 
607*fd76c71bSTreehugger Robot class DBDump implements Callback {
608*fd76c71bSTreehugger Robot     Shell s;
609*fd76c71bSTreehugger Robot 
DBDump(Shell s, String tables[])610*fd76c71bSTreehugger Robot     DBDump(Shell s, String tables[]) {
611*fd76c71bSTreehugger Robot         this.s = s;
612*fd76c71bSTreehugger Robot 	s.pw.println("BEGIN TRANSACTION;");
613*fd76c71bSTreehugger Robot         if (tables == null || tables.length == 0) {
614*fd76c71bSTreehugger Robot 	    try {
615*fd76c71bSTreehugger Robot 	        s.db.exec("SELECT name, type, sql FROM sqlite_master " +
616*fd76c71bSTreehugger Robot 			  "WHERE type!='meta' AND sql NOT NULL " +
617*fd76c71bSTreehugger Robot 			  "ORDER BY substr(type,2,1), name", this);
618*fd76c71bSTreehugger Robot 	    } catch (Exception e) {
619*fd76c71bSTreehugger Robot 	        s.err.println("SQL Error: " + e);
620*fd76c71bSTreehugger Robot 		s.err.flush();
621*fd76c71bSTreehugger Robot 	    }
622*fd76c71bSTreehugger Robot 	} else {
623*fd76c71bSTreehugger Robot 	    String arg[] = new String[1];
624*fd76c71bSTreehugger Robot 	    for (int i = 0; i < tables.length; i++) {
625*fd76c71bSTreehugger Robot 	        arg[0] = tables[i];
626*fd76c71bSTreehugger Robot 		try {
627*fd76c71bSTreehugger Robot 		    s.db.exec("SELECT name, type, sql FROM sqlite_master " +
628*fd76c71bSTreehugger Robot 			      "WHERE tbl_name LIKE '%q' AND type!='meta' " +
629*fd76c71bSTreehugger Robot 			      " AND sql NOT NULL " +
630*fd76c71bSTreehugger Robot 			      " ORDER BY substr(type,2,1), name",
631*fd76c71bSTreehugger Robot 			      this, arg);
632*fd76c71bSTreehugger Robot 		} catch (Exception e) {
633*fd76c71bSTreehugger Robot 		    s.err.println("SQL Error: " + e);
634*fd76c71bSTreehugger Robot 		    s.err.flush();
635*fd76c71bSTreehugger Robot 		}
636*fd76c71bSTreehugger Robot 	    }
637*fd76c71bSTreehugger Robot 	}
638*fd76c71bSTreehugger Robot 	s.pw.println("COMMIT;");
639*fd76c71bSTreehugger Robot     }
640*fd76c71bSTreehugger Robot 
columns(String col[])641*fd76c71bSTreehugger Robot     public void columns(String col[]) {
642*fd76c71bSTreehugger Robot 	/* Empty body to satisfy SQLite.Callback interface. */
643*fd76c71bSTreehugger Robot     }
644*fd76c71bSTreehugger Robot 
types(String args[])645*fd76c71bSTreehugger Robot     public void types(String args[]) {
646*fd76c71bSTreehugger Robot 	/* Empty body to satisfy SQLite.Callback interface. */
647*fd76c71bSTreehugger Robot     }
648*fd76c71bSTreehugger Robot 
newrow(String args[])649*fd76c71bSTreehugger Robot     public boolean newrow(String args[]) {
650*fd76c71bSTreehugger Robot         if (args.length != 3) {
651*fd76c71bSTreehugger Robot 	    return true;
652*fd76c71bSTreehugger Robot 	}
653*fd76c71bSTreehugger Robot 	s.pw.println(args[2] + ";");
654*fd76c71bSTreehugger Robot 	if (args[1].compareTo("table") == 0) {
655*fd76c71bSTreehugger Robot 	    Shell s2 = (Shell) s.clone();
656*fd76c71bSTreehugger Robot 	    s2.mode = Shell.MODE_Insert;
657*fd76c71bSTreehugger Robot 	    s2.set_table_name(args[0]);
658*fd76c71bSTreehugger Robot 	    String qargs[] = new String[1];
659*fd76c71bSTreehugger Robot 	    qargs[0] = args[0];
660*fd76c71bSTreehugger Robot 	    try {
661*fd76c71bSTreehugger Robot 	        if (s2.db.is3()) {
662*fd76c71bSTreehugger Robot 		    TableResult t = null;
663*fd76c71bSTreehugger Robot 		    t = s2.db.get_table("PRAGMA table_info('%q')", qargs);
664*fd76c71bSTreehugger Robot 		    String query;
665*fd76c71bSTreehugger Robot 		    if (t != null) {
666*fd76c71bSTreehugger Robot 		        StringBuffer sb = new StringBuffer();
667*fd76c71bSTreehugger Robot 			String sep = "";
668*fd76c71bSTreehugger Robot 
669*fd76c71bSTreehugger Robot 			sb.append("SELECT ");
670*fd76c71bSTreehugger Robot 			for (int i = 0; i < t.nrows; i++) {
671*fd76c71bSTreehugger Robot 			    String col = ((String[]) t.rows.elementAt(i))[1];
672*fd76c71bSTreehugger Robot 			    sb.append(sep + "quote(" +
673*fd76c71bSTreehugger Robot 				      Shell.sql_quote_dbl(col) + ")");
674*fd76c71bSTreehugger Robot 			    sep = ",";
675*fd76c71bSTreehugger Robot 			}
676*fd76c71bSTreehugger Robot 			sb.append(" from '%q'");
677*fd76c71bSTreehugger Robot 			query = sb.toString();
678*fd76c71bSTreehugger Robot 			s2.mode = Shell.MODE_Insert2;
679*fd76c71bSTreehugger Robot 		    } else {
680*fd76c71bSTreehugger Robot 		        query = "SELECT * from '%q'";
681*fd76c71bSTreehugger Robot 		    }
682*fd76c71bSTreehugger Robot 		    s2.db.exec(query, s2, qargs);
683*fd76c71bSTreehugger Robot 		} else {
684*fd76c71bSTreehugger Robot 		    s2.db.exec("SELECT * from '%q'", s2, qargs);
685*fd76c71bSTreehugger Robot 		}
686*fd76c71bSTreehugger Robot 	    } catch (Exception e) {
687*fd76c71bSTreehugger Robot 	        s.err.println("SQL Error: " + e);
688*fd76c71bSTreehugger Robot 		s.err.flush();
689*fd76c71bSTreehugger Robot 		return true;
690*fd76c71bSTreehugger Robot 	    }
691*fd76c71bSTreehugger Robot 	}
692*fd76c71bSTreehugger Robot 	return false;
693*fd76c71bSTreehugger Robot     }
694*fd76c71bSTreehugger Robot }
695