Add "Describe" command, with support for describing both (a) specific table(s) and...
[squelch.git] / src / main / java / net / jaekl / squelch / stmt / Describe.java
1 package net.jaekl.squelch.stmt;
2
3 import java.io.IOException;
4 import java.io.PrintWriter;
5 import java.sql.Connection;
6 import java.sql.DatabaseMetaData;
7 import java.sql.ResultSet;
8 import java.sql.SQLException;
9 import java.util.Locale;
10
11 import net.jaekl.squelch.db.DbDriver;
12
13 public class Describe extends Stmt {
14
15         @Override
16         public boolean handles(String line) 
17         {
18                 if (null == line) {
19                         return false;
20                 }
21                 
22                 String trimmed = line.trim();
23                 if (trimmed.equals("\\d")) {
24                         return true;
25                 }
26                 if (trimmed.startsWith("\\d ")) {
27                         return true;
28                 }
29                 
30                 String upper = trimmed.toUpperCase(Locale.CANADA);
31                 if (upper.equals("DESCRIBE")) {
32                         return true;
33                 }
34                 if (upper.startsWith("DESCRIBE ")) {
35                         return true;
36                 }
37                 
38                 return false;
39         }
40
41         @Override
42         public int exec(DbDriver driver, Connection conn, PrintWriter pw, String line)
43                         throws IOException, SQLException 
44         {
45                 DatabaseMetaData metaData = conn.getMetaData();
46                 
47                 String trimmed = line.trim();
48                 String tablePattern;
49                 if (trimmed.startsWith("\\d")) {
50                         tablePattern = trimmed.substring(2).trim();
51                 }
52                 else {
53                         assert (trimmed.toUpperCase(Locale.CANADA).startsWith("DESCRIBE"));
54                         tablePattern = trimmed.substring(8).trim();
55                 }
56                 tablePattern = driver.adjustCase(tablePattern);
57                 
58                 if (tablePattern.length() < 1) {
59                         return describeAll(pw, metaData);
60                 }
61                 else {
62                         return describeTable(pw, metaData, tablePattern);
63                 }
64         }
65
66         int describeAll(PrintWriter pw, DatabaseMetaData metaData)
67                 throws SQLException
68         {
69                 try (ResultSet rs = metaData.getTables(null, null, "%", null))
70                 {
71                         TabularResultSet tabular = new TabularResultSet(rs);
72                         // TODO:  StringTable i18n
73                         tabular.printTable(pw, "???");
74                 }
75                 
76                 return 0;
77         }
78
79         int describeTable(PrintWriter pw, DatabaseMetaData metaData, String tablePattern) 
80                 throws SQLException
81         {
82                 boolean found = false;
83                 String trimmed = tablePattern.trim();
84                 
85                 try (ResultSet rs = metaData.getTables(null, null, trimmed, null))
86                 {
87                         while (rs.next()) {
88                                 found = true;
89                                 describe(pw, metaData, rs);
90                         }
91                 }
92                 
93                 if (!found) {
94                         // TODO:  StringTable i18n
95                         pw.println("??? " + trimmed);
96                 }
97                 return 0;
98         }
99         
100         void describe(PrintWriter pw, DatabaseMetaData metaData, ResultSet tableRs)
101                 throws SQLException
102         {
103                 String catalogueName = tableRs.getString(1);
104                 String schemaName = tableRs.getString(2);
105                 String tableName = tableRs.getString(3);
106                 String tableType = tableRs.getString(4);
107                 String remarks = tableRs.getString(5);
108                 
109                 pw.print("" + tableType + " ");
110                 if (null != catalogueName) {
111                         pw.print(catalogueName + ".");
112                 }
113                 if (null != schemaName) {
114                         pw.print(schemaName + ".");
115                 }
116                 pw.print("" + tableName);
117                 if ((null != remarks) && (remarks.length() > 0)) {
118                         pw.print(" (" + remarks + ")");
119                 }
120                 pw.println("");
121                 
122                 try (ResultSet colsRs = metaData.getColumns(catalogueName, schemaName, tableName, null))
123                 {
124                         TabularColumnInfo tabular = new TabularColumnInfo(colsRs);
125                         // TODO:  StringTable i18n
126                         tabular.printTable(pw, "???");
127                 }
128         }
129 }