提交 0789a984 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 ac3c906a
...@@ -17,13 +17,14 @@ h3 { margin-top: 0px; margin-bottom: 10px; } ...@@ -17,13 +17,14 @@ h3 { margin-top: 0px; margin-bottom: 10px; }
<h1>H2 Database Engine</h1> <h1>H2 Database Engine</h1>
<p> <p>
Welcome to H2, the free SQL database. The main feature of H2 are: Welcome to H2, the Java SQL database. The main feature of H2 are:
</p> </p>
<ul> <ul>
<li>Very fast, free for everybody, source code is included <li>Very fast, free for everybody, source code is included
</li><li>Written in Java; can be compiled with GCJ (Linux) </li><li>Embedded, server and cluster modes
</li><li>Embedded, Server and Cluster modes </li><li>JDBC and ODBC API; browser based Console application
</li><li>JDBC and (partial) ODBC API; Web Client application </li><li>Written in Java; can be compiled with GCJ and IKVM.NET
</li><li>Small footprint: around 1 MB
</li></ul> </li></ul>
<table style="border: 0px; width: 395px;"> <table style="border: 0px; width: 395px;">
......
...@@ -60,6 +60,7 @@ Roadmap ...@@ -60,6 +60,7 @@ Roadmap
</li><li>Procedural language / script language (Javascript) </li><li>Procedural language / script language (Javascript)
</li><li>Change LOB mechanism (less files, keep index of lob files, point to files and row, delete unused files earlier, maybe bundle files into a tar file) </li><li>Change LOB mechanism (less files, keep index of lob files, point to files and row, delete unused files earlier, maybe bundle files into a tar file)
</li><li>Clustering: recovery needs to becomes fully automatic. Global write lock feature. </li><li>Clustering: recovery needs to becomes fully automatic. Global write lock feature.
</li><li>Option for Java functions: constant/isDeterministic to allow early evaluation when all parameters are constant
</li><li>Deferred integrity checking (DEFERRABLE INITIALLY DEFERRED) </li><li>Deferred integrity checking (DEFERRABLE INITIALLY DEFERRED)
</li><li>Groovy Stored Procedures (http://groovy.codehaus.org/Groovy+SQL) </li><li>Groovy Stored Procedures (http://groovy.codehaus.org/Groovy+SQL)
</li><li>System table / function: cache usage </li><li>System table / function: cache usage
...@@ -102,7 +103,6 @@ Roadmap ...@@ -102,7 +103,6 @@ Roadmap
</li><li>Include SMPT (mail) server (at least client) (alert on cluster failure, low disk space,...) </li><li>Include SMPT (mail) server (at least client) (alert on cluster failure, low disk space,...)
</li><li>Drop with restrict (currently cascade is the default) </li><li>Drop with restrict (currently cascade is the default)
</li><li>JSON parser and functions </li><li>JSON parser and functions
</li><li>Option for Java functions: constant/isDeterministic to allow early evaluation when all parameters are constant
</li><li>Automatic collection of statistics (auto ANALYZE) </li><li>Automatic collection of statistics (auto ANALYZE)
</li><li>Server: client ping from time to time (to avoid timeout - is timeout a problem?) </li><li>Server: client ping from time to time (to avoid timeout - is timeout a problem?)
</li><li>Copy database: Tool with config GUI and batch mode, extensible (example: compare) </li><li>Copy database: Tool with config GUI and batch mode, extensible (example: compare)
......
...@@ -49,9 +49,10 @@ public interface Service { ...@@ -49,9 +49,10 @@ public interface Service {
/** /**
* Check if the service is running. * Check if the service is running.
* *
* @param traceError if errors should be written
* @return if the server is running * @return if the server is running
*/ */
boolean isRunning(); boolean isRunning(boolean traceError);
/** /**
* Check if remote connections are allowed. * Check if remote connections are allowed.
......
...@@ -224,7 +224,7 @@ public class TcpServer implements Service { ...@@ -224,7 +224,7 @@ public class TcpServer implements Service {
stopManagementDb(); stopManagementDb();
} }
public synchronized boolean isRunning() { public synchronized boolean isRunning(boolean traceError) {
if (serverSocket == null) { if (serverSocket == null) {
return false; return false;
} }
...@@ -233,6 +233,9 @@ public class TcpServer implements Service { ...@@ -233,6 +233,9 @@ public class TcpServer implements Service {
s.close(); s.close();
return true; return true;
} catch (Exception e) { } catch (Exception e) {
if (traceError) {
traceError(e);
}
return false; return false;
} }
} }
......
...@@ -205,7 +205,7 @@ public class FtpServer implements Service { ...@@ -205,7 +205,7 @@ public class FtpServer implements Service {
serverSocket = null; serverSocket = null;
} }
public boolean isRunning() { public boolean isRunning(boolean traceError) {
if (serverSocket == null) { if (serverSocket == null) {
return false; return false;
} }
...@@ -214,6 +214,9 @@ public class FtpServer implements Service { ...@@ -214,6 +214,9 @@ public class FtpServer implements Service {
s.close(); s.close();
return true; return true;
} catch (Exception e) { } catch (Exception e) {
if (traceError) {
traceError(e);
}
return false; return false;
} }
} }
......
...@@ -172,7 +172,7 @@ public class PgServer implements Service { ...@@ -172,7 +172,7 @@ public class PgServer implements Service {
} }
} }
public boolean isRunning() { public boolean isRunning(boolean traceError) {
if (serverSocket == null) { if (serverSocket == null) {
return false; return false;
} }
...@@ -181,6 +181,9 @@ public class PgServer implements Service { ...@@ -181,6 +181,9 @@ public class PgServer implements Service {
s.close(); s.close();
return true; return true;
} catch (Exception e) { } catch (Exception e) {
if (traceError) {
traceError(e);
}
return false; return false;
} }
} }
......
...@@ -276,7 +276,7 @@ public class WebServer implements Service { ...@@ -276,7 +276,7 @@ public class WebServer implements Service {
} }
} }
public boolean isRunning() { public boolean isRunning(boolean traceError) {
if (serverSocket == null) { if (serverSocket == null) {
return false; return false;
} }
...@@ -285,6 +285,9 @@ public class WebServer implements Service { ...@@ -285,6 +285,9 @@ public class WebServer implements Service {
s.close(); s.close();
return true; return true;
} catch (Exception e) { } catch (Exception e) {
if (traceError) {
traceError(e);
}
return false; return false;
} }
} }
......
...@@ -572,15 +572,15 @@ class WebThread extends Thread implements DatabaseEventListener { ...@@ -572,15 +572,15 @@ class WebThread extends Thread implements DatabaseEventListener {
} else { } else {
throw Message.getInternalError(toolName); throw Message.getInternalError(toolName);
} }
ByteArrayOutputStream bout = new ByteArrayOutputStream(); ByteArrayOutputStream outBuff = new ByteArrayOutputStream();
PrintStream out = new PrintStream(bout, false, "UTF-8"); PrintStream out = new PrintStream(outBuff, false, "UTF-8");
tool.setPrintStream(out); tool.setOut(out);
try { try {
tool.run(argList); tool.run(argList);
out.flush(); out.flush();
byte[] data = bout.toByteArray(); String o = new String(outBuff.toByteArray(), "UTF-8");
String result = new String(data, "UTF-8"); String result = PageParser.escapeHtml(o);
session.put("toolResult", PageParser.escapeHtml(result)); session.put("toolResult", result);
} catch (Exception e) { } catch (Exception e) {
session.put("toolResult", getStackTrace(0, e, true)); session.put("toolResult", getStackTrace(0, e, true));
} }
......
...@@ -32,11 +32,10 @@ function quote(x) { ...@@ -32,11 +32,10 @@ function quote(x) {
var q = ''; var q = '';
for (var i=0; i<x.length; i++) { for (var i=0; i<x.length; i++) {
var c = x.charAt(i); var c = x.charAt(i);
if(c == '"') { if(c == '"' || c == '\\') {
q += '\\"'; q += '\\';
} else {
q += c;
} }
q += c;
} }
return q; return q;
} }
......
...@@ -135,7 +135,7 @@ ShutdownHandler { ...@@ -135,7 +135,7 @@ ShutdownHandler {
// because some people don't look at the output, // because some people don't look at the output,
// but are wondering why nothing happens // but are wondering why nothing happens
StartBrowser.openURL(web.getURL()); StartBrowser.openURL(web.getURL());
if (!web.isRunning()) { if (!web.isRunning(true)) {
exitCode = EXIT_ERROR; exitCode = EXIT_ERROR;
} }
return exitCode; return exitCode;
...@@ -158,15 +158,15 @@ ShutdownHandler { ...@@ -158,15 +158,15 @@ ShutdownHandler {
} }
private void stopAll() { private void stopAll() {
if (web != null && web.isRunning()) { if (web != null && web.isRunning(false)) {
web.stop(); web.stop();
web = null; web = null;
} }
if (tcp != null && tcp.isRunning()) { if (tcp != null && tcp.isRunning(false)) {
tcp.stop(); tcp.stop();
tcp = null; tcp = null;
} }
if (pg != null && pg.isRunning()) { if (pg != null && pg.isRunning(false)) {
pg.stop(); pg.stop();
pg = null; pg = null;
} }
......
...@@ -128,10 +128,10 @@ public class CreateCluster extends Tool { ...@@ -128,10 +128,10 @@ public class CreateCluster extends Tool {
String scriptFile = "backup.sql"; String scriptFile = "backup.sql";
Script sc = new Script(); Script sc = new Script();
sc.setPrintStream(out); sc.setOut(out);
sc.process(urlSource, user, password, scriptFile); sc.process(urlSource, user, password, scriptFile);
RunScript runscript = new RunScript(); RunScript runscript = new RunScript();
runscript.setPrintStream(out); runscript.setOut(out);
runscript.process(urlTarget, user, password, scriptFile, null, false); runscript.process(urlTarget, user, password, scriptFile, null, false);
FileUtils.delete(scriptFile); FileUtils.delete(scriptFile);
......
...@@ -161,7 +161,7 @@ public class Recover extends Tool implements DataHandler { ...@@ -161,7 +161,7 @@ public class Recover extends Tool implements DataHandler {
private void traceError(String message, Throwable t) { private void traceError(String message, Throwable t) {
out.println(message + ": " + t.toString()); out.println(message + ": " + t.toString());
if (trace) { if (trace) {
t.printStackTrace(); t.printStackTrace(out);
} }
} }
...@@ -272,7 +272,7 @@ public class Recover extends Tool implements DataHandler { ...@@ -272,7 +272,7 @@ public class Recover extends Tool implements DataHandler {
} }
break; break;
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace(out);
} }
} }
} }
...@@ -688,21 +688,34 @@ public class Recover extends Tool implements DataHandler { ...@@ -688,21 +688,34 @@ public class Recover extends Tool implements DataHandler {
} }
private void dumpData(String fileName) throws SQLException { private void dumpData(String fileName) throws SQLException {
setDatabaseName(fileName.substring(0, fileName.length() - Constants.SUFFIX_DATA_FILE.length()));
try {
textStorage = Database.isTextStorage(fileName, false);
dumpData(fileName, textStorage, fileName, FileStore.HEADER_LENGTH);
} catch (SQLException e) {
traceError("Can not parse file header", e);
for (int i = 0; i < 256; i += 16) {
textStorage = (i % 2) == 0;
int offset = i / 2;
String out = fileName + (textStorage ? ".txt." : ".") + offset + ".data.db";
dumpData(fileName, textStorage, out, offset);
}
}
}
private void dumpData(String fileName, boolean textStorage, String outputName, int offset) {
PrintWriter writer = null; PrintWriter writer = null;
FileStore store = null; FileStore store = null;
try { try {
setDatabaseName(fileName.substring(0, fileName.length() - Constants.SUFFIX_DATA_FILE.length())); writer = getWriter(outputName, ".sql");
writer = getWriter(fileName, ".sql");
writer.println("CREATE ALIAS IF NOT EXISTS READ_CLOB FOR \"" + this.getClass().getName() + ".readClob\";"); writer.println("CREATE ALIAS IF NOT EXISTS READ_CLOB FOR \"" + this.getClass().getName() + ".readClob\";");
writer.println("CREATE ALIAS IF NOT EXISTS READ_BLOB FOR \"" + this.getClass().getName() + ".readBlob\";"); writer.println("CREATE ALIAS IF NOT EXISTS READ_BLOB FOR \"" + this.getClass().getName() + ".readBlob\";");
ObjectArray schema = new ObjectArray(); ObjectArray schema = new ObjectArray();
HashSet objectIdSet = new HashSet(); HashSet objectIdSet = new HashSet();
HashMap tableMap = new HashMap(); HashMap tableMap = new HashMap();
textStorage = Database.isTextStorage(fileName, false);
byte[] magic = Database.getMagic(textStorage); byte[] magic = Database.getMagic(textStorage);
store = FileStore.open(null, fileName, "r", magic); store = FileStore.open(null, fileName, "r", magic);
long length = store.length(); long length = store.length();
int offset = FileStore.HEADER_LENGTH;
int blockSize = DiskFile.BLOCK_SIZE; int blockSize = DiskFile.BLOCK_SIZE;
int blocks = (int) (length / blockSize); int blocks = (int) (length / blockSize);
blockCount = 1; blockCount = 1;
......
...@@ -207,7 +207,7 @@ public class RunScript extends Tool { ...@@ -207,7 +207,7 @@ public class RunScript extends Tool {
} }
} catch (SQLException e) { } catch (SQLException e) {
if (continueOnError) { if (continueOnError) {
e.printStackTrace(); e.printStackTrace(out);
} else { } else {
throw e; throw e;
} }
......
...@@ -356,7 +356,7 @@ public class Server implements Runnable, ShutdownHandler { ...@@ -356,7 +356,7 @@ public class Server implements Runnable, ShutdownHandler {
String getStatus() { String getStatus() {
StringBuffer buff = new StringBuffer(); StringBuffer buff = new StringBuffer();
if (isRunning()) { if (isRunning(false)) {
buff.append(service.getType()); buff.append(service.getType());
buff.append(" server running on "); buff.append(" server running on ");
buff.append(service.getURL()); buff.append(service.getURL());
...@@ -450,10 +450,13 @@ public class Server implements Runnable, ShutdownHandler { ...@@ -450,10 +450,13 @@ public class Server implements Runnable, ShutdownHandler {
t.start(); t.start();
for (int i = 1; i < 64; i += i) { for (int i = 1; i < 64; i += i) {
wait(i); wait(i);
if (isRunning()) { if (isRunning(false)) {
return this; return this;
} }
} }
if (isRunning(true)) {
return this;
}
throw Message.getSQLException(ErrorCode.CONNECTION_BROKEN); throw Message.getSQLException(ErrorCode.CONNECTION_BROKEN);
} }
...@@ -468,19 +471,19 @@ public class Server implements Runnable, ShutdownHandler { ...@@ -468,19 +471,19 @@ public class Server implements Runnable, ShutdownHandler {
} }
private void stopAll() { private void stopAll() {
if (web != null && web.isRunning()) { if (web != null && web.isRunning(false)) {
web.stop(); web.stop();
web = null; web = null;
} }
if (tcp != null && tcp.isRunning()) { if (tcp != null && tcp.isRunning(false)) {
tcp.stop(); tcp.stop();
tcp = null; tcp = null;
} }
if (pg != null && pg.isRunning()) { if (pg != null && pg.isRunning(false)) {
pg.stop(); pg.stop();
pg = null; pg = null;
} }
if (ftp != null && ftp.isRunning()) { if (ftp != null && ftp.isRunning(false)) {
ftp.stop(); ftp.stop();
ftp = null; ftp = null;
} }
...@@ -489,10 +492,11 @@ public class Server implements Runnable, ShutdownHandler { ...@@ -489,10 +492,11 @@ public class Server implements Runnable, ShutdownHandler {
/** /**
* Checks if the server is running. * Checks if the server is running.
* *
* @param traceError if errors should be written
* @return if the server is running * @return if the server is running
*/ */
public boolean isRunning() { public boolean isRunning(boolean traceError) {
return service.isRunning(); return service.isRunning(traceError);
} }
/** /**
......
...@@ -15,13 +15,14 @@ import java.sql.SQLException; ...@@ -15,13 +15,14 @@ import java.sql.SQLException;
public abstract class Tool { public abstract class Tool {
protected PrintStream out = System.out; protected PrintStream out = System.out;
protected PrintStream err = System.err;
/** /**
* Sets the print stream. * Sets the standard output stream.
* *
* @param out the new print stream * @param out the new standard output stream
*/ */
public void setPrintStream(PrintStream out) { public void setOut(PrintStream out) {
this.out = out; this.out = out;
} }
......
...@@ -159,7 +159,8 @@ java org.h2.test.TestAll timer ...@@ -159,7 +159,8 @@ java org.h2.test.TestAll timer
/* /*
database.tgz server problem : only log error the last iteration
output.zip output.zip
function table called twice: document: function table called twice: document:
Yes. The first call is to get the list of columns, and the second call is to get the data. Yes. The first call is to get the list of columns, and the second call is to get the data.
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论