提交 8e3d4e7d authored 作者: Thomas Mueller's avatar Thomas Mueller

H2 Console: the server properties directory can now be set on the command line.

上级 6f56b7de
...@@ -18,7 +18,9 @@ Change Log ...@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>New feature INSERT INTO ... DIRECT SELECT, mainly to speed up loading tables <ul><li>H2 Console: the server properties directory can now be set on the command line using
java ... -properties &lt;directory&gt;. Issue 159.
</li><li>New feature INSERT INTO ... DIRECT SELECT, mainly to speed up loading tables
from a CSV file. When using DIRECT, then the results from the query are directly applied from a CSV file. When using DIRECT, then the results from the query are directly applied
in the target table without any intermediate step (without temporary file). in the target table without any intermediate step (without temporary file).
</li><li>Converting binary data to UUID was incorrect when the converting more than 31 bytes. </li><li>Converting binary data to UUID was incorrect when the converting more than 31 bytes.
......
...@@ -81,7 +81,6 @@ See also <a href="build.html#providing_patches">Providing Patches</a>. ...@@ -81,7 +81,6 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>Write more tests and documentation for MVCC (Multi Version Concurrency Control). </li><li>Write more tests and documentation for MVCC (Multi Version Concurrency Control).
</li><li>Find a tool to view large text file (larger than 100 MB), with find, page up and down (like less), truncate before / after. </li><li>Find a tool to view large text file (larger than 100 MB), with find, page up and down (like less), truncate before / after.
</li><li>Implement, test, document XAConnection and so on. </li><li>Implement, test, document XAConnection and so on.
</li><li>Issue 159: System property for the H2 Console and TCP configuration (which .h2.server.properties and .h2.keystore to use).
</li><li>Pluggable data type (for streaming, hashing, compression, validation, conversion, encryption). </li><li>Pluggable data type (for streaming, hashing, compression, validation, conversion, encryption).
</li><li>CHECK: find out what makes CHECK=TRUE slow, move to CHECK2. </li><li>CHECK: find out what makes CHECK=TRUE slow, move to CHECK2.
</li><li>Drop with invalidate views (so that source code is not lost). Check what other databases do exactly. </li><li>Drop with invalidate views (so that source code is not lost). Check what other databases do exactly.
......
...@@ -356,9 +356,14 @@ public class Constants { ...@@ -356,9 +356,14 @@ public class Constants {
public static final int SELECTIVITY_DISTINCT_COUNT = 10000; public static final int SELECTIVITY_DISTINCT_COUNT = 10000;
/** /**
* The name of the server properties file. * The default directory name of the server properties file for the H2 Console.
*/ */
public static final String SERVER_PROPERTIES_FILE = ".h2.server.properties"; public static final String SERVER_PROPERTIES_DIR = "~";
/**
* The name of the server properties file for the H2 Console.
*/
public static final String SERVER_PROPERTIES_NAME = ".h2.server.properties";
/** /**
* Queries that take longer than this number of milliseconds are written to * Queries that take longer than this number of milliseconds are written to
......
...@@ -36,6 +36,6 @@ org.h2.tools.RunScript.main=Options are case sensitive. Supported options are\:\ ...@@ -36,6 +36,6 @@ org.h2.tools.RunScript.main=Options are case sensitive. Supported options are\:\
org.h2.tools.Script=Creates a SQL script file by extracting the schema and data of a database. org.h2.tools.Script=Creates a SQL script file by extracting the schema and data of a database.
org.h2.tools.Script.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-url "<url>"] The database URL (jdbc\:...)\n[-user <user>] The user name (default\: sa)\n[-password <pwd>] The password\n[-script <file>] The target script file name (default\: backup.sql)\n[-options ...] A list of options (only for embedded H2, see SCRIPT)\n[-quiet] Do not print progress information org.h2.tools.Script.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-url "<url>"] The database URL (jdbc\:...)\n[-user <user>] The user name (default\: sa)\n[-password <pwd>] The password\n[-script <file>] The target script file name (default\: backup.sql)\n[-options ...] A list of options (only for embedded H2, see SCRIPT)\n[-quiet] Do not print progress information
org.h2.tools.Server=Starts the H2 Console (web-) server, TCP, and PG server. org.h2.tools.Server=Starts the H2 Console (web-) server, TCP, and PG server.
org.h2.tools.Server.main=When running without options, -tcp, -web, -browser and -pg are started.\nOptions are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-web] Start the web server with the H2 Console\n[-webAllowOthers] Allow other computers to connect - see below\n[-webDaemon] Use a daemon thread\n[-webPort <port>] The port (default\: 8082)\n[-webSSL] Use encrypted (HTTPS) connections\n[-browser] Start a browser connecting to the web server\n[-tcp] Start the TCP server\n[-tcpAllowOthers] Allow other computers to connect - see below\n[-tcpDaemon] Use a daemon thread\n[-tcpPort <port>] The port (default\: 9092)\n[-tcpSSL] Use encrypted (SSL) connections\n[-tcpPassword <pwd>] The password for shutting down a TCP server\n[-tcpShutdown "<url>"] Stop the TCP server; example\: tcp\://localhost\n[-tcpShutdownForce] Do not wait until all connections are closed\n[-pg] Start the PG server\n[-pgAllowOthers] Allow other computers to connect - see below\n[-pgDaemon] Use a daemon thread\n[-pgPort <port>] The port (default\: 5435)\n[-baseDir <dir>] The base directory for H2 databases (all servers)\n[-ifExists] Only existing databases may be opened (all servers)\n[-trace] Print additional trace information (all servers)\nThe options -xAllowOthers are potentially risky.\nFor details, see Advanced Topics / Protection against Remote Access. org.h2.tools.Server.main=When running without options, -tcp, -web, -browser and -pg are started.\nOptions are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-web] Start the web server with the H2 Console\n[-webAllowOthers] Allow other computers to connect - see below\n[-webDaemon] Use a daemon thread\n[-webPort <port>] The port (default\: 8082)\n[-webSSL] Use encrypted (HTTPS) connections\n[-browser] Start a browser connecting to the web server\n[-tcp] Start the TCP server\n[-tcpAllowOthers] Allow other computers to connect - see below\n[-tcpDaemon] Use a daemon thread\n[-tcpPort <port>] The port (default\: 9092)\n[-tcpSSL] Use encrypted (SSL) connections\n[-tcpPassword <pwd>] The password for shutting down a TCP server\n[-tcpShutdown "<url>"] Stop the TCP server; example\: tcp\://localhost\n[-tcpShutdownForce] Do not wait until all connections are closed\n[-pg] Start the PG server\n[-pgAllowOthers] Allow other computers to connect - see below\n[-pgDaemon] Use a daemon thread\n[-pgPort <port>] The port (default\: 5435)\n[-properties "<dir>"] The server properties directory (default\: ~)\n[-baseDir <dir>] The base directory for H2 databases (all servers)\n[-ifExists] Only existing databases may be opened (all servers)\n[-trace] Print additional trace information (all servers)\nThe options -xAllowOthers are potentially risky.\nFor details, see Advanced Topics / Protection against Remote Access.
org.h2.tools.Shell=Interactive command line tool to access a database using JDBC. org.h2.tools.Shell=Interactive command line tool to access a database using JDBC.
org.h2.tools.Shell.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-url "<url>"] The database URL (jdbc\:h2\:...)\n[-user <user>] The user name\n[-password <pwd>] The password\n[-driver <class>] The JDBC driver class to use (not required in most cases)\n[-sql "<statements>"] Execute the SQL statements and exit\nIf special characters don't work as expected, you may need to use\n -Dfile.encoding\=UTF-8 (Mac OS X) or CP850 (Windows). org.h2.tools.Shell.main=Options are case sensitive. Supported options are\:\n[-help] or [-?] Print the list of options\n[-url "<url>"] The database URL (jdbc\:h2\:...)\n[-user <user>] The user name\n[-password <pwd>] The password\n[-driver <class>] The JDBC driver class to use (not required in most cases)\n[-sql "<statements>"] Execute the SQL statements and exit\n[-properties "<dir>"] Load the server properties from this directory\nIf special characters don't work as expected, you may need to use\n -Dfile.encoding\=UTF-8 (Mac OS X) or CP850 (Windows).
...@@ -43,7 +43,7 @@ public class CipherFactory { ...@@ -43,7 +43,7 @@ public class CipherFactory {
* The default password to use for the .h2.keystore file * The default password to use for the .h2.keystore file
*/ */
public static final String KEYSTORE_PASSWORD = "h2pass"; public static final String KEYSTORE_PASSWORD = "h2pass";
private static final String KEYSTORE = ".h2.keystore"; private static final String KEYSTORE = "~/.h2.keystore";
private static final String KEYSTORE_KEY = "javax.net.ssl.keyStore"; private static final String KEYSTORE_KEY = "javax.net.ssl.keyStore";
private static final String KEYSTORE_PASSWORD_KEY = "javax.net.ssl.keyStorePassword"; private static final String KEYSTORE_PASSWORD_KEY = "javax.net.ssl.keyStorePassword";
private static final String ANONYMOUS_CIPHER_SUITE = "SSL_DH_anon_WITH_RC4_128_MD5"; private static final String ANONYMOUS_CIPHER_SUITE = "SSL_DH_anon_WITH_RC4_128_MD5";
...@@ -190,7 +190,7 @@ public class CipherFactory { ...@@ -190,7 +190,7 @@ public class CipherFactory {
private static void setKeystore() throws IOException { private static void setKeystore() throws IOException {
Properties p = System.getProperties(); Properties p = System.getProperties();
if (p.getProperty(KEYSTORE_KEY) == null) { if (p.getProperty(KEYSTORE_KEY) == null) {
String fileName = IOUtils.getFileInUserHome(KEYSTORE); String fileName = KEYSTORE;
byte[] data = getKeyStoreBytes(getKeyStore(KEYSTORE_PASSWORD), KEYSTORE_PASSWORD); byte[] data = getKeyStoreBytes(getKeyStore(KEYSTORE_PASSWORD), KEYSTORE_PASSWORD);
boolean needWrite = true; boolean needWrite = true;
if (IOUtils.exists(fileName) && IOUtils.length(fileName) == data.length) { if (IOUtils.exists(fileName) && IOUtils.length(fileName) == data.length) {
......
...@@ -130,8 +130,8 @@ public class WebServer implements Service { ...@@ -130,8 +130,8 @@ public class WebServer implements Service {
private boolean ifExists; private boolean ifExists;
private boolean trace; private boolean trace;
private TranslateThread translateThread; private TranslateThread translateThread;
private boolean allowChunked = true; private boolean allowChunked = true;
private String serverPropertiesDir = Constants.SERVER_PROPERTIES_DIR;
/** /**
* Read the given file from the file system or from the resources. * Read the given file from the file system or from the resources.
...@@ -251,7 +251,12 @@ public class WebServer implements Service { ...@@ -251,7 +251,12 @@ public class WebServer implements Service {
} }
public void init(String... args) { public void init(String... args) {
// TODO web: support using a different properties file // set the serverPropertiesDir, because it's used in loadProperties()
for (int i = 0; args != null && i < args.length; i++) {
if (args[i].equals("-properties")) {
serverPropertiesDir = args[++i];
}
}
Properties prop = loadProperties(); Properties prop = loadProperties();
port = SortedProperties.getIntProperty(prop, "webPort", Constants.DEFAULT_HTTP_PORT); port = SortedProperties.getIntProperty(prop, "webPort", Constants.DEFAULT_HTTP_PORT);
ssl = SortedProperties.getBooleanProperty(prop, "webSSL", false); ssl = SortedProperties.getBooleanProperty(prop, "webSSL", false);
...@@ -271,6 +276,9 @@ public class WebServer implements Service { ...@@ -271,6 +276,9 @@ public class WebServer implements Service {
SysProperties.setBaseDir(baseDir); SysProperties.setBaseDir(baseDir);
} else if ("-ifExists".equals(a)) { } else if ("-ifExists".equals(a)) {
ifExists = true; ifExists = true;
} else if (args[i].equals("-properties")) {
// already set
i++;
} else if ("-trace".equals(a)) { } else if ("-trace".equals(a)) {
trace = true; trace = true;
} }
...@@ -509,15 +517,9 @@ public class WebServer implements Service { ...@@ -509,15 +517,9 @@ public class WebServer implements Service {
connInfoMap.remove(name); connInfoMap.remove(name);
} }
private String getPropertiesFileName() {
// store the properties in the user directory
return IOUtils.getFileInUserHome(Constants.SERVER_PROPERTIES_FILE);
}
private Properties loadProperties() { private Properties loadProperties() {
String fileName = getPropertiesFileName();
try { try {
return SortedProperties.loadProperties(fileName); return SortedProperties.loadProperties(serverPropertiesDir + "/" + Constants.SERVER_PROPERTIES_NAME);
} catch (Exception e) { } catch (Exception e) {
TraceSystem.traceThrowable(e); TraceSystem.traceThrowable(e);
return new Properties(); return new Properties();
...@@ -593,8 +595,7 @@ public class WebServer implements Service { ...@@ -593,8 +595,7 @@ public class WebServer implements Service {
prop.setProperty(String.valueOf(len - i - 1), info.getString()); prop.setProperty(String.valueOf(len - i - 1), info.getString());
} }
} }
String fileName = getPropertiesFileName(); OutputStream out = IOUtils.openFileOutputStream(serverPropertiesDir + "/" + Constants.SERVER_PROPERTIES_NAME, false);
OutputStream out = IOUtils.openFileOutputStream(fileName, false);
prop.store(out, "H2 Server Properties"); prop.store(out, "H2 Server Properties");
out.close(); out.close();
} catch (Exception e) { } catch (Exception e) {
......
...@@ -94,6 +94,8 @@ public class Server extends Tool implements Runnable, ShutdownHandler { ...@@ -94,6 +94,8 @@ public class Server extends Tool implements Runnable, ShutdownHandler {
* <td>Use a daemon thread</td></tr> * <td>Use a daemon thread</td></tr>
* <tr><td>[-pgPort &lt;port&gt;]</td> * <tr><td>[-pgPort &lt;port&gt;]</td>
* <td>The port (default: 5435)</td></tr> * <td>The port (default: 5435)</td></tr>
* <tr><td>[-properties "&lt;dir&gt;"]</td>
* <td>The server properties directory (default: ~)</td></tr>
* <tr><td>[-baseDir &lt;dir&gt;]</td> * <tr><td>[-baseDir &lt;dir&gt;]</td>
* <td>The base directory for H2 databases (all servers)</td></tr> * <td>The base directory for H2 databases (all servers)</td></tr>
* <tr><td>[-ifExists]</td> * <tr><td>[-ifExists]</td>
...@@ -182,6 +184,8 @@ public class Server extends Tool implements Runnable, ShutdownHandler { ...@@ -182,6 +184,8 @@ public class Server extends Tool implements Runnable, ShutdownHandler {
} else { } else {
throwUnsupportedOption(arg); throwUnsupportedOption(arg);
} }
} else if ("-properties".equals(arg)) {
i++;
} else if ("-trace".equals(arg)) { } else if ("-trace".equals(arg)) {
// no parameters // no parameters
} else if ("-ifExists".equals(arg)) { } else if ("-ifExists".equals(arg)) {
......
...@@ -23,7 +23,6 @@ import java.util.ArrayList; ...@@ -23,7 +23,6 @@ import java.util.ArrayList;
import java.util.Properties; import java.util.Properties;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.server.web.ConnectionInfo; import org.h2.server.web.ConnectionInfo;
import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.ScriptReader; import org.h2.util.ScriptReader;
...@@ -50,6 +49,7 @@ public class Shell extends Tool implements Runnable { ...@@ -50,6 +49,7 @@ public class Shell extends Tool implements Runnable {
private char boxVertical = '|'; private char boxVertical = '|';
private ArrayList<String> history = New.arrayList(); private ArrayList<String> history = New.arrayList();
private boolean stopHide; private boolean stopHide;
private String serverPropertiesDir = Constants.SERVER_PROPERTIES_DIR;
/** /**
* Options are case sensitive. Supported options are: * Options are case sensitive. Supported options are:
...@@ -66,6 +66,8 @@ public class Shell extends Tool implements Runnable { ...@@ -66,6 +66,8 @@ public class Shell extends Tool implements Runnable {
* <td>The JDBC driver class to use (not required in most cases)</td></tr> * <td>The JDBC driver class to use (not required in most cases)</td></tr>
* <tr><td>[-sql "&lt;statements&gt;"]</td> * <tr><td>[-sql "&lt;statements&gt;"]</td>
* <td>Execute the SQL statements and exit</td></tr> * <td>Execute the SQL statements and exit</td></tr>
* <tr><td>[-properties "&lt;dir&gt;"]</td>
* <td>Load the server properties from this directory</td></tr>
* </table> * </table>
* If special characters don't work as expected, you may need to use * If special characters don't work as expected, you may need to use
* -Dfile.encoding=UTF-8 (Mac OS X) or CP850 (Windows). * -Dfile.encoding=UTF-8 (Mac OS X) or CP850 (Windows).
...@@ -127,6 +129,8 @@ public class Shell extends Tool implements Runnable { ...@@ -127,6 +129,8 @@ public class Shell extends Tool implements Runnable {
Utils.loadUserClass(driver); Utils.loadUserClass(driver);
} else if (arg.equals("-sql")) { } else if (arg.equals("-sql")) {
sql = args[++i]; sql = args[++i];
} else if (arg.equals("-properties")) {
serverPropertiesDir = args[++i];
} else if (arg.equals("-help") || arg.equals("-?")) { } else if (arg.equals("-help") || arg.equals("-?")) {
showUsage(); showUsage();
return; return;
...@@ -346,12 +350,11 @@ public class Shell extends Tool implements Runnable { ...@@ -346,12 +350,11 @@ public class Shell extends Tool implements Runnable {
} }
private void connect() throws IOException, SQLException { private void connect() throws IOException, SQLException {
String propertiesFileName = IOUtils.getFileInUserHome(Constants.SERVER_PROPERTIES_FILE);
String url = "jdbc:h2:~/test"; String url = "jdbc:h2:~/test";
String user = "sa"; String user = "sa";
String driver = null; String driver = null;
try { try {
Properties prop = SortedProperties.loadProperties(propertiesFileName); Properties prop = SortedProperties.loadProperties(serverPropertiesDir + "/" + Constants.SERVER_PROPERTIES_NAME);
String data = null; String data = null;
boolean found = false; boolean found = false;
for (int i = 0;; i++) { for (int i = 0;; i++) {
......
...@@ -487,21 +487,6 @@ public class IOUtils { ...@@ -487,21 +487,6 @@ public class IOUtils {
} }
} }
/**
* Get the absolute file path of a file in the user home directory.
*
* @param fileName the file name
* @return the absolute path
*/
public static String getFileInUserHome(String fileName) {
String userDir = SysProperties.USER_HOME;
if (userDir == null) {
return fileName;
}
File file = new File(userDir, fileName);
return file.getAbsolutePath();
}
/** /**
* Get the file name (without directory part). * Get the file name (without directory part).
* *
......
...@@ -317,7 +317,7 @@ java org.h2.test.TestAll timer ...@@ -317,7 +317,7 @@ java org.h2.test.TestAll timer
} }
private static void run(String... args) throws Exception { private static void run(String... args) throws Exception {
SelfDestructor.startCountdown(6 * 60); SelfDestructor.startCountdown(2 * 60);
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
TestAll test = new TestAll(); TestAll test = new TestAll();
test.printSystem(); test.printSystem();
......
...@@ -24,8 +24,9 @@ public class TestWeb extends TestBase { ...@@ -24,8 +24,9 @@ public class TestWeb extends TestBase {
} }
public void test() throws Exception { public void test() throws Exception {
Server server = Server.createWebServer("-webPort", "8182"); Server server = Server.createWebServer("-webPort", "8182", "-properties", getBaseDir());
server.start(); server.start();
try {
String url = server.getURL(); String url = server.getURL();
WebClient client = new WebClient(); WebClient client = new WebClient();
String result = client.get(url); String result = client.get(url);
...@@ -63,12 +64,12 @@ public class TestWeb extends TestBase { ...@@ -63,12 +64,12 @@ public class TestWeb extends TestBase {
assertContains(result, "select * from test"); assertContains(result, "select * from test");
result = client.get(url, "autoCompleteList.do?query=se"); result = client.get(url, "autoCompleteList.do?query=se");
// long time = System.currentTimeMillis(); // long time = System.currentTimeMillis();
// for (int i=0; i<1000; i++) { // for (int i=0; i<1000; i++) {
// if(System.currentTimeMillis()-time > 15000) { // if(System.currentTimeMillis()-time > 15000) {
// break; // break;
// } // }
// result = client.get(url, "autoCompleteList.do?query=select * from "); // result = client.get(url, "autoCompleteList.do?query=select * from ");
assertContains(result, "select"); assertContains(result, "select");
assertContains(result, "set"); assertContains(result, "set");
...@@ -115,8 +116,10 @@ public class TestWeb extends TestBase { ...@@ -115,8 +116,10 @@ public class TestWeb extends TestBase {
client.get(url, "admin.do"); client.get(url, "admin.do");
// this would also stop the server // this would also stop the server
// client.get(url, "adminShutdown.do"); // client.get(url, "adminShutdown.do");
server.stop(); server.stop();
} finally {
// server.stop();
}
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论