提交 1f1226d1 authored 作者: noelgrandin's avatar noelgrandin

Add methods to DatabaseEventListener to notify of statement start and statement end.

Patch from Steve McLeod steve.mcleod@gmail.com
上级 eaeb0c7c
...@@ -18,7 +18,8 @@ Change Log ...@@ -18,7 +18,8 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>The table INFORMATION_SCHEMA.FUNCTION_ALIASES now includes a column TYPE_NAME. <ul><li>DatabaseEventListener now calls setProgress whenever a statement starts and ends.
</li><li>The table INFORMATION_SCHEMA.FUNCTION_ALIASES now includes a column TYPE_NAME.
</li><li>Issue 378: when using views, the wrong values were bound to a parameter in some cases. </li><li>Issue 378: when using views, the wrong values were bound to a parameter in some cases.
</li><li>Terrence Huang has translated the error messages to Chinese. Thanks a lot! </li><li>Terrence Huang has translated the error messages to Chinese. Thanks a lot!
</li></ul> </li></ul>
......
...@@ -44,6 +44,16 @@ public interface DatabaseEventListener extends EventListener { ...@@ -44,6 +44,16 @@ public interface DatabaseEventListener extends EventListener {
*/ */
int STATE_RECONNECTED = 4; int STATE_RECONNECTED = 4;
/**
* This state is used when a query starts.
*/
int STATE_STATEMENT_START = 5;
/**
* This state is used when a query ends.
*/
int STATE_STATEMENT_END = 6;
/** /**
* This method is called just after creating the object. * This method is called just after creating the object.
* This is done when opening the database if the listener is specified * This is done when opening the database if the listener is specified
...@@ -79,7 +89,7 @@ public interface DatabaseEventListener extends EventListener { ...@@ -79,7 +89,7 @@ public interface DatabaseEventListener extends EventListener {
* @param state the state * @param state the state
* @param name the object name * @param name the object name
* @param x the current position * @param x the current position
* @param max the highest value * @param max the highest value, -1 if the max value is unknown
*/ */
void setProgress(int state, String name, int x, int max); void setProgress(int state, String name, int x, int max);
......
...@@ -8,6 +8,8 @@ package org.h2.command; ...@@ -8,6 +8,8 @@ package org.h2.command;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import org.h2.api.DatabaseEventListener;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
...@@ -123,6 +125,14 @@ public abstract class Command implements CommandInterface { ...@@ -123,6 +125,14 @@ public abstract class Command implements CommandInterface {
} }
} }
void publishStart() {
session.getDatabase().publishEvent(DatabaseEventListener.STATE_STATEMENT_START, sql);
}
void publishEnd() {
session.getDatabase().publishEvent(DatabaseEventListener.STATE_STATEMENT_END, sql);
}
/** /**
* Check if this command has been canceled, and throw an exception if yes. * Check if this command has been canceled, and throw an exception if yes.
* *
......
...@@ -67,20 +67,24 @@ class CommandContainer extends Command { ...@@ -67,20 +67,24 @@ class CommandContainer extends Command {
public int update() { public int update() {
recompileIfRequired(); recompileIfRequired();
publishStart();
start(); start();
session.setLastIdentity(ValueNull.INSTANCE); session.setLastIdentity(ValueNull.INSTANCE);
prepared.checkParameters(); prepared.checkParameters();
int updateCount = prepared.update(); int updateCount = prepared.update();
prepared.trace(startTime, updateCount); prepared.trace(startTime, updateCount);
publishEnd();
return updateCount; return updateCount;
} }
public ResultInterface query(int maxrows) { public ResultInterface query(int maxrows) {
recompileIfRequired(); recompileIfRequired();
publishStart();
start(); start();
prepared.checkParameters(); prepared.checkParameters();
ResultInterface result = prepared.query(maxrows); ResultInterface result = prepared.query(maxrows);
prepared.trace(startTime, result.getRowCount()); prepared.trace(startTime, result.getRowCount());
publishEnd();
return result; return result;
} }
......
...@@ -2406,4 +2406,9 @@ public class Database implements DataHandler { ...@@ -2406,4 +2406,9 @@ public class Database implements DataHandler {
throw DbException.throwInternalError(); throw DbException.throwInternalError();
} }
public void publishEvent(int state, String sql) {
if (eventListener!= null) {
eventListener.setProgress(state, sql, 0, -1);
}
}
} }
...@@ -23,6 +23,7 @@ import org.h2.test.TestBase; ...@@ -23,6 +23,7 @@ import org.h2.test.TestBase;
public class TestDatabaseEventListener extends TestBase implements DatabaseEventListener { public class TestDatabaseEventListener extends TestBase implements DatabaseEventListener {
private static boolean calledOpened, calledClosingDatabase, calledScan, calledCreateIndex; private static boolean calledOpened, calledClosingDatabase, calledScan, calledCreateIndex;
private static boolean calledStatementStart, calledStatementEnd;
/** /**
* Run just this test. * Run just this test.
...@@ -40,6 +41,7 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent ...@@ -40,6 +41,7 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
testCalled(); testCalled();
testCloseLog0(false); testCloseLog0(false);
testCloseLog0(true); testCloseLog0(true);
testCalledForStatement();
deleteDb("databaseEventListener"); deleteDb("databaseEventListener");
} }
...@@ -90,7 +92,7 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent ...@@ -90,7 +92,7 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
} }
deleteDb("databaseEventListener"); deleteDb("databaseEventListener");
String url = getURL("databaseEventListener", true); String url = getURL("databaseEventListener", true);
url += ";DATABASE_EVENT_LISTENER='"+ Init.class.getName() + "'"; url += ";DATABASE_EVENT_LISTENER='" + Init.class.getName() + "'";
Connection conn = DriverManager.getConnection(url, "sa", "sa"); Connection conn = DriverManager.getConnection(url, "sa", "sa");
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("select * from test"); stat.execute("select * from test");
...@@ -210,6 +212,24 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent ...@@ -210,6 +212,24 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
assertTrue(calledClosingDatabase); assertTrue(calledClosingDatabase);
} }
private void testCalledForStatement() throws SQLException {
Properties p = new Properties();
p.setProperty("user", "sa");
p.setProperty("password", "sa");
calledStatementStart = false;
calledStatementEnd = false;
p.put("DATABASE_EVENT_LISTENER", getClass().getName());
org.h2.Driver.load();
String url = "jdbc:h2:mem:databaseEventListener";
Connection conn = org.h2.Driver.load().connect(url, p);
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, name varchar)");
stat.execute("select * from test");
conn.close();
assertTrue(calledStatementStart);
assertTrue(calledStatementEnd);
}
public void closingDatabase() { public void closingDatabase() {
calledClosingDatabase = true; calledClosingDatabase = true;
} }
...@@ -235,6 +255,17 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent ...@@ -235,6 +255,17 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
calledCreateIndex = true; calledCreateIndex = true;
} }
} }
if (state == STATE_STATEMENT_START) {
System.out.println("name = " + name);
if (name.equals("select * from test")) {
calledStatementStart = true;
}
}
if (state == STATE_STATEMENT_END) {
if (name.equals("select * from test")) {
calledStatementEnd = true;
}
}
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论