提交 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
<h1>Change Log</h1>
<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>Terrence Huang has translated the error messages to Chinese. Thanks a lot!
</li></ul>
......
......@@ -44,6 +44,16 @@ public interface DatabaseEventListener extends EventListener {
*/
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 is done when opening the database if the listener is specified
......@@ -79,7 +89,7 @@ public interface DatabaseEventListener extends EventListener {
* @param state the state
* @param name the object name
* @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);
......
......@@ -8,6 +8,8 @@ package org.h2.command;
import java.sql.SQLException;
import java.util.ArrayList;
import org.h2.api.DatabaseEventListener;
import org.h2.constant.ErrorCode;
import org.h2.engine.Constants;
import org.h2.engine.Database;
......@@ -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.
*
......
......@@ -67,20 +67,24 @@ class CommandContainer extends Command {
public int update() {
recompileIfRequired();
publishStart();
start();
session.setLastIdentity(ValueNull.INSTANCE);
prepared.checkParameters();
int updateCount = prepared.update();
prepared.trace(startTime, updateCount);
publishEnd();
return updateCount;
}
public ResultInterface query(int maxrows) {
recompileIfRequired();
publishStart();
start();
prepared.checkParameters();
ResultInterface result = prepared.query(maxrows);
prepared.trace(startTime, result.getRowCount());
publishEnd();
return result;
}
......
......@@ -2406,4 +2406,9 @@ public class Database implements DataHandler {
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;
public class TestDatabaseEventListener extends TestBase implements DatabaseEventListener {
private static boolean calledOpened, calledClosingDatabase, calledScan, calledCreateIndex;
private static boolean calledStatementStart, calledStatementEnd;
/**
* Run just this test.
......@@ -40,6 +41,7 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
testCalled();
testCloseLog0(false);
testCloseLog0(true);
testCalledForStatement();
deleteDb("databaseEventListener");
}
......@@ -90,7 +92,7 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
}
deleteDb("databaseEventListener");
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");
Statement stat = conn.createStatement();
stat.execute("select * from test");
......@@ -210,6 +212,24 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
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() {
calledClosingDatabase = true;
}
......@@ -235,6 +255,17 @@ public class TestDatabaseEventListener extends TestBase implements DatabaseEvent
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论