提交 0e597e68 authored 作者: Thomas Mueller's avatar Thomas Mueller

Trigger that are called before a select statement are now supported.

上级 eab40a6c
...@@ -29,6 +29,11 @@ public interface Trigger { ...@@ -29,6 +29,11 @@ public interface Trigger {
*/ */
int DELETE = 4; int DELETE = 4;
/**
* The trigger is called for SELECT statements.
*/
int SELECT = 8;
/** /**
* This method is called by the database engine once when initializing the * This method is called by the database engine once when initializing the
* trigger. * trigger.
......
...@@ -3707,6 +3707,8 @@ public class Parser { ...@@ -3707,6 +3707,8 @@ public class Parser {
typeMask |= Trigger.UPDATE; typeMask |= Trigger.UPDATE;
} else if (readIf("DELETE")) { } else if (readIf("DELETE")) {
typeMask |= Trigger.DELETE; typeMask |= Trigger.DELETE;
} else if (readIf("SELECT")) {
typeMask |= Trigger.SELECT;
} else { } else {
throw getSyntaxError(); throw getSyntaxError();
} }
......
...@@ -177,6 +177,11 @@ public abstract class Query extends Prepared { ...@@ -177,6 +177,11 @@ public abstract class Query extends Prepared {
*/ */
public abstract void updateAggregate(Session s) throws SQLException; public abstract void updateAggregate(Session s) throws SQLException;
/**
* Call the before triggers on all tables.
*/
public abstract void fireBeforeSelectTriggers() throws SQLException;
public boolean isQuery() { public boolean isQuery() {
return true; return true;
} }
...@@ -216,6 +221,7 @@ public abstract class Query extends Prepared { ...@@ -216,6 +221,7 @@ public abstract class Query extends Prepared {
} }
public ResultInterface query(int limit) throws SQLException { public ResultInterface query(int limit) throws SQLException {
fireBeforeSelectTriggers();
if (!session.getDatabase().getOptimizeReuseResults()) { if (!session.getDatabase().getOptimizeReuseResults()) {
return queryWithoutCache(limit); return queryWithoutCache(limit);
} }
......
...@@ -10,6 +10,7 @@ import java.sql.SQLException; ...@@ -10,6 +10,7 @@ import java.sql.SQLException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import org.h2.api.Trigger;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.engine.Constants; import org.h2.engine.Constants;
...@@ -791,6 +792,12 @@ public class Select extends Query { ...@@ -791,6 +792,12 @@ public class Select extends Query {
return set; return set;
} }
public void fireBeforeSelectTriggers() throws SQLException {
for (TableFilter filter : filters) {
filter.getTable().fire(session, Trigger.SELECT, true);
}
}
private double preparePlan() throws SQLException { private double preparePlan() throws SQLException {
TableFilter[] topArray = topFilters.toArray(new TableFilter[topFilters.size()]); TableFilter[] topArray = topFilters.toArray(new TableFilter[topFilters.size()]);
for (TableFilter t : topArray) { for (TableFilter t : topArray) {
......
...@@ -353,4 +353,9 @@ public class SelectUnion extends Query { ...@@ -353,4 +353,9 @@ public class SelectUnion extends Query {
return null; return null;
} }
public void fireBeforeSelectTriggers() throws SQLException {
left.fireBeforeSelectTriggers();
right.fireBeforeSelectTriggers();
}
} }
...@@ -20,6 +20,7 @@ import org.h2.message.Trace; ...@@ -20,6 +20,7 @@ import org.h2.message.Trace;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.util.ClassUtils; import org.h2.util.ClassUtils;
import org.h2.util.StatementBuilder;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -96,15 +97,19 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -96,15 +97,19 @@ public class TriggerObject extends SchemaObjectBase {
* or after any rows have been processed, once for each statement. * or after any rows have been processed, once for each statement.
* *
* @param session the session * @param session the session
* @param type the trigger type
* @param beforeAction if this method is called before applying the changes * @param beforeAction if this method is called before applying the changes
*/ */
public void fire(Session session, boolean beforeAction) throws SQLException { public void fire(Session session, int type, boolean beforeAction) throws SQLException {
if (rowBased || before != beforeAction) { if (rowBased || before != beforeAction || (typeMask & type) == 0) {
return; return;
} }
load(session); load(session);
Connection c2 = session.createConnection(false); Connection c2 = session.createConnection(false);
boolean old = session.setCommitOrRollbackDisabled(true); boolean old = false;
if (type != Trigger.SELECT) {
old = session.setCommitOrRollbackDisabled(true);
}
Value identity = session.getScopeIdentity(); Value identity = session.getScopeIdentity();
try { try {
triggerCallback.fire(c2, null, null); triggerCallback.fire(c2, null, null);
...@@ -113,7 +118,9 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -113,7 +118,9 @@ public class TriggerObject extends SchemaObjectBase {
triggerClassName, e.toString()); triggerClassName, e.toString());
} finally { } finally {
session.setScopeIdentity(identity); session.setScopeIdentity(identity);
session.setCommitOrRollbackDisabled(old); if (type != Trigger.SELECT) {
session.setCommitOrRollbackDisabled(old);
}
} }
} }
...@@ -256,22 +263,23 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -256,22 +263,23 @@ public class TriggerObject extends SchemaObjectBase {
} }
public String getTypeNameList() { public String getTypeNameList() {
StringBuilder buff = new StringBuilder(); StatementBuilder buff = new StatementBuilder();
if ((typeMask & Trigger.INSERT) != 0) { if ((typeMask & Trigger.INSERT) != 0) {
buff.appendExceptFirst(", ");
buff.append("INSERT"); buff.append("INSERT");
} }
if ((typeMask & Trigger.UPDATE) != 0) { if ((typeMask & Trigger.UPDATE) != 0) {
if (buff.length() > 0) { buff.appendExceptFirst(", ");
buff.append(", ");
}
buff.append("UPDATE"); buff.append("UPDATE");
} }
if ((typeMask & Trigger.DELETE) != 0) { if ((typeMask & Trigger.DELETE) != 0) {
if (buff.length() > 0) { buff.appendExceptFirst(", ");
buff.append(", ");
}
buff.append("DELETE"); buff.append("DELETE");
} }
if ((typeMask & Trigger.SELECT) != 0) {
buff.appendExceptFirst(", ");
buff.append("SELECT");
}
return buff.toString(); return buff.toString();
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论