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 h2-database+unsubscr...@googlegroups.com.
To post to this group, send email to h2-database@googlegroups.com.
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;
}

Reply via email to