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;
}

Reply via email to