/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This source file is based on code taken from SQLLine 1.0.2
* See SQLLine notice in LICENSE
*/
package org.apache.hive.beeline;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
public class Commands {
private final BeeLine beeLine;
/**
* @param beeLine
*/
Commands(BeeLine beeLine) {
this.beeLine = beeLine;
}
public boolean metadata(String line) {
beeLine.debug(line);
String[] parts = beeLine.split(line);
List<String> params = new LinkedList<String>(Arrays.asList(parts));
if (parts == null || parts.length == 0) {
return dbinfo("");
}
params.remove(0);
params.remove(0);
beeLine.debug(params.toString());
return metadata(parts[1],
params.toArray(new String[0]));
}
public boolean metadata(String cmd, String[] args) {
if (!(beeLine.assertConnection())) {
return false;
}
try {
Method[] m = beeLine.getDatabaseMetaData().getClass().getMethods();
Set<String> methodNames = new TreeSet<String>();
Set<String> methodNamesUpper = new TreeSet<String>();
for (int i = 0; i < m.length; i++) {
methodNames.add(m[i].getName());
methodNamesUpper.add(m[i].getName().toUpperCase());
}
if (!methodNamesUpper.contains(cmd.toUpperCase())) {
beeLine.error(beeLine.loc("no-such-method", cmd));
beeLine.error(beeLine.loc("possible-methods"));
for (Iterator<String> i = methodNames.iterator(); i.hasNext();) {
beeLine.error(" " + i.next());
}
return false;
}
Object res = beeLine.getReflector().invoke(beeLine.getDatabaseMetaData(),
DatabaseMetaData.class, cmd, Arrays.asList(args));
if (res instanceof ResultSet) {
ResultSet rs = (ResultSet) res;
if (rs != null) {
try {
beeLine.print(rs);
} finally {
rs.close();
}
}
} else if (res != null) {
beeLine.output(res.toString());
}
} catch (Exception e) {
return beeLine.error(e);
}
return true;
}
public boolean history(String line) {
List hist = beeLine.getConsoleReader().getHistory().getHistoryList();
int index = 1;
for (Iterator i = hist.iterator(); i.hasNext(); index++) {
beeLine.output(beeLine.getColorBuffer().pad(index + ".", 6)
.append(i.next().toString()));
}
return true;
}
String arg1(String line, String paramname) {
return arg1(line, paramname, null);
}
String arg1(String line, String paramname, String def) {
String[] ret = beeLine.split(line);
if (ret == null || ret.length != 2) {
if (def != null) {
return def;
}
throw new IllegalArgumentException(beeLine.loc("arg-usage",
new Object[] {ret.length == 0 ? "" : ret[0],
paramname}));
}
return ret[1];
}
public boolean indexes(String line) throws Exception {
return metadata("getIndexInfo", new String[] {
beeLine.getConnection().getCatalog(), null,
arg1(line, "table name"),
false + "",
true + ""});
}
public boolean primarykeys(String line) throws Exception {
return metadata("getPrimaryKeys", new String[] {
beeLine.getConnection().getCatalog(), null,
arg1(line, "table name"),});
}
public boolean exportedkeys(String line) throws Exception {
return metadata("getExportedKeys", new String[] {
beeLine.getConnection().getCatalog(), null,
arg1(line, "table name"),});
}
public boolean importedkeys(String line) throws Exception {
return metadata("getImportedKeys", new String[] {
beeLine.getConnection().getCatalog(), null,
arg1(line, "table name"),});
}
public boolean procedures(String line) throws Exception {
return metadata("getProcedures", new String[] {
beeLine.getConnection().getCatalog(), null,
arg1(line, "procedure name pattern", "%"),});
}
public boolean tables(String line) throws Exception {
return metadata("getTables", new String[] {
beeLine.getConnection().getCatalog(), null,
arg1(line, "table name", "%"), null});
}
public boolean typeinfo(String line) throws Exception {
return metadata("getTypeInfo", new String[0]);
}
public boolean nativesql(String sql) throws Exception {
if (sql.startsWith(BeeLine.COMMAND_PREFIX)) {
sql = sql.substring(1);
}
if (sql.startsWith("native")) {
sql = sql.substring("native".length() + 1);
}
String nat = beeLine.getConnection().nativeSQL(sql);
beeLine.output(nat);
return true;
}
public boolean columns(String line) throws Exception {
return metadata("getColumns", new String[] {
beeLine.getConnection().getCatalog(), null,
arg1(line, "table name"), "%"});
}
public boolean dropall(String line) {
if (beeLine.getDatabaseConnection() == null || beeLine.getDatabaseConnection().getUrl() == null) {
return beeLine.error(beeLine.loc("no-current-connection"));
}
try {
if (!(beeLine.getConsoleReader().readLine(beeLine.loc("really-drop-all")).equals("y"))) {
return beeLine.error("abort-drop-all");
}
List<String> cmds = new LinkedList<String>();
ResultSet rs = beeLine.getTables();
try {
while (rs.next()) {
cmds.add("DROP TABLE "
+ rs.getString("TABLE_NAME") + ";");
}
} finally {
try {
rs.close();
} catch (Exception e) {
}
}
// run as a batch
return beeLine.runCommands(cmds) == cmds.size();
} catch (Exception e) {
return beeLine.error(e);
}
}
public boolean reconnect(String line) {
if (beeLine.getDatabaseConnection() == null || beeLine.getDatabaseConnection().getUrl() == null) {
return beeLine.error(beeLine.loc("no-current-connection"));
}
beeLine.info(beeLine.loc("reconnecting", beeLine.getDatabaseConnection().getUrl()));
try {
beeLine.getDatabaseConnection().reconnect();
} catch (Exception e) {
return beeLine.error(e);
}
return true;
}
public boolean scan(String line) throws IOException {
TreeSet<String> names = new TreeSet<String>();
if (beeLine.getDrivers() == null) {
beeLine.setDrivers(Arrays.asList(beeLine.scanDrivers(line)));
}
beeLine.info(beeLine.loc("drivers-found-count", beeLine.getDrivers().size()));
// unique the list
for (Iterator<Driver> i = beeLine.getDrivers().iterator(); i.hasNext();) {
names.add(i.next().getClass().getName());
}
beeLine.output(beeLine.getColorBuffer()
.bold(beeLine.getColorBuffer().pad(beeLine.loc("compliant"), 10).getMono())
.bold(beeLine.getColorBuffer().pad(beeLine.loc("jdbc-version"), 8).getMono())
.bold(beeLine.getColorBuffer(beeLine.loc("driver-class")).getMono()));
for (Iterator<String> i = names.iterator(); i.hasNext();) {
String name = i.next().toString();
try {
Driver driver = (Driver) Class.forName(name).newInstance();
ColorBuffer msg = beeLine.getColorBuffer()
.pad(driver.jdbcCompliant() ? "yes" : "no", 10)
.pad(driver.getMajorVersion() + "."
+ driver.getMinorVersion(), 8)
.append(name);
if (driver.jdbcCompliant()) {
beeLine.output(msg);
} else {
beeLine.output(beeLine.getColorBuffer().red(msg.getMono()));
}
} catch (Throwable t) {
beeLine.output(beeLine.getColorBuffer().red(name)); // error with driver
}
}
return true;
}
public boolean save(String line) throws IOException {
beeLine.info(beeLine.loc("saving-options", beeLine.getOpts().getPropertiesFile()));
beeLine.getOpts().save();
return true;
}
public boolean load(String line) throws IOException {
beeLine.getOpts().load();
beeLine.info(beeLine.loc("loaded-options", beeLine.getOpts().getPropertiesFile()));
return true;
}
public boolean config(String line) {
try {
Properties props = beeLine.getOpts().toProperties();
Set keys = new TreeSet(props.keySet());
for (Iterator i = keys.iterator(); i.hasNext();) {
String key = (String) i.next();
beeLine.output(beeLine.getColorBuffer()
.green(beeLine.getColorBuffer().pad(key.substring(
beeLine.getOpts().PROPERTY_PREFIX.length()), 20)
.getMono())
.append(props.getProperty(key)));
}
} catch (Exception e) {
return beeLine.error(e);
}
return true;
}
public boolean set(String line) {
if (line == null || line.trim().equals("set")
|| line.length() == 0) {
return config(null);
}
String[] parts = beeLine.split(line, 3, "Usage: set <key> <value>");
if (parts == null) {
return false;
}
String key = parts[1];
String value = parts[2];
boolean success = beeLine.getOpts().set(key, value, false);
// if we autosave, then save
if (success && beeLine.getOpts().getAutosave()) {
try {
beeLine.getOpts().save();
} catch (Exception saveException) {
}
}
return success;
}
public boolean commit(String line) throws SQLException {
if (!(beeLine.assertConnection())) {
return false;
}
if (!(beeLine.assertAutoCommit())) {
return false;
}
try {
long start = System.currentTimeMillis();
beeLine.getDatabaseConnection().getConnection().commit();
long end = System.currentTimeMillis();
beeLine.showWarnings();
beeLine.info(beeLine.loc("commit-complete")
+ " " + beeLine.locElapsedTime(end - start));
return true;
} catch (Exception e) {
return beeLine.error(e);
}
}
public boolean rollback(String line) throws SQLException {
if (!(beeLine.assertConnection())) {
return false;
}
if (!(beeLine.assertAutoCommit())) {
return false;
}
try {
long start = System.currentTimeMillis();
beeLine.getDatabaseConnection().getConnection().rollback();
long end = System.currentTimeMillis();
beeLine.showWarnings();
beeLine.info(beeLine.loc("rollback-complete")
+ " " + beeLine.locElapsedTime(end - start));
return true;
} catch (Exception e) {
return beeLine.error(e);
}
}
public boolean autocommit(String line) throws SQLException {
if (!(beeLine.assertConnection())) {
return false;
}
if (line.endsWith("on")) {
beeLine.getDatabaseConnection().getConnection().setAutoCommit(true);
} else if (line.endsWith("off")) {
beeLine.getDatabaseConnection().getConnection().setAutoCommit(false);
}
beeLine.showWarnings();
beeLine.autocommitStatus(beeLine.getDatabaseConnection().getConnection());
return true;
}
public boolean dbinfo(String line) {
if (!(beeLine.assertConnection())) {
return false;
}
beeLine.showWarnings();
int padlen = 50;
String[] m = new String[] {
"allProceduresAreCallable",
"allTablesAreSelectable",
"dataDefinitionCausesTransactionCommit",
"dataDefinitionIgnoredInTransactions",
"doesMaxRowSizeIncludeBlobs",
"getCatalogSeparator",
"getCatalogTerm",
"getDatabaseProductName",
"getDatabaseProductVersion",
"getDefaultTransactionIsolation",
"getDriverMajorVersion",
"getDriverMinorVersion",
"getDriverName",
"getDriverVersion",
"getExtraNameCharacters",
"getIdentifierQuoteString",
"getMaxBinaryLiteralLength",
"getMaxCatalogNameLength",
"getMaxCharLiteralLength",
"getMaxColumnNameLength",
"getMaxColumnsInGroupBy",
"getMaxColumnsInIndex",
"getMaxColumnsInOrderBy",
"getMaxColumnsInSelect",
"getMaxColumnsInTable",
"getMaxConnections",
"getMaxCursorNameLength",
"getMaxIndexLength",
"getMaxProcedureNameLength",
"getMaxRowSize",
"getMaxSchemaNameLength",
"getMaxStatementLength",
"getMaxStatements",
"getMaxTableNameLength",
"getMaxTablesInSelect",
"getMaxUserNameLength",
"getNumericFunctions",
"getProcedureTerm",
"getSchemaTerm",
"getSearchStringEscape",
"getSQLKeywords",
"getStringFunctions",
"getSystemFunctions",
"getTimeDateFunctions",
"getURL",
"getUserName",
"isCatalogAtStart",
"isReadOnly",
"nullPlusNonNullIsNull",
"nullsAreSortedAtEnd",
"nullsAreSortedAtStart",
"nullsAreSortedHigh",
"nullsAreSortedLow",
"storesLowerCaseIdentifiers",
"storesLowerCaseQuotedIdentifiers",
"storesMixedCaseIdentifiers",
"storesMixedCaseQuotedIdentifiers",
"storesUpperCaseIdentifiers",
"storesUpperCaseQuotedIdentifiers",
"supportsAlterTableWithAddColumn",
"supportsAlterTableWithDropColumn",
"supportsANSI92EntryLevelSQL",
"supportsANSI92FullSQL",
"supportsANSI92IntermediateSQL",
"supportsBatchUpdates",
"supportsCatalogsInDataManipulation",
"supportsCatalogsInIndexDefinitions",
"supportsCatalogsInPrivilegeDefinitions",
"supportsCatalogsInProcedureCalls",
"supportsCatalogsInTableDefinitions",
"supportsColumnAliasing",
"supportsConvert",
"supportsCoreSQLGrammar",
"supportsCorrelatedSubqueries",
"supportsDataDefinitionAndDataManipulationTransactions",
"supportsDataManipulationTransactionsOnly",
"supportsDifferentTableCorrelationNames",
"supportsExpressionsInOrderBy",
"supportsExtendedSQLGrammar",
"supportsFullOuterJoins",
"supportsGroupBy",
"supportsGroupByBeyondSelect",
"supportsGroupByUnrelated",
"supportsIntegrityEnhancementFacility",
"supportsLikeEscapeClause",
"supportsLimitedOuterJoins",
"supportsMinimumSQLGrammar",
"supportsMixedCaseIdentifiers",
"supportsMixedCaseQuotedIdentifiers",
"supportsMultipleResultSets",
"supportsMultipleTransactions",
"supportsNonNullableColumns",
"supportsOpenCursorsAcrossCommit",
"supportsOpenCursorsAcrossRollback",
"supportsOpenStatementsAcrossCommit",
"supportsOpenStatementsAcrossRollback",
"supportsOrderByUnrelated",
"supportsOuterJoins",
"supportsPositionedDelete",
"supportsPositionedUpdate",
"supportsSchemasInDataManipulation",
"supportsSchemasInIndexDefinitions",
"supportsSchemasInPrivilegeDefinitions",
"supportsSchemasInProcedureCalls",
"supportsSchemasInTableDefinitions",
"supportsSelectForUpdate",
"supportsStoredProcedures",
"supportsSubqueriesInComparisons",
"supportsSubqueriesInExists",
"supportsSubqueriesInIns",
"supportsSubqueriesInQuantifieds",
"supportsTableCorrelationNames",
"supportsTransactions",
"supportsUnion",
"supportsUnionAll",
"usesLocalFilePerTable",
"usesLocalFiles",
};
for (int i = 0; i < m.length; i++) {
try {
beeLine.output(beeLine.getColorBuffer().pad(m[i], padlen).append(
"" + beeLine.getReflector().invoke(beeLine.getDatabaseMetaData(),
m[i], new Object[0])));
} catch (Exception e) {
beeLine.handleException(e);
}
}
return true;
}
public boolean verbose(String line) {
beeLine.info("verbose: on");
return set("set verbose true");
}
public boolean outputformat(String line) {
return set("set " + line);
}
public boolean brief(String line) {
beeLine.info("verbose: off");
return set("set verbose false");
}
public boolean isolation(String line) throws SQLException {
if (!(beeLine.assertConnection())) {
return false;
}
int i;
if (line.endsWith("TRANSACTION_NONE")) {
i = Connection.TRANSACTION_NONE;
} else if (line.endsWith("TRANSACTION_READ_COMMITTED")) {
i = Connection.TRANSACTION_READ_COMMITTED;
} else if (line.endsWith("TRANSACTION_READ_UNCOMMITTED")) {
i = Connection.TRANSACTION_READ_UNCOMMITTED;
} else if (line.endsWith("TRANSACTION_REPEATABLE_READ")) {
i = Connection.TRANSACTION_REPEATABLE_READ;
} else if (line.endsWith("TRANSACTION_SERIALIZABLE")) {
i = Connection.TRANSACTION_SERIALIZABLE;
} else {
return beeLine.error("Usage: isolation <TRANSACTION_NONE "
+ "| TRANSACTION_READ_COMMITTED "
+ "| TRANSACTION_READ_UNCOMMITTED "
+ "| TRANSACTION_REPEATABLE_READ "
+ "| TRANSACTION_SERIALIZABLE>");
}
beeLine.getDatabaseConnection().getConnection().setTransactionIsolation(i);
int isol = beeLine.getDatabaseConnection().getConnection().getTransactionIsolation();
final String isoldesc;
switch (i)
{
case Connection.TRANSACTION_NONE:
isoldesc = "TRANSACTION_NONE";
break;
case Connection.TRANSACTION_READ_COMMITTED:
isoldesc = "TRANSACTION_READ_COMMITTED";
break;
case Connection.TRANSACTION_READ_UNCOMMITTED:
isoldesc = "TRANSACTION_READ_UNCOMMITTED";
break;
case Connection.TRANSACTION_REPEATABLE_READ:
isoldesc = "TRANSACTION_REPEATABLE_READ";
break;
case Connection.TRANSACTION_SERIALIZABLE:
isoldesc = "TRANSACTION_SERIALIZABLE";
break;
default:
isoldesc = "UNKNOWN";
}
beeLine.info(beeLine.loc("isolation-status", isoldesc));
return true;
}
public boolean batch(String line) {
if (!(beeLine.assertConnection())) {
return false;
}
if (beeLine.getBatch() == null) {
beeLine.setBatch(new LinkedList<String>());
beeLine.info(beeLine.loc("batch-start"));
return true;
} else {
beeLine.info(beeLine.loc("running-batch"));
try {
beeLine.runBatch(beeLine.getBatch());
return true;
} catch (Exception e) {
return beeLine.error(e);
} finally {
beeLine.setBatch(null);
}
}
}
public boolean sql(String line) {
return execute(line, false);
}
public boolean call(String line) {
return execute(line, true);
}
private boolean execute(String line, boolean call) {
if (line == null || line.length() == 0) {
return false; // ???
}
// ### FIXME: doing the multi-line handling down here means
// higher-level logic never sees the extra lines. So,
// for example, if a script is being saved, it won't include
// the continuation lines! This is logged as sf.net
// bug 879518.
// use multiple lines for statements not terminated by ";"
try {
while (!(line.trim().endsWith(";")) && beeLine.getOpts().isAllowMultiLineCommand()) {
StringBuilder prompt = new StringBuilder(beeLine.getPrompt());
for (int i = 0; i < prompt.length() - 1; i++) {
if (prompt.charAt(i) != '>') {
prompt.setCharAt(i, i % 2 == 0 ? '.' : ' ');
}
}
String extra = beeLine.getConsoleReader().readLine(prompt.toString());
if (!beeLine.isComment(extra)) {
line += " " + extra;
}
}
} catch (Exception e) {
beeLine.handleException(e);
}
if (line.endsWith(";")) {
line = line.substring(0, line.length() - 1);
}
if (!(beeLine.assertConnection())) {
return false;
}
String sql = line;
if (sql.startsWith(BeeLine.COMMAND_PREFIX)) {
sql = sql.substring(1);
}
String prefix = call ? "call" : "sql";
if (sql.startsWith(prefix)) {
sql = sql.substring(prefix.length());
}
// batch statements?
if (beeLine.getBatch() != null) {
beeLine.getBatch().add(sql);
return true;
}
try {
Statement stmnt = null;
boolean hasResults;
try {
long start = System.currentTimeMillis();
if (call) {
stmnt = beeLine.getDatabaseConnection().getConnection().prepareCall(sql);
hasResults = ((CallableStatement) stmnt).execute();
} else {
stmnt = beeLine.createStatement();
hasResults = stmnt.execute(sql);
}
beeLine.showWarnings();
if (hasResults) {
do {
ResultSet rs = stmnt.getResultSet();
try {
int count = beeLine.print(rs);
long end = System.currentTimeMillis();
beeLine.info(beeLine.loc("rows-selected", count) + " "
+ beeLine.locElapsedTime(end - start));
} finally {
rs.close();
}
} while (BeeLine.getMoreResults(stmnt));
} else {
int count = stmnt.getUpdateCount();
long end = System.currentTimeMillis();
beeLine.info(beeLine.loc("rows-affected", count)
+ " " + beeLine.locElapsedTime(end - start));
}
} finally {
if (stmnt != null) {
stmnt.close();
}
}
} catch (Exception e) {
return beeLine.error(e);
}
beeLine.showWarnings();
return true;
}
public boolean quit(String line) {
beeLine.setExit(true);
close(null);
return true;
}
/**
* Close all connections.
*/
public boolean closeall(String line) {
if (close(null)) {
while (close(null)) {
;
}
return true;
}
return false;
}
/**
* Close the current connection.
*/
public boolean close(String line) {
if (beeLine.getDatabaseConnection() == null) {
return false;
}
try {
if (beeLine.getDatabaseConnection().getConnection() != null
&& !(beeLine.getDatabaseConnection().getConnection().isClosed())) {
beeLine.info(beeLine.loc("closing",
beeLine.getDatabaseConnection().getConnection().getClass().getName()));
beeLine.getDatabaseConnection().getConnection().close();
} else {
beeLine.info(beeLine.loc("already-closed"));
}
} catch (Exception e) {
return beeLine.error(e);
}
beeLine.getDatabaseConnections().remove();
return true;
}
/**
* Connect to the database defined in the specified properties file.
*/
public boolean properties(String line) throws Exception {
String example = "";
example += "Usage: properties <properties file>" + BeeLine.getSeparator();
String[] parts = beeLine.split(line);
if (parts.length < 2) {
return beeLine.error(example);
}
int successes = 0;
for (int i = 1; i < parts.length; i++) {
Properties props = new Properties();
props.load(new FileInputStream(parts[i]));
if (connect(props)) {
successes++;
}
}
if (successes != (parts.length - 1)) {
return false;
} else {
return true;
}
}
public boolean connect(String line) throws Exception {
String example = "Usage: connect <url> <username> <password> [driver]"
+ BeeLine.getSeparator();
String[] parts = beeLine.split(line);
if (parts == null) {
return false;
}
if (parts.length < 2) {
return beeLine.error(example);
}
String url = parts.length < 2 ? null : parts[1];
String user = parts.length < 3 ? null : parts[2];
String pass = parts.length < 4 ? null : parts[3];
String driver = parts.length < 5 ? null : parts[4];
Properties props = new Properties();
if (url != null) {
props.setProperty("url", url);
}
if (driver != null) {
props.setProperty("driver", driver);
}
if (user != null) {
props.setProperty("user", user);
}
if (pass != null) {
props.setProperty("password", pass);
}
return connect(props);
}
private String getProperty(Properties props, String[] keys) {
for (int i = 0; i < keys.length; i++) {
String val = props.getProperty(keys[i]);
if (val != null) {
return val;
}
}
for (Iterator i = props.keySet().iterator(); i.hasNext();) {
String key = (String) i.next();
for (int j = 0; j < keys.length; j++) {
if (key.endsWith(keys[j])) {
return props.getProperty(key);
}
}
}
return null;
}
public boolean connect(Properties props) throws IOException {
String url = getProperty(props, new String[] {
"url",
"javax.jdo.option.ConnectionURL",
"ConnectionURL",
});
String driver = getProperty(props, new String[] {
"driver",
"javax.jdo.option.ConnectionDriverName",
"ConnectionDriverName",
});
String username = getProperty(props, new String[] {
"user",
"javax.jdo.option.ConnectionUserName",
"ConnectionUserName",
});
String password = getProperty(props, new String[] {
"password",
"javax.jdo.option.ConnectionPassword",
"ConnectionPassword",
});
if (url == null || url.length() == 0) {
return beeLine.error("Property \"url\" is required");
}
if (driver == null || driver.length() == 0) {
if (!beeLine.scanForDriver(url)) {
return beeLine.error(beeLine.loc("no-driver", url));
}
}
beeLine.info("Connecting to " + url);
if (username == null) {
username = beeLine.getConsoleReader().readLine("Enter username for " + url + ": ");
}
if (password == null) {
password = beeLine.getConsoleReader().readLine("Enter password for " + url + ": ",
new Character('*'));
}
try {
beeLine.getDatabaseConnections().setConnection(
new DatabaseConnection(beeLine, driver, url, username, password));
beeLine.getDatabaseConnection().getConnection();
beeLine.setCompletions();
return true;
} catch (SQLException sqle) {
return beeLine.error(sqle);
} catch (IOException ioe) {
return beeLine.error(ioe);
}
}
public boolean rehash(String line) {
try {
if (!(beeLine.assertConnection())) {
return false;
}
if (beeLine.getDatabaseConnection() != null) {
beeLine.getDatabaseConnection().setCompletions(false);
}
return true;
} catch (Exception e) {
return beeLine.error(e);
}
}
/**
* List the current connections
*/
public boolean list(String line) {
int index = 0;
beeLine.info(beeLine.loc("active-connections", beeLine.getDatabaseConnections().size()));
for (Iterator<DatabaseConnection> i = beeLine.getDatabaseConnections().iterator(); i.hasNext(); index++) {
DatabaseConnection c = i.next();
boolean closed = false;
try {
closed = c.getConnection().isClosed();
} catch (Exception e) {
closed = true;
}
beeLine.output(beeLine.getColorBuffer().pad(" #" + index + "", 5)
.pad(closed ? beeLine.loc("closed") : beeLine.loc("open"), 9)
.append(c.getUrl()));
}
return true;
}
public boolean all(String line) {
int index = beeLine.getDatabaseConnections().getIndex();
boolean success = true;
for (int i = 0; i < beeLine.getDatabaseConnections().size(); i++) {
beeLine.getDatabaseConnections().setIndex(i);
beeLine.output(beeLine.loc("executing-con", beeLine.getDatabaseConnection()));
// ### FIXME: this is broken for multi-line SQL
success = sql(line.substring("all ".length())) && success;
}
// restore index
beeLine.getDatabaseConnections().setIndex(index);
return success;
}
public boolean go(String line) {
String[] parts = beeLine.split(line, 2, "Usage: go <connection index>");
if (parts == null) {
return false;
}
int index = Integer.parseInt(parts[1]);
if (!(beeLine.getDatabaseConnections().setIndex(index))) {
beeLine.error(beeLine.loc("invalid-connection", "" + index));
list(""); // list the current connections
return false;
}
return true;
}
/**
* Save or stop saving a script to a file
*/
public boolean script(String line) {
if (beeLine.getScriptOutputFile() == null) {
return startScript(line);
} else {
return stopScript(line);
}
}
/**
* Stop writing to the script file and close the script.
*/
private boolean stopScript(String line) {
try {
beeLine.getScriptOutputFile().close();
} catch (Exception e)
{
beeLine.handleException(e);
}
beeLine.output(beeLine.loc("script-closed", beeLine.getScriptOutputFile()));
beeLine.setScriptOutputFile(null);
return true;
}
/**
* Start writing to the specified script file.
*/
private boolean startScript(String line) {
if (beeLine.getScriptOutputFile() != null) {
return beeLine.error(beeLine.loc("script-already-running", beeLine.getScriptOutputFile()));
}
String[] parts = beeLine.split(line, 2, "Usage: script <filename>");
if (parts == null) {
return false;
}
try {
beeLine.setScriptOutputFile(new OutputFile(parts[1]));
beeLine.output(beeLine.loc("script-started", beeLine.getScriptOutputFile()));
return true;
} catch (Exception e) {
return beeLine.error(e);
}
}
/**
* Run a script from the specified file.
*/
public boolean run(String line) {
String[] parts = beeLine.split(line, 2, "Usage: run <scriptfile>");
if (parts == null) {
return false;
}
List<String> cmds = new LinkedList<String>();
try {
BufferedReader reader = new BufferedReader(new FileReader(
parts[1]));
try {
// ### NOTE: fix for sf.net bug 879427
StringBuilder cmd = null;
for (;;) {
String scriptLine = reader.readLine();
if (scriptLine == null) {
break;
}
String trimmedLine = scriptLine.trim();
if (beeLine.getOpts().getTrimScripts()) {
scriptLine = trimmedLine;
}
if (cmd != null) {
// we're continuing an existing command
cmd.append(" \n");
cmd.append(scriptLine);
if (trimmedLine.endsWith(";")) {
// this command has terminated
cmds.add(cmd.toString());
cmd = null;
}
} else {
// we're starting a new command
if (beeLine.needsContinuation(scriptLine)) {
// multi-line
cmd = new StringBuilder(scriptLine);
} else {
// single-line
cmds.add(scriptLine);
}
}
}
if (cmd != null) {
// ### REVIEW: oops, somebody left the last command
// unterminated; should we fix it for them or complain?
// For now be nice and fix it.
cmd.append(";");
cmds.add(cmd.toString());
}
} finally {
reader.close();
}
// success only if all the commands were successful
return beeLine.runCommands(cmds) == cmds.size();
} catch (Exception e) {
return beeLine.error(e);
}
}
/**
* Save or stop saving all output to a file.
*/
public boolean record(String line) {
if (beeLine.getRecordOutputFile() == null) {
return startRecording(line);
} else {
return stopRecording(line);
}
}
/**
* Stop writing output to the record file.
*/
private boolean stopRecording(String line) {
try {
beeLine.getRecordOutputFile().close();
} catch (Exception e) {
beeLine.handleException(e);
}
beeLine.output(beeLine.loc("record-closed", beeLine.getRecordOutputFile()));
beeLine.setRecordOutputFile(null);
return true;
}
/**
* Start writing to the specified record file.
*/
private boolean startRecording(String line) {
if (beeLine.getRecordOutputFile() != null) {
return beeLine.error(beeLine.loc("record-already-running", beeLine.getRecordOutputFile()));
}
String[] parts = beeLine.split(line, 2, "Usage: record <filename>");
if (parts == null) {
return false;
}
try {
beeLine.setRecordOutputFile(new OutputFile(parts[1]));
beeLine.output(beeLine.loc("record-started", beeLine.getRecordOutputFile()));
return true;
} catch (Exception e) {
return beeLine.error(e);
}
}
public boolean describe(String line) throws SQLException {
String[] table = beeLine.split(line, 2, "Usage: describe <table name>");
if (table == null) {
return false;
}
ResultSet rs;
if (table[1].equals("tables")) {
rs = beeLine.getTables();
} else {
rs = beeLine.getColumns(table[1]);
}
if (rs == null) {
return false;
}
beeLine.print(rs);
rs.close();
return true;
}
public boolean help(String line) {
String[] parts = beeLine.split(line);
String cmd = parts.length > 1 ? parts[1] : "";
int count = 0;
TreeSet<ColorBuffer> clist = new TreeSet<ColorBuffer>();
for (int i = 0; i < beeLine.commandHandlers.length; i++) {
if (cmd.length() == 0 ||
Arrays.asList(beeLine.commandHandlers[i].getNames()).contains(cmd)) {
clist.add(beeLine.getColorBuffer().pad("!" + beeLine.commandHandlers[i].getName(), 20)
.append(beeLine.wrap(beeLine.commandHandlers[i].getHelpText(), 60, 20)));
}
}
for (Iterator<ColorBuffer> i = clist.iterator(); i.hasNext();) {
beeLine.output(i.next());
}
if (cmd.length() == 0) {
beeLine.output("");
beeLine.output(beeLine.loc("comments", beeLine.getApplicationContactInformation()));
}
return true;
}
public boolean manual(String line) throws IOException {
InputStream in = BeeLine.class.getResourceAsStream("manual.txt");
if (in == null) {
return beeLine.error(beeLine.loc("no-manual"));
}
BufferedReader breader = new BufferedReader(
new InputStreamReader(in));
String man;
int index = 0;
while ((man = breader.readLine()) != null) {
index++;
beeLine.output(man);
// silly little pager
if (index % (beeLine.getOpts().getMaxHeight() - 1) == 0) {
String ret = beeLine.getConsoleReader().readLine(beeLine.loc("enter-for-more"));
if (ret != null && ret.startsWith("q")) {
break;
}
}
}
breader.close();
return true;
}
}