提交 fbb95e9d authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 ce7fd11d
...@@ -466,6 +466,8 @@ The database URL for connecting to a local database is <code>jdbc:h2:[file:][&lt ...@@ -466,6 +466,8 @@ The database URL for connecting to a local database is <code>jdbc:h2:[file:][&lt
The prefix <code>file:</code> is optional. If no or only a relative path is used, then the current working The prefix <code>file:</code> is optional. If no or only a relative path is used, then the current working
directory is used as a starting point. The case sensitivity of the path and database name depend on the directory is used as a starting point. The case sensitivity of the path and database name depend on the
operating system, however it is suggested to use lowercase letters only. operating system, however it is suggested to use lowercase letters only.
The database name must be at least three characters long (a limitation of File.createTempFile).
To point to the user directory, use ~/, as in: jdbc:h2:~/test.
<h3>Memory-Only Databases</h3> <h3>Memory-Only Databases</h3>
<p> <p>
......
...@@ -37,25 +37,27 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -37,25 +37,27 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 1.0 (Current)</h3> <h3>Version 1.0 (Current)</h3>
<h3>Version 1.0 / TODO (Build TODO)</h3><ul> <h3>Version 1.0 / TODO (Build TODO)</h3><ul>
<li>PooledConnection.getConnection took a long time if only one connection was open at any time. Fixed. <li>The default trace level for JdbcDataSourceFactory was DEBUG, so when using data sources a trace file
was always created. Now the default trace level is ERROR, and the file is only created if necessary.
</li><li>PooledConnection.getConnection took a long time if only one connection was open at any time. Fixed.
</li><li>Referential integrity violation: Two different SQL states are now used for missing parent / existing child. </li><li>Referential integrity violation: Two different SQL states are now used for missing parent / existing child.
</li><li>DatabaseEventListener.exceptionThrown has a new parameter: SQL </li><li>DatabaseEventListener.exceptionThrown has a new parameter: SQL
</li><li>For compatibility reasons, the catalog name can now be used in queries: SELECT * FROM TESTDB.PUBLIC.TEST </li><li>For compatibility reasons, the catalog name can now be used in queries: SELECT * FROM TESTDB.PUBLIC.TEST
</li><li>If SHUTDOWN IMMEDIATELY was called, then the connection was not closed and the database </li><li>If SHUTDOWN IMMEDIATELY was called, then the connection was not closed and the database
opened from somebody else at the same time, in some cases this could result in errors with LOB files. Fixed. opened from somebody else at the same time, in some cases this could result in errors with LOB files. Fixed.
</li><li>The new view implementation is now enabled by default. </li><li>The new view implementation is now enabled by default.
To use the old implementation, set the system property 'h2.indexOld' to true To use the old implementation, set the system property 'h2.indexOld' to true
(java -Dh2.indexOld=true ..., or in source code Constants.INDEX_OLD = true). (java -Dh2.indexOld=true ..., or in source code Constants.INDEX_OLD = true).
If no problems are found, the old implementation will be removed in the next release. If no problems are found, the old implementation will be removed in the next release.
The old implementation does not work with multi-level nested temporary views The old implementation does not work with multi-level nested temporary views
(select * from (select * from (select * from test))). (select * from (select * from (select * from test))).
</li><li>The new view implementation did not work with &lt; and &lt;= comparison, </li><li>The new view implementation did not work with &lt; and &lt;= comparison,
and did not allow conditions on aggregates or grouped columns (HAVING). Fixed.. Fixed. and did not allow conditions on aggregates or grouped columns (HAVING). Fixed.. Fixed.
</li><li>Both view implementations did not work with multiple levels of nested temporary views (FROM (SELECT...)). Fixed. </li><li>Both view implementations did not work with multiple levels of nested temporary views (FROM (SELECT...)). Fixed.
</li><li>The H2 Console can now be run as a standalone web application, </li><li>The H2 Console can now be run as a standalone web application,
or it can be embedded as a servlet into any existing web application. To build the or it can be embedded as a servlet into any existing web application. To build the
'H2 Console' web application, execute 'ant warConsole'. 'H2 Console' web application, execute 'ant warConsole'.
See src/tools/org/h2/server/web and src/tools/WEB-INF for details. See src/tools/org/h2/server/web and src/tools/WEB-INF for details.
</li><li>Deleting database files didn't work for Windows if the database was on the root directory of a drive. </li><li>Deleting database files didn't work for Windows if the database was on the root directory of a drive.
</li><li>The Polish translation is available. Thanks a lot to Tomek! </li><li>The Polish translation is available. Thanks a lot to Tomek!
</li><li>Windows service: the CLASSPATH was not included when starting the service. Fixed. </li><li>Windows service: the CLASSPATH was not included when starting the service. Fixed.
...@@ -833,7 +835,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -833,7 +835,7 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</li><li>Row level locking </li><li>Row level locking
</li><li>Read-only databases inside a jar (splitting large files to speed up random access) </li><li>Read-only databases inside a jar (splitting large files to speed up random access)
</li><li>System table: open sessions and locks of a database </li><li>System table: open sessions and locks of a database
</li><li>Function in management db: open connections and databases of a (TCP) server </li><li>Function in management db: list open connections and databases of a (TCP) server
</li><li>Fix right outer joins </li><li>Fix right outer joins
</li><li>Full outer joins </li><li>Full outer joins
</li><li>Long running queries / errors / trace system table </li><li>Long running queries / errors / trace system table
......
...@@ -410,9 +410,9 @@ public class Database implements DataHandler { ...@@ -410,9 +410,9 @@ public class Database implements DataHandler {
dummy = DataPage.create(this, 0); dummy = DataPage.create(this, 0);
if(persistent) { if(persistent) {
if(readOnly || FileUtils.isInMemory(databaseName)) { if(readOnly || FileUtils.isInMemory(databaseName)) {
traceSystem = new TraceSystem(null); traceSystem = new TraceSystem(null, false);
} else { } else {
traceSystem = new TraceSystem(databaseName+Constants.SUFFIX_TRACE_FILE); traceSystem = new TraceSystem(databaseName+Constants.SUFFIX_TRACE_FILE, true);
} }
if(cipher != null) { if(cipher != null) {
traceSystem.setManualEnabling(false); traceSystem.setManualEnabling(false);
...@@ -447,7 +447,7 @@ public class Database implements DataHandler { ...@@ -447,7 +447,7 @@ public class Database implements DataHandler {
reserveLobFileObjectIds(); reserveLobFileObjectIds();
writer = WriterThread.create(this, writeDelay); writer = WriterThread.create(this, writeDelay);
} else { } else {
traceSystem = new TraceSystem(null); traceSystem = new TraceSystem(null, false);
log = new LogSystem(null, null, false, null); log = new LogSystem(null, null, false, null);
} }
systemUser = new User(this, 0, Constants.DBA_NAME, true); systemUser = new User(this, 0, Constants.DBA_NAME, true);
......
...@@ -317,7 +317,7 @@ public class Session implements SessionInterface { ...@@ -317,7 +317,7 @@ public class Session implements SessionInterface {
traceModuleName = Trace.JDBC + "[" + id + "]"; traceModuleName = Trace.JDBC + "[" + id + "]";
} }
if(database == null) { if(database == null) {
return new TraceSystem(null).getTrace(traceModuleName); return new TraceSystem(null, false).getTrace(traceModuleName);
} }
return database.getTrace(traceModuleName); return database.getTrace(traceModuleName);
} }
......
...@@ -172,7 +172,7 @@ public class SessionRemote implements SessionInterface, DataHandler { ...@@ -172,7 +172,7 @@ public class SessionRemote implements SessionInterface, DataHandler {
} }
databaseName = name.substring(idx + 1); databaseName = name.substring(idx + 1);
String server = name.substring(0, idx); String server = name.substring(0, idx);
traceSystem = new TraceSystem(null); traceSystem = new TraceSystem(null, false);
try { try {
String traceLevelFile = ci.getProperty(SetTypes.TRACE_LEVEL_FILE, null); String traceLevelFile = ci.getProperty(SetTypes.TRACE_LEVEL_FILE, null);
if(traceLevelFile != null) { if(traceLevelFile != null) {
......
...@@ -22,7 +22,7 @@ public class JdbcDataSourceFactory implements ObjectFactory { ...@@ -22,7 +22,7 @@ public class JdbcDataSourceFactory implements ObjectFactory {
static { static {
org.h2.Driver.load(); org.h2.Driver.load();
traceSystem = new TraceSystem(Constants.CLIENT_TRACE_DIRECTORY + "h2datasource" + Constants.SUFFIX_TRACE_FILE); traceSystem = new TraceSystem(Constants.CLIENT_TRACE_DIRECTORY + "h2datasource" + Constants.SUFFIX_TRACE_FILE, false);
traceSystem.setLevelFile(Constants.DATASOURCE_TRACE_LEVEL); traceSystem.setLevelFile(Constants.DATASOURCE_TRACE_LEVEL);
} }
......
...@@ -46,6 +46,7 @@ public class TraceSystem { ...@@ -46,6 +46,7 @@ public class TraceSystem {
private int checkSize; private int checkSize;
private boolean closed; private boolean closed;
private boolean manualEnabling = true; private boolean manualEnabling = true;
private boolean writingErrorLogged;
public static void traceThrowable(Throwable e) { public static void traceThrowable(Throwable e) {
PrintWriter writer = DriverManager.getLogWriter(); PrintWriter writer = DriverManager.getLogWriter();
...@@ -58,11 +59,11 @@ public class TraceSystem { ...@@ -58,11 +59,11 @@ public class TraceSystem {
this.manualEnabling = value; this.manualEnabling = value;
} }
public TraceSystem(String fileName) { public TraceSystem(String fileName, boolean init) {
this.fileName = fileName; this.fileName = fileName;
traces = new SmallLRUCache(100); traces = new SmallLRUCache(100);
dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss "); dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss ");
if(fileName != null) { if(fileName != null && init) {
try { try {
openWriter(); openWriter();
} catch(Exception e) { } catch(Exception e) {
...@@ -185,6 +186,10 @@ public class TraceSystem { ...@@ -185,6 +186,10 @@ public class TraceSystem {
} }
private void logWritingError(Exception e) { private void logWritingError(Exception e) {
if(writingErrorLogged) {
return;
}
writingErrorLogged = true;
// TODO translate trace messages // TODO translate trace messages
SQLException se = Message.getSQLException(Message.LOG_FILE_ERROR_1, new String[] { fileName }, e); SQLException se = Message.getSQLException(Message.LOG_FILE_ERROR_1, new String[] { fileName }, e);
// print this error only once // print this error only once
...@@ -193,7 +198,7 @@ public class TraceSystem { ...@@ -193,7 +198,7 @@ public class TraceSystem {
se.printStackTrace(); se.printStackTrace();
} }
private boolean openWriter() throws IOException { private boolean openWriter() {
if(printWriter == null) { if(printWriter == null) {
try { try {
FileUtils.createDirs(fileName); FileUtils.createDirs(fileName);
...@@ -203,7 +208,8 @@ public class TraceSystem { ...@@ -203,7 +208,8 @@ public class TraceSystem {
} }
fileWriter = FileUtils.openFileWriter(fileName, true); fileWriter = FileUtils.openFileWriter(fileName, true);
printWriter = new PrintWriter(fileWriter, true); printWriter = new PrintWriter(fileWriter, true);
} catch(SQLException e) { } catch(Exception e) {
logWritingError(e);
return false; return false;
} }
} }
......
...@@ -12,6 +12,7 @@ import java.sql.SQLException; ...@@ -12,6 +12,7 @@ import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import org.h2.message.TraceSystem;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.NetUtils; import org.h2.util.NetUtils;
...@@ -31,6 +32,7 @@ public class OdbcServer implements Service { ...@@ -31,6 +32,7 @@ public class OdbcServer implements Service {
private String url; private String url;
private boolean allowOthers; private boolean allowOthers;
private boolean ifExists; private boolean ifExists;
private Thread listenerThread;
boolean getLog() { boolean getLog() {
return log; return log;
...@@ -88,7 +90,8 @@ public class OdbcServer implements Service { ...@@ -88,7 +90,8 @@ public class OdbcServer implements Service {
} }
public void listen() { public void listen() {
String threadName = Thread.currentThread().getName(); listenerThread = Thread.currentThread();
String threadName = listenerThread.getName();
try { try {
while (!stop) { while (!stop) {
Socket s = serverSocket.accept(); Socket s = serverSocket.accept();
...@@ -124,6 +127,13 @@ public class OdbcServer implements Service { ...@@ -124,6 +127,13 @@ public class OdbcServer implements Service {
} }
serverSocket = null; serverSocket = null;
} }
if(listenerThread != null) {
try {
listenerThread.join(1000);
} catch (InterruptedException e) {
TraceSystem.traceThrowable(e);
}
}
} }
// TODO server: using a boolean 'now' argument? a timeout? // TODO server: using a boolean 'now' argument? a timeout?
ArrayList list = new ArrayList(running); ArrayList list = new ArrayList(running);
......
...@@ -44,6 +44,7 @@ public class TcpServer implements Service { ...@@ -44,6 +44,7 @@ public class TcpServer implements Service {
private Connection managementDb; private Connection managementDb;
private String managementPassword = ""; private String managementPassword = "";
private static HashMap servers = new HashMap(); private static HashMap servers = new HashMap();
private Thread listenerThread;
public static String getManagementDbName(int port) { public static String getManagementDbName(int port) {
return "mem:" + Constants.MANAGEMENT_DB_PREFIX + port; return "mem:" + Constants.MANAGEMENT_DB_PREFIX + port;
...@@ -118,7 +119,8 @@ public class TcpServer implements Service { ...@@ -118,7 +119,8 @@ public class TcpServer implements Service {
} }
public void listen() { public void listen() {
String threadName = Thread.currentThread().getName(); listenerThread = Thread.currentThread();
String threadName = listenerThread.getName();
try { try {
while (!stop) { while (!stop) {
Socket s = serverSocket.accept(); Socket s = serverSocket.accept();
...@@ -163,6 +165,13 @@ public class TcpServer implements Service { ...@@ -163,6 +165,13 @@ public class TcpServer implements Service {
} }
serverSocket = null; serverSocket = null;
} }
if(listenerThread != null) {
try {
listenerThread.join(1000);
} catch (InterruptedException e) {
TraceSystem.traceThrowable(e);
}
}
} }
// TODO server: using a boolean 'now' argument? a timeout? // TODO server: using a boolean 'now' argument? a timeout?
ArrayList list = new ArrayList(running); ArrayList list = new ArrayList(running);
......
...@@ -88,6 +88,7 @@ public class WebServer implements Service { ...@@ -88,6 +88,7 @@ public class WebServer implements Service {
private ServerSocket serverSocket; private ServerSocket serverSocket;
private String url; private String url;
private boolean allowShutdown; private boolean allowShutdown;
private Thread listenerThread;
byte[] getFile(String file) throws IOException { byte[] getFile(String file) throws IOException {
trace("getFile <"+file+">"); trace("getFile <"+file+">");
...@@ -202,6 +203,7 @@ public class WebServer implements Service { ...@@ -202,6 +203,7 @@ public class WebServer implements Service {
} }
public void listen() { public void listen() {
this.listenerThread = Thread.currentThread();
try { try {
while (serverSocket != null) { while (serverSocket != null) {
Socket s = serverSocket.accept(); Socket s = serverSocket.accept();
...@@ -233,6 +235,13 @@ public class WebServer implements Service { ...@@ -233,6 +235,13 @@ public class WebServer implements Service {
// TODO log exception // TODO log exception
} }
serverSocket = null; serverSocket = null;
if(listenerThread != null) {
try {
listenerThread.join(1000);
} catch (InterruptedException e) {
TraceSystem.traceThrowable(e);
}
}
} }
void trace(String s) { void trace(String s) {
......
...@@ -92,24 +92,9 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2 ...@@ -92,24 +92,9 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
TestAll test = new TestAll(); TestAll test = new TestAll();
test.printSystem(); test.printSystem();
/* /*
The database name must be at least 3 characters
jdbc:h2:te
traceSystem.setLevelFile(TraceSystem.ERROR);
because of temp file limitations, database names with less than 3 characters are not supported
add test case:
prepare: select * from (select * from (select * from dual) a) b;
select * from dual;
execute prepared
add test case:
try to create a view without access rights
try to create a view with a subquery without access right
make sure INDEX_LOOKUP_NEW = is true by default. make sure INDEX_LOOKUP_NEW = is true by default.
Test Console (batch, javaw, different platforms) Test Console (batch, javaw, different platforms)
test with openoffice (metadata changes) test with openoffice (metadata changes)
...@@ -177,18 +162,16 @@ Please note that ...@@ -177,18 +162,16 @@ Please note that
support translated exceptions (translated, then english at the end, for Hibernate compatibility) support translated exceptions (translated, then english at the end, for Hibernate compatibility)
keep db open as long as there are PooledConnections
make static member variables final (this helps find forgotten initializers) make static member variables final (this helps find forgotten initializers)
Merge more from diff.zip (Pavel Ganelin) Merge more from diff.zip (Pavel Ganelin)
keep db open (independent of DB_CLOSE_DELAY) while a PooledConnections exists.
*/ */
/* /*
complete recursive views:
drop all objects; drop all objects;
create table parent(id int primary key, parent int); create table parent(id int primary key, parent int);
insert into parent values(1, null), (2, 1), (3, 1); insert into parent values(1, null), (2, 1), (3, 1);
...@@ -215,13 +198,6 @@ drop table parent; ...@@ -215,13 +198,6 @@ drop table parent;
*/ */
/* /*
create local temporary table abc(id varchar) on commit drop;
insert into abc select * from dual;
create local temporary table abc(id varchar) on commit drop;
insert into abc select * from dual where 1=0;
create local temporary table abc(id varchar) on commit drop;
insert into abc select * from dual;
drop table abc;
DROP TABLE TEST; DROP TABLE TEST;
CREATE TABLE TEST(ID INT); CREATE TABLE TEST(ID INT);
......
...@@ -222,7 +222,7 @@ public abstract class TestBase { ...@@ -222,7 +222,7 @@ public abstract class TestBase {
System.out.println("ERROR: " + s + " " + e.toString() + " ------------------------------"); System.out.println("ERROR: " + s + " " + e.toString() + " ------------------------------");
e.printStackTrace(); e.printStackTrace();
try { try {
TraceSystem ts = new TraceSystem(null); TraceSystem ts = new TraceSystem(null, false);
FileLock lock = new FileLock(ts, 1000); FileLock lock = new FileLock(ts, 1000);
lock.lock("error.lock", false); lock.lock("error.lock", false);
FileWriter fw = new FileWriter("ERROR.txt", true); FileWriter fw = new FileWriter("ERROR.txt", true);
......
...@@ -71,7 +71,7 @@ public class TestFileLock extends TestBase implements Runnable { ...@@ -71,7 +71,7 @@ public class TestFileLock extends TestBase implements Runnable {
public void run() { public void run() {
while (!stop) { while (!stop) {
FileLock lock = new FileLock(new TraceSystem(null), 100); FileLock lock = new FileLock(new TraceSystem(null, false), 100);
try { try {
lock.lock(FILE, allowSockets); lock.lock(FILE, allowSockets);
base.trace(lock + " locked"); base.trace(lock + " locked");
......
...@@ -461,6 +461,7 @@ headless ...@@ -461,6 +461,7 @@ headless
polish javaee resp xsi instances tomek realm xsd appended auth polski polish javaee resp xsi instances tomek realm xsd appended auth polski
signsoft intellibo jdo intelli middleware ute war sends snippet signsoft intellibo jdo intelli middleware ute war sends snippet
gallery ord javaw weblica ltarget gallery ord javaw weblica ltarget
initializers crashes openoffice member forgotten
### check those again: ### check those again:
populate slowly xacon inser maxbqualsize counter regards attaching official xatest populate slowly xacon inser maxbqualsize counter regards attaching official xatest
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论