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

The database URL property DATABASE_EVENT_LISTENER_OBJECT is no longer supported.

上级 ddf09f63
...@@ -18,7 +18,11 @@ Change Log ...@@ -18,7 +18,11 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>H2 Console: asynchronous login (using a DatabaseEventListener) is no longer supported. <ul><li>Converting a UUID to bytes was incorrect. Because of that, updatable result sets on
tables with UUID primary key did not work.
</li><li>The database URL property DATABASE_EVENT_LISTENER_OBJECT is no longer supported
(there are problems passing objects when the PostgreSQL driver is installed as well).
</li><li>H2 Console: asynchronous login (using a DatabaseEventListener) is no longer supported.
</li><li>A workaround for a Windows socket problem has been implemented. Thanks a lot to Sergi Vladykin. </li><li>A workaround for a Windows socket problem has been implemented. Thanks a lot to Sergi Vladykin.
</li><li>The Recover tool did not convert correctly convert CLOB data with non-ASCII characters. </li><li>The Recover tool did not convert correctly convert CLOB data with non-ASCII characters.
</li><li>Tools: the method run(String... args) has been renamed to runTool(String... args) </li><li>Tools: the method run(String... args) has been renamed to runTool(String... args)
......
...@@ -479,6 +479,7 @@ See also <a href="build.html#providing_patches">Providing Patches</a>. ...@@ -479,6 +479,7 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>Simplify running scripts and recovery: CREATE FORCE USER (overwrites an existing user). </li><li>Simplify running scripts and recovery: CREATE FORCE USER (overwrites an existing user).
</li><li>Support CREATE DATABASE LINK (a custom JDBC driver is already supported). </li><li>Support CREATE DATABASE LINK (a custom JDBC driver is already supported).
</li><li>Isse 163: Allow to create foreign keys on metadata types. </li><li>Isse 163: Allow to create foreign keys on metadata types.
</li><li>Logback: write a native DBAppender.
</li></ul> </li></ul>
<h2>Not Planned</h2> <h2>Not Planned</h2>
......
...@@ -4181,10 +4181,6 @@ public class Parser { ...@@ -4181,10 +4181,6 @@ public class Parser {
readIfEqualOrTo(); readIfEqualOrTo();
read(); read();
return new NoOperation(session); return new NoOperation(session);
} else if (readIf("DATABASE_EVENT_LISTENER_OBJECT")) {
readIfEqualOrTo();
read();
return new NoOperation(session);
} else if (readIf("OPEN_NEW")) { } else if (readIf("OPEN_NEW")) {
readIfEqualOrTo(); readIfEqualOrTo();
read(); read();
......
...@@ -11,7 +11,6 @@ import java.util.ArrayList; ...@@ -11,7 +11,6 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Properties; import java.util.Properties;
import org.h2.api.DatabaseEventListener;
import org.h2.command.dml.SetTypes; import org.h2.command.dml.SetTypes;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
...@@ -79,7 +78,7 @@ public class ConnectionInfo implements Cloneable { ...@@ -79,7 +78,7 @@ public class ConnectionInfo implements Cloneable {
set.addAll(list); set.addAll(list);
String[] connectionTime = new String[] { "ACCESS_MODE_DATA", "AUTOCOMMIT", "CIPHER", String[] connectionTime = new String[] { "ACCESS_MODE_DATA", "AUTOCOMMIT", "CIPHER",
"CREATE", "CACHE_TYPE", "DB_CLOSE_ON_EXIT", "FILE_LOCK", "IGNORE_UNKNOWN_SETTINGS", "IFEXISTS", "CREATE", "CACHE_TYPE", "DB_CLOSE_ON_EXIT", "FILE_LOCK", "IGNORE_UNKNOWN_SETTINGS", "IFEXISTS",
"PASSWORD", "RECOVER", "USER", "DATABASE_EVENT_LISTENER_OBJECT", "AUTO_SERVER", "PASSWORD", "RECOVER", "USER", "AUTO_SERVER",
"AUTO_RECONNECT", "OPEN_NEW" }; "AUTO_RECONNECT", "OPEN_NEW" };
for (String key : connectionTime) { for (String key : connectionTime) {
if (SysProperties.CHECK && set.contains(key)) { if (SysProperties.CHECK && set.contains(key)) {
...@@ -206,31 +205,6 @@ public class ConnectionInfo implements Cloneable { ...@@ -206,31 +205,6 @@ public class ConnectionInfo implements Cloneable {
} }
} }
/**
* Removes the database event listener object.
*/
void removeDatabaseEventListenerObject() {
prop.remove("DATABASE_EVENT_LISTENER_OBJECT");
}
/**
* Return the database event listener object set as a Java object. If the
* event listener is not set or set as a string (the class name), then this
* method returns null.
*
* @return the database event listener object or null
*/
DatabaseEventListener getDatabaseEventListenerObject() throws SQLException {
Object p = prop.get("DATABASE_EVENT_LISTENER_OBJECT");
if (p == null) {
return null;
}
if (p instanceof DatabaseEventListener) {
return (DatabaseEventListener) p;
}
throw Message.getSQLException(ErrorCode.DATA_CONVERSION_ERROR_1, p.getClass().getName());
}
private char[] removePassword() { private char[] removePassword() {
Object p = prop.remove("PASSWORD"); Object p = prop.remove("PASSWORD");
if (p == null) { if (p == null) {
......
...@@ -182,15 +182,11 @@ public class Database implements DataHandler { ...@@ -182,15 +182,11 @@ public class Database implements DataHandler {
} }
this.fileLockMethod = FileLock.getFileLockMethod(lockMethodName); this.fileLockMethod = FileLock.getFileLockMethod(lockMethodName);
this.databaseURL = ci.getURL(); this.databaseURL = ci.getURL();
this.eventListener = ci.getDatabaseEventListenerObject();
ci.removeDatabaseEventListenerObject();
if (eventListener == null) {
String listener = ci.removeProperty("DATABASE_EVENT_LISTENER", null); String listener = ci.removeProperty("DATABASE_EVENT_LISTENER", null);
if (listener != null) { if (listener != null) {
listener = StringUtils.trim(listener, true, true, "'"); listener = StringUtils.trim(listener, true, true, "'");
setEventListenerClass(listener); setEventListenerClass(listener);
} }
}
this.multiVersion = ci.getProperty("MVCC", false); this.multiVersion = ci.getProperty("MVCC", false);
boolean closeAtVmShutdown = ci.getProperty("DB_CLOSE_ON_EXIT", true); boolean closeAtVmShutdown = ci.getProperty("DB_CLOSE_ON_EXIT", true);
int traceLevelFile = ci.getIntProperty(SetTypes.TRACE_LEVEL_FILE, TraceSystem.DEFAULT_TRACE_LEVEL_FILE); int traceLevelFile = ci.getIntProperty(SetTypes.TRACE_LEVEL_FILE, TraceSystem.DEFAULT_TRACE_LEVEL_FILE);
......
...@@ -300,8 +300,6 @@ public class SessionRemote extends SessionWithState implements SessionFactory, D ...@@ -300,8 +300,6 @@ public class SessionRemote extends SessionWithState implements SessionFactory, D
throw Message.getUnsupportedException("autoReconnect && serverList != null"); throw Message.getUnsupportedException("autoReconnect && serverList != null");
} }
if (autoReconnect) { if (autoReconnect) {
eventListener = ci.getDatabaseEventListenerObject();
if (eventListener == null) {
String className = ci.getProperty("DATABASE_EVENT_LISTENER"); String className = ci.getProperty("DATABASE_EVENT_LISTENER");
if (className != null) { if (className != null) {
className = StringUtils.trim(className, true, true, "'"); className = StringUtils.trim(className, true, true, "'");
...@@ -314,7 +312,6 @@ public class SessionRemote extends SessionWithState implements SessionFactory, D ...@@ -314,7 +312,6 @@ public class SessionRemote extends SessionWithState implements SessionFactory, D
} }
} }
} }
}
cipher = ci.getProperty("CIPHER"); cipher = ci.getProperty("CIPHER");
if (cipher != null) { if (cipher != null) {
fileEncryptionKey = MathUtils.secureRandomBytes(32); fileEncryptionKey = MathUtils.secureRandomBytes(32);
......
...@@ -20,7 +20,7 @@ import org.h2.test.TestBase; ...@@ -20,7 +20,7 @@ import org.h2.test.TestBase;
*/ */
public class TestDatabaseEventListener extends TestBase implements DatabaseEventListener { public class TestDatabaseEventListener extends TestBase implements DatabaseEventListener {
private boolean calledOpened, calledClosingDatabase, calledScan, calledCreateIndex; private static boolean calledOpened, calledClosingDatabase, calledScan, calledCreateIndex;
/** /**
* Run just this test. * Run just this test.
...@@ -32,6 +32,7 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent ...@@ -32,6 +32,7 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
} }
public void test() throws SQLException { public void test() throws SQLException {
testInit();
testIndexRebuiltOnce(); testIndexRebuiltOnce();
testIndexNotRebuilt(); testIndexNotRebuilt();
testCalled(); testCalled();
...@@ -40,6 +41,59 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent ...@@ -40,6 +41,59 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
deleteDb("databaseEventListener"); deleteDb("databaseEventListener");
} }
/**
* Initialize the database after opening.
*/
public static class Init implements DatabaseEventListener {
private String databaseUrl;
public void init(String url) {
databaseUrl = url;
}
public void opened() {
try {
Connection conn = DriverManager.getConnection(databaseUrl, "sa", "sa");
Statement stat = conn.createStatement();
stat.execute("create table if not exists test(id int)");
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public void closingDatabase() {
// nothing to do
}
public void diskSpaceIsLow(long stillAvailable) {
// nothing to do
}
public void exceptionThrown(SQLException e, String sql) {
// nothing to do
}
public void setProgress(int state, String name, int x, int max) {
// nothing to do
}
}
private void testInit() throws SQLException {
if (config.networked || config.cipher != null || config.memory) {
return;
}
deleteDb("databaseEventListener");
String url = getURL("databaseEventListener", true);
url += ";DATABASE_EVENT_LISTENER='"+ Init.class.getName() + "'";
Connection conn = DriverManager.getConnection(url, "sa", "sa");
Statement stat = conn.createStatement();
stat.execute("select * from test");
conn.close();
}
private void testIndexRebuiltOnce() throws SQLException { private void testIndexRebuiltOnce() throws SQLException {
if (config.memory) { if (config.memory) {
return; return;
...@@ -74,11 +128,11 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent ...@@ -74,11 +128,11 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
// now the index should be re-built // now the index should be re-built
conn = DriverManager.getConnection(url, p); conn = DriverManager.getConnection(url, p);
conn.close(); conn.close();
TestDatabaseEventListener l = new TestDatabaseEventListener(); calledCreateIndex = false;
p.put("DATABASE_EVENT_LISTENER_OBJECT", l); p.put("DATABASE_EVENT_LISTENER", getClass().getName());
conn = org.h2.Driver.load().connect(url, p); conn = org.h2.Driver.load().connect(url, p);
conn.close(); conn.close();
assertTrue(!l.calledCreateIndex); assertTrue(!calledCreateIndex);
} }
private void testIndexNotRebuilt() throws SQLException { private void testIndexNotRebuilt() throws SQLException {
...@@ -106,11 +160,11 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent ...@@ -106,11 +160,11 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
stat.execute("truncate table test"); stat.execute("truncate table test");
stat.execute("insert into test select 1"); stat.execute("insert into test select 1");
conn.close(); conn.close();
TestDatabaseEventListener l = new TestDatabaseEventListener(); calledCreateIndex = false;
p.put("DATABASE_EVENT_LISTENER_OBJECT", l); p.put("DATABASE_EVENT_LISTENER", getClass().getName());
conn = org.h2.Driver.load().connect(url, p); conn = org.h2.Driver.load().connect(url, p);
conn.close(); conn.close();
assertTrue(!l.calledCreateIndex); assertTrue(!calledCreateIndex);
} }
private void testCloseLog0(boolean shutdown) throws SQLException { private void testCloseLog0(boolean shutdown) throws SQLException {
...@@ -132,12 +186,13 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent ...@@ -132,12 +186,13 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
} }
conn.close(); conn.close();
TestDatabaseEventListener l = new TestDatabaseEventListener(); calledOpened = false;
p.put("DATABASE_EVENT_LISTENER_OBJECT", l); calledScan = false;
p.put("DATABASE_EVENT_LISTENER", getClass().getName());
conn = org.h2.Driver.load().connect(url, p); conn = org.h2.Driver.load().connect(url, p);
conn.close(); conn.close();
if (l.calledOpened) { if (calledOpened) {
assertTrue(!l.calledScan); assertTrue(!calledScan);
} }
} }
...@@ -145,14 +200,15 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent ...@@ -145,14 +200,15 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
Properties p = new Properties(); Properties p = new Properties();
p.setProperty("user", "sa"); p.setProperty("user", "sa");
p.setProperty("password", "sa"); p.setProperty("password", "sa");
TestDatabaseEventListener l = new TestDatabaseEventListener(); calledOpened = false;
p.put("DATABASE_EVENT_LISTENER_OBJECT", l); calledClosingDatabase = false;
p.put("DATABASE_EVENT_LISTENER", getClass().getName());
org.h2.Driver.load(); org.h2.Driver.load();
String url = "jdbc:h2:mem:databaseEventListener"; String url = "jdbc:h2:mem:databaseEventListener";
Connection conn = org.h2.Driver.load().connect(url, p); Connection conn = org.h2.Driver.load().connect(url, p);
conn.close(); conn.close();
assertTrue(l.calledOpened); assertTrue(calledOpened);
assertTrue(l.calledClosingDatabase); assertTrue(calledClosingDatabase);
} }
public void closingDatabase() { public void closingDatabase() {
......
...@@ -7,14 +7,11 @@ ...@@ -7,14 +7,11 @@
package org.h2.test.unit; package org.h2.test.unit;
import java.sql.Connection; import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Properties;
import org.h2.api.DatabaseEventListener; import org.h2.api.DatabaseEventListener;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.tools.Server; import org.h2.tools.Server;
...@@ -29,7 +26,6 @@ public class TestAutoReconnect extends TestBase implements DatabaseEventListener ...@@ -29,7 +26,6 @@ public class TestAutoReconnect extends TestBase implements DatabaseEventListener
private Server server; private Server server;
private Connection connServer; private Connection connServer;
private Connection conn; private Connection conn;
private String state;
/** /**
* Run just this test. * Run just this test.
...@@ -79,32 +75,7 @@ public class TestAutoReconnect extends TestBase implements DatabaseEventListener ...@@ -79,32 +75,7 @@ public class TestAutoReconnect extends TestBase implements DatabaseEventListener
conn = DriverManager.getConnection(url + ";DATABASE_EVENT_LISTENER='" + getClass().getName() + "'"); conn = DriverManager.getConnection(url + ";DATABASE_EVENT_LISTENER='" + getClass().getName() + "'");
conn.close(); conn.close();
// test the database event listener object Statement stat;
Properties prop = new Properties();
state = null;
Driver postgreDriver = null;
try {
postgreDriver = DriverManager.getDriver("jdbc:postgresql:test");
if (postgreDriver != null) {
DriverManager.deregisterDriver(postgreDriver);
}
} catch (Exception e) {
// ignore
}
prop.put("DATABASE_EVENT_LISTENER_OBJECT", this);
conn = DriverManager.getConnection(url, prop);
assertEquals(null, state);
Statement stat = conn.createStatement();
stat.execute("DROP TABLE IF EXISTS TEST");
restart();
// the table is created in the database event listener
stat.execute("SELECT * FROM TEST");
assertEquals("state " + DatabaseEventListener.STATE_RECONNECTED, state);
conn.close();
if (postgreDriver != null) {
DriverManager.registerDriver(postgreDriver);
}
conn = DriverManager.getConnection(url); conn = DriverManager.getConnection(url);
restart(); restart();
...@@ -199,22 +170,15 @@ public class TestAutoReconnect extends TestBase implements DatabaseEventListener ...@@ -199,22 +170,15 @@ public class TestAutoReconnect extends TestBase implements DatabaseEventListener
} }
public void init(String u) { public void init(String u) {
state = "init"; // ignore
} }
public void opened() { public void opened() {
state = "opened"; // ignore
} }
public void setProgress(int state, String name, int x, int max) { public void setProgress(int state, String name, int x, int max) {
this.state = "state " + state; // ignore
if (state == DatabaseEventListener.STATE_RECONNECTED) {
try {
conn.createStatement().execute("CREATE LOCAL TEMPORARY TABLE TEST(ID INT)");
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论