📄 sqltool.java
字号:
/* Copyright (c) 2001-2005, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hsqldb.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
/* $Id: SqlTool.java,v 1.55 2006/07/27 20:04:31 fredt Exp $ */
/**
* Sql Tool. A command-line and/or interactive SQL tool.
* (Note: For every Javadoc block comment, I'm using a single blank line
* immediately after the description, just like's Sun's examples in
* their Coding Conventions document).
*
* See JavaDocs for the main method for syntax of how to run.
*
* @see #main()
* @version $Revision: 1.55 $
* @author Blaine Simpson unsaved@users
*/
public class SqlTool {
private static final String DEFAULT_RCFILE =
System.getProperty("user.home") + "/sqltool.rc";
private static Connection conn;
// N.b. the following is static!
private static boolean noexit; // Whether System.exit() may be called.
private static String revnum = null;
/**
* The configuration identifier to use when connection parameters are
* specified on the command line
*/
private static String CMDLINE_ID = "cmdline";
static {
revnum = "$Revision: 1.55 $".substring("$Revision: ".length(),
"$Revision: 1.55 $".length()
- 2);
}
private static final String SYNTAX_MESSAGE =
"Usage: java [-Dsqlfile.X=Y...] org.hsqldb.util.SqlTool \\\n"
+ " [--optname [optval...]] urlid [file1.sql...]\n"
+ "where arguments are:\n"
+ " --help Displays this message\n"
+ " --list List urlids in the rc file\n"
+ " --noInput Do not read stdin (default if sql file given\n"
+ " or --sql switch used).\n"
+ " --stdInput Read stdin IN ADDITION to sql files/--sql input\n"
+ " --inlineRc URL=val1,USER=val2[,DRIVER=val3][,CHARSET=val4][,TRUST=val5]\n"
+ " Inline RC file variables\n"
+ " --debug Print Debug info to stderr\n"
+ " --noAutoFile Do not execute auto.sql from home dir\n"
+ " --autoCommit Auto-commit JDBC DML commands\n"
+ " --sql \"SQL; Statements\" Execute given SQL instead of stdin (before\n"
+ " SQL files if any are specified) where \"SQL\"\n"
+ " consists of SQL command(s). See the Guide.\n"
+ " --rcFile /file/path.rc Connect Info File [$HOME/sqltool.rc]\n"
+ " --abortOnErr Abort on Error (overrides defaults)\n"
+ " --continueOnErr Continue on Error (overrides defaults)\n"
+ " --setVar NAME1=val1[,NAME2=val2...] PL variables\n"
+ " --driver a.b.c.Driver JDBC driver class ["
+ RCData.DEFAULT_JDBC_DRIVER + "]\n"
+ " urlid ID of url/userame/password in rcfile\n"
+ " file1.sql... SQL files to be executed [stdin]\n"
+ " "
+ "(Use '-' for non-interactively stdin).\n"
+ "See the SqlTool Manual for the supported sqltool.* System Properties.\n"
+ "SqlTool v. " + revnum + ".";
/** Utility nested class for internal use. */
private static class BadCmdline extends Exception {}
;
/** Utility object for internal use. */
private static BadCmdline bcl = new BadCmdline();
/** Nested class for external callers of SqlTool.main() */
public static class SqlToolException extends Exception {
public SqlToolException() {
super();
}
public SqlToolException(String s) {
super(s);
}
}
/**
* Exit the main() method by either throwing an exception or exiting JVM.
*
* Call return() right after you call this method, because this method
* will not exit if (noexit is true && retval == 0).
*/
private static void exitMain(int retval) throws SqlToolException {
exitMain(retval, null);
}
/**
* Exit the main() method by either throwing an exception or exiting JVM.
*
* Call return() right after you call this method, because this method
* will not exit if (noexit is true && retval == 0).
*/
private static void exitMain(int retval,
String msg) throws SqlToolException {
if (noexit) {
if (retval == 0) {
return;
} else if (msg == null) {
throw new SqlToolException();
} else {
throw new SqlToolException(msg);
}
} else {
if (msg != null) {
((retval == 0) ? System.out
: System.err).println(msg);
}
System.exit(retval);
}
}
/**
* Prompt the user for a password.
*
* @param username The user the password is for
* @return The password the user entered
*/
private static String promptForPassword(String username)
throws SqlToolException {
BufferedReader console;
String password;
password = null;
try {
console = new BufferedReader(new InputStreamReader(System.in));
// Prompt for password
System.out.print(username + "'s password: ");
// Read the password from the command line
password = console.readLine();
if (password == null) {
password = "";
} else {
password = password.trim();
}
} catch (IOException e) {
exitMain(30,
"Error while reading password from console: "
+ e.getMessage());
}
return password;
}
/**
* Parses a comma delimited string of name value pairs into a
* <code>Map</code> object.
*
* @param varString The string to parse
* @param varMap The map to save the pared values into
* @param lowerCaseKeys Set to <code>true</code> if the map keys should be
* converted to lower case
*/
private static void varParser(String varString, Map varMap,
boolean lowerCaseKeys)
throws SqlToolException {
int equals;
String curSetting;
String var;
String val;
StringTokenizer allvars;
if ((varMap == null) || (varString == null)) {
return;
}
allvars = new StringTokenizer(varString, ",");
while (allvars.hasMoreTokens()) {
curSetting = allvars.nextToken().trim();
equals = curSetting.indexOf('=');
if (equals < 1) {
throw new SqlToolException(
"Var settings not of format NAME=var[,...]");
}
var = curSetting.substring(0, equals).trim();
val = curSetting.substring(equals + 1).trim();
if (var.length() < 1 || val.length() < 1) {
throw new SqlToolException(
"Var settings not of format NAME=var[,...]");
}
if (lowerCaseKeys) {
var = var.toLowerCase();
}
varMap.put(var, val);
}
}
/**
* Connect to a JDBC Database and execute the commands given on
* stdin or in SQL file(s).
* Like most main methods, this is not intended to be thread-safe.
*
* @param arg Run "java... org.hsqldb.util.SqlTool --help" for syntax.
* @throws SqlToolException May be thrown only if the system property
* 'sqltool.noexit' is set (to anything).
*/
public static void main(String[] arg) throws SqlToolException {
/*
* The big picture is, we parse input args; load a RCData;
* get a JDBC Connection with the RCData; instantiate and
* execute as many SqlFiles as we need to.
*/
String rcFile = null;
File tmpFile = null;
String sqlText = null;
String driver = null;
String targetDb = null;
String varSettings = null;
boolean debug = false;
File[] scriptFiles = null;
int i = -1;
boolean listMode = false;
boolean interactive = false;
boolean noinput = false;
boolean noautoFile = false;
boolean autoCommit = false;
Boolean coeOverride = null;
Boolean stdinputOverride = null;
String rcParams = null;
String rcUrl = null;
String rcUsername = null;
String rcPassword = null;
String rcDriver = null;
String rcCharset = null;
String rcTruststore = null;
Map rcFields = null;
String parameter;
noexit = System.getProperty("sqltool.noexit") != null;
try {
while ((i + 1 < arg.length) && arg[i + 1].startsWith("--")) {
i++;
if (arg[i].length() == 2) {
break; // "--"
}
parameter = arg[i].substring(2).toLowerCase();
if (parameter.equals("help")) {
exitMain(0, SYNTAX_MESSAGE);
return;
} else if (parameter.equals("abortonerr")) {
if (coeOverride != null) {
exitMain(
0, "Switches '--abortOnErr' and "
+ "'--continueOnErr' are mutually exclusive");
return;
}
coeOverride = Boolean.FALSE;
} else if (parameter.equals("continueonerr")) {
if (coeOverride != null) {
exitMain(
0, "Switches '--abortOnErr' and "
+ "'--continueOnErr' are mutually exclusive");
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -