adds support for null suppression
[squelch.git] / src / main / java / net / jaekl / squelch / Squelch.java
index 5985338bf00a6f6b22bb8e03110b7337ed9e4873..953a1790031f93b05722a3f7ca3517bb725daa61 100644 (file)
@@ -2,8 +2,17 @@ package net.jaekl.squelch;
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
 import java.util.Locale;
 
+import net.jaekl.squelch.db.DbDriver;
+import net.jaekl.squelch.db.MsSqlDriver;
+import net.jaekl.squelch.db.MySqlDriver;
+import net.jaekl.squelch.db.OracleDriver;
+import net.jaekl.squelch.db.PostgresqlDriver;
+import net.jaekl.squelch.stmt.Describe;
+import net.jaekl.squelch.stmt.PSet;
 import net.jaekl.squelch.stmt.Select;
 import net.jaekl.squelch.stmt.Stmt;
 import net.jaekl.squelch.util.ConsoleInput;
@@ -12,24 +21,37 @@ import net.jaekl.squelch.util.ConsoleUtil;
 
 public class Squelch {
        static final String PROMPT = "> ";
+       private static final DbDriver[] DB_DRIVERS = {
+               new MsSqlDriver(),
+               new MySqlDriver(),
+               new OracleDriver(),
+               new PostgresqlDriver()
+       };
        private static final Stmt[] READ_ONLY_STATEMENTS = {
+               new Describe(),
+               new PSet(),
                new Select()
        };
        
+       private Args m_args;
        private Stmt[] m_statements;
 
        public Squelch() {
+               m_args = new Args(this.getClass().getName());
                m_statements = READ_ONLY_STATEMENTS;
        }
        
-       public void doMain(String[] args)
+       public void doMain(String[] params)
        {
-               ConsoleInputImpl ci;
                try (PrintWriter pw = new PrintWriter(System.out))
                {
-                       ci = ConsoleUtil.getInst().getInput();
+                       if (!m_args.parseArgs(pw, params)) {
+                               return;
+                       }
+                       
+                       ConsoleInputImpl ci = ConsoleUtil.getInst().getInput();
                        pumpLines(pw, ci);                      
-               } catch (IOException e) {
+               } catch (IOException | ClassNotFoundException | SQLException | SquelchException e) {
                        e.printStackTrace();
                }
        }
@@ -38,15 +60,60 @@ public class Squelch {
                new Squelch().doMain(args);
        }
        
-       void pumpLines(PrintWriter pw, ConsoleInput ci) throws IOException {
+       boolean isQuit(String line) 
+       {
+               if ((null == line)) {
+                       return true;
+               }
+               String trimmed = line.trim();
+               if (trimmed.endsWith(";")) {
+                       trimmed = trimmed.substring(0, trimmed.length() - 1).trim();
+               }
+               String upperCased = trimmed.toUpperCase(Locale.CANADA);
+               
+               if (  "EXIT".equals(upperCased)
+                  || "QUIT".equals(upperCased)
+                  || "\\q".equals(trimmed) ) 
+               {
+                       return true;
+               }
+               return false;
+       }
+       
+       Connection getConnection(DbDriver driver, String jdbcUrl) 
+               throws ClassNotFoundException, SQLException, SquelchException 
+       {
+               return driver.connect(jdbcUrl, m_args.getUser(), m_args.getPass());
+       }
+       
+       DbDriver getDriverFor(String jdbcUrl) throws SquelchException 
+       {
+               for (DbDriver driver : DB_DRIVERS) {
+                       if (driver.handles(jdbcUrl)) {
+                               return driver;
+                       }
+               }
+               throw new SquelchException("Cannot determine DB Driver for JDBC URL:  \"" + jdbcUrl + "\".");
+       }
+       
+       void pumpLines(PrintWriter pw, ConsoleInput ci) throws IOException, ClassNotFoundException, SQLException, SquelchException 
+       {
                String line = null;
+               String jdbcUrl = m_args.getUrl();
+               DbDriver driver = getDriverFor(jdbcUrl);
+
                while (true) {
                        boolean processed = false;
                        line = ci.readLine(PROMPT);
                        
                        for (Stmt statement : m_statements) {
                                if (statement.handles(line)) {
-                                       //statement.exec(conn, pw, line);
+                                       try (Connection conn = getConnection(driver, jdbcUrl)){
+                                               statement.exec(driver, conn, pw, line);
+                                       }
+                                       catch (SQLException exc) {
+                                               exc.printStackTrace(pw);
+                                       }
                                        processed = true;
                                        break;
                                }
@@ -57,27 +124,10 @@ public class Squelch {
                                        break;
                                }
                                // Unrecognized command
+                               // TODO:  add a string table, and a natural-language error message.
                                pw.println("??? \"" + line + "\"");
                        }
+                       pw.flush();
                }
-       }
-       
-       boolean isQuit(String line) {
-               if ((null == line)) {
-                       return true;
-               }
-               String trimmed = line.trim();
-               if (trimmed.endsWith(";")) {
-                       trimmed = trimmed.substring(0, trimmed.length() - 1).trim();
-               }
-               String upperCased = trimmed.toUpperCase(Locale.CANADA);
-               
-               if (  "EXIT".equals(upperCased)
-                  || "QUIT".equals(upperCased)
-                  || "\\q".equals(trimmed) ) 
-               {
-                       return true;
-               }
-               return false;
-       }
+       }       
 }