Hi, I'd like to propose a new Trigger interface (attached) with the following benefits:
- - Simplified init() method: Users can pull as little or as much data as they'd like from class Metadata. - Performance benefit for triggers that process multiple rows: PreparedStatements sharing using initTransaction(), closeTransaction(). - Ability to detect when triggers are fired by SELECT or ROLLBACK. - Ability to clean up resources when a trigger is dropped (not just when the database is closed). I initially shared this proposal with Noel a few months back and had hoped to implement it myself. Unfortunately, my work schedule has gotten completely out of hand and I no longer believe that I will be able to work on it after all. I am sharing it with the community in the hopes that you will pick up where I left off. Kind regards, Gili -- You received this message because you are subscribed to the Google Groups "H2 Database" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/h2-database. For more options, visit https://groups.google.com/groups/opt_out.
/* * Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License, * Version 1.0, and under the Eclipse Public License, Version 1.0 * (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.api; import java.sql.Connection; import java.sql.SQLException; import java.util.HashSet; import java.util.Set; /** * A class that implements this interface can be used as a trigger. */ public interface Trigger2 { /** * Indicates when the Trigger is fired. */ public enum TimingType { /** * The trigger is called before a statement. */ BEFORE, /** * The trigger is called after a statement. */ AFTER, /** * The trigger is called instead of a statement. */ INSTEAD_OF }; /** * The type of statements that may be associated with a Trigger. */ public enum StatementType { /** * The trigger is called for INSERT statements. */ INSERT, /** * The trigger is called for UPDATE statements. */ UPDATE, /** * The trigger is called for DELETE statements. */ DELETE, /** * The trigger is called for SELECT statements. */ SELECT, /** * The trigger is called for ROLLBACK statements. */ ROLLBACK }; /** * The trigger metadata. */ public static class Metadata { private final String schemaName; private final String triggerName; private final String tableName; private final TimingType timing; private final Set<StatementType> statements; /** * Creates a new Metadata. * <p> * @param schemaName the name of the schema the trigger is operating on * @param triggerName the name of the trigger used in the CREATE TRIGGER statement * @param tableName the name of the table the trigger is operating on * @param timing indicates when the trigger will be called * @param statements indicates the type of statements that cause the trigger to fire */ public Metadata(String schemaName, String triggerName, String tableName, TimingType timing, Set<StatementType> statements) { this.schemaName = schemaName; this.triggerName = triggerName; this.tableName = tableName; this.timing = timing; this.statements = new HashSet<>(statements); } /** * @return the name of the schema the trigger is operating on */ public String getSchemaName() { return schemaName; } /** * @return the name of the trigger used in the CREATE TRIGGER statement */ public String getTriggerName() { return triggerName; } /** * @return the name of the table the trigger is operating on */ public String getTableName() { return tableName; } /** * @return when the trigger will be called */ public TimingType getTiming() { return timing; } /** * @return the type of statements that cause the trigger to fire */ public Set<StatementType> getStatements() { return statements; } } /** * This method is called when the trigger is created, as well as when the database is opened. * <p/> * @param systemConnection a connection to the database (not the same connection that is used to * run the trigger) * @param metadata information about the trigger * @throws SQLException if an error occurs while initializing the trigger */ void init(Connection systemConnection, Metadata metadata) throws SQLException; /** * This method is called before the first time the trigger is fired in a transaction. * <p/> * @param connection a connection to the database * @throws SQLException if an error occurs */ void initTransaction(Connection connection) throws SQLException; /** * This method is called for each triggered action. The method is called within the same * transaction as the statement that triggered the action (before it is committed). A transaction * rollback will also rollback the operations that were done within the trigger, if the operations * occurred within the same database. If the trigger changes state outside the database, a * rollback trigger should be used. * <p> * The row arrays contain all columns of the table, in the same order as defined in the table. * </p> * <p/> * @param connection a connection to the database * @param statement the type of statement that caused the trigger to fire * @param oldRow the old row, or null if no old row is available (for INSERT) * @param newRow the new row, or null if no new row is available (for DELETE) * @throws SQLException if the operation must be undone */ void fire(Connection connection, StatementType statement, Object[] oldRow, Object[] newRow) throws SQLException; /** * This method is called after the last time the trigger is fired in a transaction. * <p/> * @param connection a connection to the database * @throws SQLException if an error occurs */ void closeTransaction(Connection connection) throws SQLException; /** * This method is called when the trigger is dropped or the database is closed. If the database is * being closed and the method throws an exception, it will be logged, but closing the database * will continue. * <p/> * @throws SQLException if an error occurs */ void close() throws SQLException; }
