提交 734f8950 authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #363 from dyorgio/master

Added support to define last IDENTIFIER on a Trigger.
...@@ -78,6 +78,7 @@ public class Session extends SessionWithState { ...@@ -78,6 +78,7 @@ public class Session extends SessionWithState {
private int lockTimeout; private int lockTimeout;
private Value lastIdentity = ValueLong.get(0); private Value lastIdentity = ValueLong.get(0);
private Value lastScopeIdentity = ValueLong.get(0); private Value lastScopeIdentity = ValueLong.get(0);
private Value lastTriggerIdentity = null;
private int firstUncommittedLog = Session.LOG_WRITTEN; private int firstUncommittedLog = Session.LOG_WRITTEN;
private int firstUncommittedPos = Session.LOG_WRITTEN; private int firstUncommittedPos = Session.LOG_WRITTEN;
private HashMap<String, Savepoint> savepoints; private HashMap<String, Savepoint> savepoints;
...@@ -1000,6 +1001,14 @@ public class Session extends SessionWithState { ...@@ -1000,6 +1001,14 @@ public class Session extends SessionWithState {
return lastScopeIdentity; return lastScopeIdentity;
} }
public void setLastTriggerIdentity(Value last) {
this.lastTriggerIdentity = last;
}
public Value getLastTriggerIdentity() {
return lastTriggerIdentity;
}
/** /**
* Called when a log entry for this session is added. The session keeps * Called when a log entry for this session is added. The session keeps
* track of the first entry in the transaction log that is not yet * track of the first entry in the transaction log that is not yet
......
...@@ -167,7 +167,12 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -167,7 +167,12 @@ public class TriggerObject extends SchemaObjectBase {
throw DbException.get(ErrorCode.ERROR_EXECUTING_TRIGGER_3, e, getName(), throw DbException.get(ErrorCode.ERROR_EXECUTING_TRIGGER_3, e, getName(),
triggerClassName != null ? triggerClassName : "..source..", e.toString()); triggerClassName != null ? triggerClassName : "..source..", e.toString());
} finally { } finally {
session.setLastScopeIdentity(identity); if (session.getLastTriggerIdentity() != null) {
session.setLastScopeIdentity(session.getLastTriggerIdentity());
session.setLastTriggerIdentity(null);
} else {
session.setLastScopeIdentity(identity);
}
if (type != Trigger.SELECT) { if (type != Trigger.SELECT) {
session.setCommitOrRollbackDisabled(old); session.setCommitOrRollbackDisabled(old);
} }
...@@ -262,7 +267,12 @@ public class TriggerObject extends SchemaObjectBase { ...@@ -262,7 +267,12 @@ public class TriggerObject extends SchemaObjectBase {
throw DbException.convert(e); throw DbException.convert(e);
} }
} finally { } finally {
session.setLastScopeIdentity(identity); if (session.getLastTriggerIdentity() != null) {
session.setLastScopeIdentity(session.getLastTriggerIdentity());
session.setLastTriggerIdentity(null);
} else {
session.setLastScopeIdentity(identity);
}
session.setCommitOrRollbackDisabled(oldDisabled); session.setCommitOrRollbackDisabled(oldDisabled);
session.setAutoCommit(old); session.setAutoCommit(old);
} }
......
...@@ -15,9 +15,12 @@ import java.util.HashSet; ...@@ -15,9 +15,12 @@ import java.util.HashSet;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.Trigger; import org.h2.api.Trigger;
import org.h2.engine.Session;
import org.h2.jdbc.JdbcConnection;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.tools.TriggerAdapter; import org.h2.tools.TriggerAdapter;
import org.h2.util.Task; import org.h2.util.Task;
import org.h2.value.ValueLong;
/** /**
* Tests for trigger and constraints. * Tests for trigger and constraints.
...@@ -44,6 +47,7 @@ public class TestTriggersConstraints extends TestBase implements Trigger { ...@@ -44,6 +47,7 @@ public class TestTriggersConstraints extends TestBase implements Trigger {
testTriggerAdapter(); testTriggerAdapter();
testTriggerSelectEachRow(); testTriggerSelectEachRow();
testViewTrigger(); testViewTrigger();
testViewTriggerGeneratedKeys();
testTriggerBeforeSelect(); testTriggerBeforeSelect();
testTriggerAlterTable(); testTriggerAlterTable();
testTriggerAsSource(); testTriggerAsSource();
...@@ -202,6 +206,44 @@ public class TestTriggersConstraints extends TestBase implements Trigger { ...@@ -202,6 +206,44 @@ public class TestTriggersConstraints extends TestBase implements Trigger {
stat.execute("drop table test"); stat.execute("drop table test");
conn.close(); conn.close();
} }
private void testViewTriggerGeneratedKeys() 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 identity)");
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 \"" +
TestViewGeneratedKeys.class.getName() + "\"");
if (!config.memory) {
conn.close();
conn = getConnection("trigger");
stat = conn.createStatement();
}
PreparedStatement pstat;
pstat = conn.prepareStatement("insert into test_view values()", Statement.RETURN_GENERATED_KEYS);
int count = pstat.executeUpdate();
assertEquals(1, count);
ResultSet gkRs;
gkRs = pstat.getGeneratedKeys();
assertTrue(gkRs.next());
assertEquals(1, gkRs.getInt(1));
assertFalse(gkRs.next());
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 adapter implementation. * A test trigger adapter implementation.
...@@ -286,6 +328,43 @@ public class TestTriggersConstraints extends TestBase implements Trigger { ...@@ -286,6 +328,43 @@ public class TestTriggersConstraints extends TestBase implements Trigger {
} }
} }
public static class TestViewGeneratedKeys implements Trigger {
PreparedStatement prepInsert;
@Override
public void init(Connection conn, String schemaName,
String triggerName, String tableName, boolean before, int type)
throws SQLException {
prepInsert = conn.prepareStatement("insert into test values()", Statement.RETURN_GENERATED_KEYS);
}
@Override
public void fire(Connection conn, Object[] oldRow, Object[] newRow)
throws SQLException {
if (newRow != null) {
prepInsert.execute();
ResultSet rs = prepInsert.getGeneratedKeys();
if (rs.next()) {
JdbcConnection jconn = (JdbcConnection) conn;
Session session = (Session) jconn.getSession();
session.setLastTriggerIdentity(ValueLong.get(rs.getLong(1)));
}
}
}
@Override
public void close() {
// ignore
}
@Override
public void remove() {
// ignore
}
}
private void testTriggerBeforeSelect() throws SQLException { private void testTriggerBeforeSelect() throws SQLException {
Connection conn; Connection conn;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论