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("<"); 129*fd76c71bSTreehugger Robot } else if (c == '>') { 130*fd76c71bSTreehugger Robot sb.append(">"); 131*fd76c71bSTreehugger Robot } else if (c == '&') { 132*fd76c71bSTreehugger Robot sb.append("&"); 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