提交 658332f0 authored 作者: Thomas Mueller's avatar Thomas Mueller

Triggers: INSTEAD OF triggers are now supported.

上级 ed7740d3
...@@ -35,6 +35,7 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -35,6 +35,7 @@ public class TriggerObject extends SchemaObjectBase {
*/ */
public static final int DEFAULT_QUEUE_SIZE = 1024; public static final int DEFAULT_QUEUE_SIZE = 1024;
private boolean insteadOf;
private boolean before; private boolean before;
private int typeMask; private int typeMask;
private boolean rowBased; private boolean rowBased;
...@@ -56,6 +57,10 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -56,6 +57,10 @@ public class TriggerObject extends SchemaObjectBase {
this.before = before; this.before = before;
} }
public void setInsteadOf(boolean insteadOf) {
this.insteadOf = insteadOf;
}
private synchronized void load(Session session) throws SQLException { private synchronized void load(Session session) throws SQLException {
if (triggerCallback != null) { if (triggerCallback != null) {
return; return;
...@@ -148,14 +153,15 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -148,14 +153,15 @@ public class TriggerObject extends SchemaObjectBase {
* @param newRow the new row * @param newRow the new row
* @param beforeAction true if this method is called before the operation is * @param beforeAction true if this method is called before the operation is
* applied * applied
* @param rollback when the operation occurred within a rollback * @param rollback when the operation occurred within a rollback
* @return true if no further action is required (for 'instead of' triggers)
*/ */
public void fireRow(Session session, Row oldRow, Row newRow, boolean beforeAction, boolean rollback) throws SQLException { public boolean fireRow(Session session, Row oldRow, Row newRow, boolean beforeAction, boolean rollback) throws SQLException {
if (!rowBased || before != beforeAction) { if (!rowBased || before != beforeAction) {
return; return false;
} }
if (rollback && !onRollback) { if (rollback && !onRollback) {
return; return false;
} }
load(session); load(session);
Object[] oldList; Object[] oldList;
...@@ -177,7 +183,7 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -177,7 +183,7 @@ public class TriggerObject extends SchemaObjectBase {
} }
} }
if (!fire) { if (!fire) {
return; return false;
} }
oldList = convertToObjectList(oldRow); oldList = convertToObjectList(oldRow);
newList = convertToObjectList(newRow); newList = convertToObjectList(newRow);
...@@ -217,6 +223,7 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -217,6 +223,7 @@ public class TriggerObject extends SchemaObjectBase {
session.setCommitOrRollbackDisabled(oldDisabled); session.setCommitOrRollbackDisabled(oldDisabled);
session.setAutoCommit(old); session.setAutoCommit(old);
} }
return insteadOf;
} }
/** /**
...@@ -259,7 +266,9 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -259,7 +266,9 @@ public class TriggerObject extends SchemaObjectBase {
public String getCreateSQLForCopy(Table targetTable, String quotedName) { public String getCreateSQLForCopy(Table targetTable, String quotedName) {
StringBuilder buff = new StringBuilder("CREATE FORCE TRIGGER "); StringBuilder buff = new StringBuilder("CREATE FORCE TRIGGER ");
buff.append(quotedName); buff.append(quotedName);
if (before) { if (insteadOf) {
buff.append(" INSTEAD OF ");
} else if (before) {
buff.append(" BEFORE "); buff.append(" BEFORE ");
} else { } else {
buff.append(" AFTER "); buff.append(" AFTER ");
......
...@@ -745,13 +745,15 @@ public abstract class Table extends SchemaObjectBase { ...@@ -745,13 +745,15 @@ public abstract class Table extends SchemaObjectBase {
/** /**
* Fire all triggers that need to be called before a row is updated. * Fire all triggers that need to be called before a row is updated.
* *
* @param session the session * @param session the session
* @param oldRow the old data or null for an insert * @param oldRow the old data or null for an insert
* @param newRow the new data or null for a delete * @param newRow the new data or null for a delete
* @return true if no further action is required (for 'instead of' triggers)
*/ */
public void fireBeforeRow(Session session, Row oldRow, Row newRow) throws SQLException { public boolean fireBeforeRow(Session session, Row oldRow, Row newRow) throws SQLException {
fireRow(session, oldRow, newRow, true, false); boolean done = fireRow(session, oldRow, newRow, true, false);
fireConstraints(session, oldRow, newRow, true); fireConstraints(session, oldRow, newRow, true);
return done;
} }
private void fireConstraints(Session session, Row oldRow, Row newRow, boolean before) throws SQLException { private void fireConstraints(Session session, Row oldRow, Row newRow, boolean before) throws SQLException {
...@@ -779,12 +781,16 @@ public abstract class Table extends SchemaObjectBase { ...@@ -779,12 +781,16 @@ public abstract class Table extends SchemaObjectBase {
} }
} }
private void fireRow(Session session, Row oldRow, Row newRow, boolean beforeAction, boolean rollback) throws SQLException { private boolean fireRow(Session session, Row oldRow, Row newRow, boolean beforeAction, boolean rollback) throws SQLException {
if (triggers != null) { if (triggers != null) {
for (TriggerObject trigger : triggers) { for (TriggerObject trigger : triggers) {
trigger.fireRow(session, oldRow, newRow, beforeAction, rollback); boolean done = trigger.fireRow(session, oldRow, newRow, beforeAction, rollback);
if (done) {
return true;
}
} }
} }
return false;
} }
public boolean isGlobalTemporary() { public boolean isGlobalTemporary() {
......
...@@ -37,6 +37,7 @@ public class TestTriggersConstraints extends TestBase implements Trigger { ...@@ -37,6 +37,7 @@ public class TestTriggersConstraints extends TestBase implements Trigger {
public void test() throws SQLException { public void test() throws SQLException {
deleteDb("trigger"); deleteDb("trigger");
testViewTrigger();
testTriggerBeforeSelect(); testTriggerBeforeSelect();
testTriggerAlterTable(); testTriggerAlterTable();
testTriggers(); testTriggers();
...@@ -44,6 +45,49 @@ public class TestTriggersConstraints extends TestBase implements Trigger { ...@@ -44,6 +45,49 @@ public class TestTriggersConstraints extends TestBase implements Trigger {
deleteDb("trigger"); deleteDb("trigger");
} }
private void testViewTrigger() throws SQLException {
Connection conn;
Statement stat;
conn = getConnection("trigger");
stat = conn.createStatement();
stat.execute("drop table if exists test");
stat.execute("create table test(id int)");
stat.execute("create view test_view as select * from test");
stat.execute("create trigger test_view_insert instead of insert on test_view for each row call \"" + TestView.class.getName() + "\"");
if (!config.memory) {
conn.close();
conn = getConnection("trigger");
stat = conn.createStatement();
}
stat.execute("insert into test_view values(1)");
ResultSet rs;
rs = stat.executeQuery("select * from test");
assertTrue(rs.next());
assertFalse(rs.next());
stat.execute("drop view test_view");
stat.execute("drop table test");
conn.close();
}
/**
* A test trigger implementation.
*/
public static class TestView implements Trigger {
PreparedStatement prepInsert;
public void init(Connection conn, String schemaName, String triggerName, String tableName, boolean before,
int type) throws SQLException {
prepInsert = conn.prepareStatement("insert into test values(?)");
}
public void fire(Connection conn, Object[] oldRow, Object[] newRow) throws SQLException {
prepInsert.setInt(1, (Integer) newRow[0]);
prepInsert.execute();
}
}
private void testTriggerBeforeSelect() throws SQLException { private void testTriggerBeforeSelect() throws SQLException {
Connection conn; Connection conn;
Statement stat; Statement stat;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论