Add "Describe" command, with support for describing both (a) specific table(s) and...
[squelch.git] / src / main / java / net / jaekl / squelch / stmt / Describe.java
diff --git a/src/main/java/net/jaekl/squelch/stmt/Describe.java b/src/main/java/net/jaekl/squelch/stmt/Describe.java
new file mode 100644 (file)
index 0000000..a76e5f0
--- /dev/null
@@ -0,0 +1,129 @@
+package net.jaekl.squelch.stmt;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Locale;
+
+import net.jaekl.squelch.db.DbDriver;
+
+public class Describe extends Stmt {
+
+       @Override
+       public boolean handles(String line) 
+       {
+               if (null == line) {
+                       return false;
+               }
+               
+               String trimmed = line.trim();
+               if (trimmed.equals("\\d")) {
+                       return true;
+               }
+               if (trimmed.startsWith("\\d ")) {
+                       return true;
+               }
+               
+               String upper = trimmed.toUpperCase(Locale.CANADA);
+               if (upper.equals("DESCRIBE")) {
+                       return true;
+               }
+               if (upper.startsWith("DESCRIBE ")) {
+                       return true;
+               }
+               
+               return false;
+       }
+
+       @Override
+       public int exec(DbDriver driver, Connection conn, PrintWriter pw, String line)
+                       throws IOException, SQLException 
+       {
+               DatabaseMetaData metaData = conn.getMetaData();
+               
+               String trimmed = line.trim();
+               String tablePattern;
+               if (trimmed.startsWith("\\d")) {
+                       tablePattern = trimmed.substring(2).trim();
+               }
+               else {
+                       assert (trimmed.toUpperCase(Locale.CANADA).startsWith("DESCRIBE"));
+                       tablePattern = trimmed.substring(8).trim();
+               }
+               tablePattern = driver.adjustCase(tablePattern);
+               
+               if (tablePattern.length() < 1) {
+                       return describeAll(pw, metaData);
+               }
+               else {
+                       return describeTable(pw, metaData, tablePattern);
+               }
+       }
+
+       int describeAll(PrintWriter pw, DatabaseMetaData metaData)
+               throws SQLException
+       {
+               try (ResultSet rs = metaData.getTables(null, null, "%", null))
+               {
+                       TabularResultSet tabular = new TabularResultSet(rs);
+                       // TODO:  StringTable i18n
+                       tabular.printTable(pw, "???");
+               }
+               
+               return 0;
+       }
+
+       int describeTable(PrintWriter pw, DatabaseMetaData metaData, String tablePattern) 
+               throws SQLException
+       {
+               boolean found = false;
+               String trimmed = tablePattern.trim();
+               
+               try (ResultSet rs = metaData.getTables(null, null, trimmed, null))
+               {
+                       while (rs.next()) {
+                               found = true;
+                               describe(pw, metaData, rs);
+                       }
+               }
+               
+               if (!found) {
+                       // TODO:  StringTable i18n
+                       pw.println("??? " + trimmed);
+               }
+               return 0;
+       }
+       
+       void describe(PrintWriter pw, DatabaseMetaData metaData, ResultSet tableRs)
+               throws SQLException
+       {
+               String catalogueName = tableRs.getString(1);
+               String schemaName = tableRs.getString(2);
+               String tableName = tableRs.getString(3);
+               String tableType = tableRs.getString(4);
+               String remarks = tableRs.getString(5);
+               
+               pw.print("" + tableType + " ");
+               if (null != catalogueName) {
+                       pw.print(catalogueName + ".");
+               }
+               if (null != schemaName) {
+                       pw.print(schemaName + ".");
+               }
+               pw.print("" + tableName);
+               if ((null != remarks) && (remarks.length() > 0)) {
+                       pw.print(" (" + remarks + ")");
+               }
+               pw.println("");
+               
+               try (ResultSet colsRs = metaData.getColumns(catalogueName, schemaName, tableName, null))
+               {
+                       TabularColumnInfo tabular = new TabularColumnInfo(colsRs);
+                       // TODO:  StringTable i18n
+                       tabular.printTable(pw, "???");
+               }
+       }
+}