Changeset: 6581a18f89e3 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6581a18f89e3
Modified Files:
java/ChangeLog
java/src/main/java/nl/cwi/monetdb/client/JdbcClient.java
Branch: default
Log Message:
Improved JdbcClient program:
- the \d command now also lists other table types such as temporary tables,
merge, remote and replica tables
- use con.getSchema() instead of executeQuery("SELECT CURRENT_SCHEMA") fetch
resultset etc. to retrieve the current schema
- at startup it now also lists what the current schema is
- in interactive mode (no -f is specified on startup) timing information of
execution and fetching data is now printed
- simplified (no need to pass on global variables) and improved code and
readablity
- made the class final
- changed prompt from user name to sql (as is the case in mclient)
- simplified class Table by removing the alwasy empty catalog variable and its
methods
diffs (truncated from 658 to 300 lines):
diff --git a/java/ChangeLog b/java/ChangeLog
--- a/java/ChangeLog
+++ b/java/ChangeLog
@@ -1,6 +1,11 @@
# ChangeLog file for java
# This file is updated with Maddlog
+* Thu Sep 8 2016 Martin van Dinther <[email protected]>
+- Improved JdbcClient program by fixing some resource leaks.
+- Extended JdbcClient program by showing elapsed time information for each
+ query or command when started in interactive mode (no -f was used at
startup).
+
* Thu Sep 1 2016 Martin van Dinther <[email protected]>
- Improved fetching and output speed of JdbcClient program for query results.
diff --git a/java/src/main/java/nl/cwi/monetdb/client/JdbcClient.java
b/java/src/main/java/nl/cwi/monetdb/client/JdbcClient.java
--- a/java/src/main/java/nl/cwi/monetdb/client/JdbcClient.java
+++ b/java/src/main/java/nl/cwi/monetdb/client/JdbcClient.java
@@ -22,11 +22,12 @@ import java.net.*;
* it demonstrates the power of the JDBC interface since it built on top
* of JDBC only.
*
- * @author Fabian Groffen
- * @version 1.2
+ * @author Fabian Groffen, Martin van Dinther
+ * @version 1.3
*/
-public class JdbcClient {
+public final class JdbcClient {
+
private static Connection con;
private static Statement stmt;
private static BufferedReader in;
@@ -109,7 +110,8 @@ public class JdbcClient {
// look for a file called .monetdb in the current dir or in the
// user's homedir and read its preferences
File pref = new File(".monetdb");
- if (!pref.exists()) pref = new
File(System.getProperty("user.home"), ".monetdb");
+ if (!pref.exists())
+ pref = new File(System.getProperty("user.home"),
".monetdb");
if (pref.exists()) {
try {
copts.processFile(pref);
@@ -135,34 +137,33 @@ public class JdbcClient {
if (copts.getOption("help").isPresent()) {
System.out.print(
-"Usage java -jar jdbcclient.jar\n" +
-" [-h host[:port]] [-p port] [-f file] [-u user]\n" +
-" [-l language] [-d database] [-e] [-D [table]]\n" +
-" [-X<opt>]\n" +
-"or using long option equivalents --host --port --file --user --language\n" +
-"--dump --echo --database.\n" +
-"Arguments may be written directly after the option like -p50000.\n" +
-"\n" +
-"If no host and port are given, localhost and 50000 are assumed. An
.monetdb\n" +
-"file may exist in the user's home directory. This file can contain\n" +
-"preferences to use each time JdbcClient is started. Options given on the\n" +
-"command line override the preferences file. The .monetdb file syntax is\n" +
-"<option>=<value> where option is one of the options host, port, file, mode\n"
+
-"debug, or password. Note that the last one is perilous and therefore not\n" +
-"available as command line option.\n" +
-"If no input file is given using the -f flag, an interactive session is\n" +
-"started on the terminal.\n" +
-"\n" +
-"OPTIONS\n" +
-copts.produceHelpMessage()
-);
+ "Usage java -jar jdbcclient.jar\n" +
+ " [-h host[:port]] [-p port]
[-f file] [-u user]\n" +
+ " [-l language] [-d database]
[-e] [-D [table]]\n" +
+ " [-X<opt>]\n" +
+ "or using long option equivalents --host --port
--file --user --language\n" +
+ "--dump --echo --database.\n" +
+ "Arguments may be written directly after the
option like -p50000.\n" +
+ "\n" +
+ "If no host and port are given, localhost and
50000 are assumed. An .monetdb\n" +
+ "file may exist in the user's home directory.
This file can contain\n" +
+ "preferences to use each time JdbcClient is
started. Options given on the\n" +
+ "command line override the preferences file.
The .monetdb file syntax is\n" +
+ "<option>=<value> where option is one of the
options host, port, file, mode\n" +
+ "debug, or password. Note that the last one is
perilous and therefore not\n" +
+ "available as command line option.\n" +
+ "If no input file is given using the -f flag,
an interactive session is\n" +
+ "started on the terminal.\n" +
+ "\n" +
+ "OPTIONS\n" +
+ copts.produceHelpMessage()
+ );
System.exit(0);
} else if (copts.getOption("version").isPresent()) {
// We cannot use the DatabaseMetaData here, because we
// cannot get a Connection. So instead, we just get the
// values we want out of the Driver directly.
- System.out.println("Driver: v" +
-
nl.cwi.monetdb.jdbc.MonetDriver.getDriverVersion());
+ System.out.println("JDBC Driver: v" +
nl.cwi.monetdb.jdbc.MonetDriver.getDriverVersion());
System.exit(0);
}
@@ -172,8 +173,7 @@ copts.produceHelpMessage()
// whether the semi-colon at the end of a String terminates the
// query or not (default = yes => SQL)
boolean scolonterm = true;
- boolean xmlMode =
-
"xml".equals(copts.getOption("Xoutput").getArgument());
+ boolean xmlMode =
"xml".equals(copts.getOption("Xoutput").getArgument());
// we need the password from the user, fetch it with a pseudo
// password protector
@@ -233,8 +233,7 @@ copts.produceHelpMessage()
);
SQLWarning warn = con.getWarnings();
while (warn != null) {
- System.err.println("Connection warning: " +
- warn.getMessage());
+ System.err.println("Connection warning: " +
warn.getMessage());
warn = warn.getNextWarning();
}
con.clearWarnings();
@@ -242,6 +241,7 @@ copts.produceHelpMessage()
System.err.println("Database connect failed: " +
e.getMessage());
System.exit(1);
}
+
try {
dbmd = con.getMetaData();
} catch (SQLException e) {
@@ -251,8 +251,7 @@ copts.produceHelpMessage()
}
stmt = con.createStatement();
- // see if we will have to perform a database dump (only in SQL
- // mode)
+ // see if we will have to perform a database dump (only in SQL
mode)
if ("sql".equals(lang) && copts.getOption("dump").isPresent()) {
ResultSet tbl;
@@ -261,17 +260,17 @@ copts.produceHelpMessage()
if (oc.isPresent())
out = new PrintWriter(new BufferedWriter(new
FileWriter(oc.getArgument())));
- // we only want tables and views to be dumped, unless a
specific
+ // we only want user tables and views to be dumped,
unless a specific
// table is requested
String[] types = {"TABLE", "VIEW"};
- if (copts.getOption("dump").getArgumentCount() > 0)
types = null;
- // request the tables available in the database
- tbl = dbmd.getTables(null, null, null, types);
+ if (copts.getOption("dump").getArgumentCount() > 0)
+ types = null;
+ // request the tables available in the current schema
in the database
+ tbl = dbmd.getTables(null, con.getSchema(), null,
types);
List<Table> tables = new LinkedList<Table>();
while (tbl.next()) {
tables.add(new Table(
- tbl.getString("TABLE_CAT"),
tbl.getString("TABLE_SCHEM"),
tbl.getString("TABLE_NAME"),
tbl.getString("TABLE_TYPE")));
@@ -284,14 +283,15 @@ copts.produceHelpMessage()
exporter.setProperty(XMLExporter.TYPE_NIL,
XMLExporter.VALUE_XSI);
} else {
exporter = new SQLExporter(out);
- // stick with inserts for now, in the future we
might do
- // COPY INTO's here using VALUE_COPY
+ // stick with SQL INSERT INTO commands for now
+ // in the future we might do COPY INTO's here
using VALUE_COPY
exporter.setProperty(SQLExporter.TYPE_OUTPUT,
SQLExporter.VALUE_INSERT);
}
exporter.useSchemas(true);
// start SQL output
- if (!xmlMode) out.println("START TRANSACTION;\n");
+ if (!xmlMode)
+ out.println("START TRANSACTION;\n");
// dump specific table(s) or not?
if (copts.getOption("dump").getArgumentCount() > 0) {
// yes we do
@@ -303,7 +303,7 @@ copts.produceHelpMessage()
ttmp.getFqname().equalsIgnoreCase(dumpers[j].toString()))
{
// dump the table
- doDump(out, ttmp, dbmd,
stmt);
+ doDump(out, ttmp);
}
}
}
@@ -353,14 +353,19 @@ copts.produceHelpMessage()
// we now have the right order to dump tables
for (Table t : tables) {
// dump the table
- doDump(out, t, dbmd, stmt);
+ doDump(out, t);
}
}
- if (!xmlMode) out.println("COMMIT;");
+ if (!xmlMode)
+ out.println("COMMIT;");
out.flush();
+ // free resources, close the statement
+ stmt.close();
+ // close the connection with the database
con.close();
+ // completed database dump
System.exit(0);
}
@@ -369,7 +374,7 @@ copts.produceHelpMessage()
exporter.setProperty(XMLExporter.TYPE_NIL,
XMLExporter.VALUE_XSI);
} else {
exporter = new SQLExporter(out);
- // we want nice table views
+ // we want nice table formatted output
exporter.setProperty(SQLExporter.TYPE_OUTPUT,
SQLExporter.VALUE_TABLE);
}
exporter.useSchemas(false);
@@ -409,13 +414,12 @@ copts.produceHelpMessage()
// print welcome message
out.println("Welcome to the MonetDB
interactive JDBC terminal!");
if (dbmd != null) {
- out.println("Database: " +
-
dbmd.getDatabaseProductName() + " v" +
-
dbmd.getDatabaseProductVersion() + ", '" +
-
dbmd.getConnection().getCatalog() + "'");
- out.println("Driver: " +
dbmd.getDriverName() + " v" +
-
dbmd.getDriverVersion());
+ out.println("Database Server: "
+ dbmd.getDatabaseProductName() +
+ " v" +
dbmd.getDatabaseProductVersion());
+ out.println("JDBC Driver: " +
dbmd.getDriverName() +
+ " v" +
dbmd.getDriverVersion());
}
+ out.println("Current Schema: " +
con.getSchema());
out.println("Type \\q to quit, \\h for
a list of available commands");
out.flush();
}
@@ -526,7 +530,7 @@ copts.produceHelpMessage()
if (!hasFile) {
lastac = con.getAutoCommit();
out.println("auto commit mode: " + (lastac ? "on" :
"off"));
- out.print(getPrompt(user, stack, true));
+ out.print(getPrompt(stack, true));
out.flush();
}
@@ -539,16 +543,16 @@ copts.produceHelpMessage()
curLine = in.readLine();
if (curLine == null) {
out.println("");
- if (query != "") {
+ if (!query.isEmpty()) {
try {
- executeQuery(query, stmt, out);
+ executeQuery(query, stmt, out,
!hasFile);
} catch (SQLException e) {
out.flush();
do {
if (hasFile) {
System.err.println("Error on line " + i + ": [" + e.getSQLState() + "] " +
e.getMessage());
} else {
-
System.err.println("Error: [" + e.getSQLState() + "] " + e.getMessage());
+
System.err.println("Error [" + e.getSQLState() + "]: " + e.getMessage());
}
// print all error
messages in the chain (if any)
} while ((e =
e.getNextException()) != null);
@@ -561,7 +565,7 @@ copts.produceHelpMessage()
out.println("auto
commit mode: " + (ac ? "on" : "off"));
lastac = ac;
}
- out.print(getPrompt(user,
stack, wasComplete));
+ out.print(getPrompt(stack,
wasComplete));
}
out.flush();
// try to read again
@@ -579,15 +583,16 @@ copts.produceHelpMessage()
}
qp = scanQuery(curLine, stack, scolonterm);
if (!qp.isEmpty()) {
+ String command = qp.getQuery();
doProcess = true;
if (wasComplete) {
doProcess = false;
// check for commands only when the
previous row was
// complete
- if (qp.getQuery().equals("\\q")) {
+ if (command.equals("\\q")) {
// quit
break;
- } else if
(qp.getQuery().startsWith("\\h")) {
+ } else if (command.startsWith("\\h")) {
out.println("Available
commands:");
out.println("\\q quits
this program");
out.println("\\h this help
screen");
@@ -596,64 +601,56 @@ copts.produceHelpMessage()
out.println("\\d<obj> describes
the given table or view");
out.println("\\l<uri> executes
the contents of the given file or URL");
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list