diff --git a/jOOQ/src/main/java/org/jooq/ExecuteContext.java b/jOOQ/src/main/java/org/jooq/ExecuteContext.java
index b23692b942..5cec22346b 100644
--- a/jOOQ/src/main/java/org/jooq/ExecuteContext.java
+++ b/jOOQ/src/main/java/org/jooq/ExecuteContext.java
@@ -38,6 +38,8 @@ package org.jooq;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import org.jooq.conf.StatementType;
+
/**
* A context object for {@link Query} execution passed to registered
* {@link ExecuteListener}'s.
@@ -45,43 +47,109 @@ import java.sql.ResultSet;
* Expect most of this context's objects to be nullable!
*
* @author Lukas Eder
+ * @see ExecuteListener
*/
public interface ExecuteContext extends Configuration {
+ /**
+ * The configuration wrapped by this context
+ */
Configuration configuration();
- // TODO Routines?
- // Nullable!
+ /**
+ * The jOOQ {@link Query} that is being executed or null if the
+ * query is unknown or if there was no jOOQ Query
+ *
+ * @see #routine()
+ */
Query query();
- // Nullable!
- void sql(String sql);
+ /**
+ * The jOOQ {@link Routine} that is being executed or null if
+ * the query is unknown or if there was no jOOQ Routine
+ *
+ * @see #routine()
+ */
+ Routine> routine();
+ /**
+ * The SQL that is being executed or null if the SQL statement
+ * is unknown or if there was no SQL statement
+ */
String sql();
/**
- * Override the context's {@link PreparedStatement}
+ * Override the SQL statement that is being executed. This may have no
+ * effect, if called at the wrong moment.
+ *
+ * @see ExecuteListener#renderEnd(ExecuteContext)
+ * @see ExecuteListener#prepareStart(ExecuteContext)
+ */
+ void sql(String sql);
+
+ /**
+ * The {@link PreparedStatement} that is being executed or null
+ * if the statement is unknown or if there was no statement.
*
- * Use this to wrap the PreparedStatement executed by jOOQ with
- * your custom wrapper statement, logging bind variables and query
- * execution. Beware
+ * This can be any of the following:
+ *
+ *
java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.Statement from your JDBC driver wrapped in a
+ * java.sql.PreparedStatement when your jOOQ Query
+ * is being executed as {@link StatementType#STATIC_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ Routinenull if the
+ * result set is unknown or if no result set is being fetched.
+ */
ResultSet resultSet();
- // Nullable
- void record(Record record);
+ /**
+ * Override the {@link ResultSet} that is being fetched. This may have no
+ * effect, if called at the wrong moment.
+ *
+ * @see ExecuteListener#executeEnd(ExecuteContext)
+ * @see ExecuteListener#fetchStart(ExecuteContext)
+ */
+ void resultSet(ResultSet resultSet);
+ /**
+ * The last record that was fetched from the result set, or
+ * null if no record has been fetched.
+ */
Record record();
- void result(Result> result);
+ /**
+ * Calling this has no effect. It is being used by jOOQ internally.
+ */
+ void record(Record record);
+ /**
+ * The last result that was fetched from the result set, or
+ * null if no result has been fetched.
+ */
Result> result();
+ /**
+ * Calling this has no effect. It is being used by jOOQ internally.
+ */
+ void result(Result> result);
+
}
diff --git a/jOOQ/src/main/java/org/jooq/ExecuteListener.java b/jOOQ/src/main/java/org/jooq/ExecuteListener.java
index c27961b3a4..3c07b0572c 100644
--- a/jOOQ/src/main/java/org/jooq/ExecuteListener.java
+++ b/jOOQ/src/main/java/org/jooq/ExecuteListener.java
@@ -40,62 +40,735 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.jooq.conf.Settings;
+import org.jooq.conf.StatementType;
import org.jooq.impl.DefaultExecuteListener;
import org.jooq.impl.Factory;
import org.jooq.tools.LoggerListener;
import org.jooq.tools.StopWatchListener;
/**
- * An event listener for {@link Query} render, prepare, bind, execute, fetch
- * steps.
+ * An event listener for {@link Query}, {@link Routine}, or {@link ResultSet}
+ * render, prepare, bind, execute, fetch steps.
*
- * EventListener is a base type for loggers, debuggers, profilers,
- * data collectors that can be hooked into a jOOQ {@link Factory} using the
- * {@link Settings#getEventListeners()} property, passing Settings
- * to {@link Factory#Factory(java.sql.Connection, SQLDialect, Settings)}
+ * ExecuteListener is a base type for loggers, debuggers,
+ * profilers, data collectors that can be hooked into a jOOQ {@link Factory}
+ * using the {@link Settings#getExecuteListeners()} property, passing
+ * Settings to
+ * {@link Factory#Factory(java.sql.Connection, SQLDialect, Settings)}. Advanced
+ * ExecuteListeners can also provide custom implementations of
+ * {@link Connection}, {@link PreparedStatement} and {@link ResultSet} to jOOQ
+ * in apropriate methods. For convenience, consider extending
+ * {@link DefaultExecuteListener} instead of implementing this interface. This
+ * will prevent compilation errors in future versions of jOOQ, when this
+ * interface might get new methods.
*
- * Advanced EventListeners can also provide custom implementations
- * of {@link Connection}, {@link PreparedStatement} and {@link ResultSet} to
- * jOOQ in apropriate methods.
+ * The following table explains how every type of statement / operation invokes
+ * callback methods in the correct order for all registered
+ * ExecuteListeners. Find a legend below the table for the various
+ * use cases.
+ *
| Callback method | + *Use case [1] | + *Use case [2] | + *Use case [3] | + *Use case [4] | + *
|---|---|---|---|---|
| {@link #start(ExecuteContext)} | + *Yes | + *Yes | + *Yes | + *Yes | + *
| {@link #renderStart(ExecuteContext)} | + *Yes | + *Yes | + *No | + *Yes | + *
| {@link #renderEnd(ExecuteContext)} | + *Yes | + *Yes | + *No | + *Yes | + *
| {@link #prepareStart(ExecuteContext)} | + *Yes | + *Yes | + *No | + *Yes | + *
| {@link #prepareEnd(ExecuteContext)} | + *Yes | + *Yes | + *No | + *Yes | + *
| {@link #bindStart(ExecuteContext)} | + *Yes | + *No | + *No | + *Yes | + *
| {@link #bindEnd(ExecuteContext)} | + *Yes | + *No | + *No | + *Yes | + *
| {@link #executeStart(ExecuteContext)} | + *Yes | + *Yes | + *No | + *Yes | + *
| {@link #executeEnd(ExecuteContext)} | + *Yes | + *Yes | + *No | + *Yes | + *
| {@link #fetchStart(ExecuteContext)} | + *Yes | + *Yes | + *Yes | + *No | + *
| {@link #resultStart(ExecuteContext)} | + *Yes | + *Yes | + *Yes | + *No | + *
| {@link #recordStart(ExecuteContext)} + * |
+ * Yes | + *Yes | + *Yes | + *No | + *
| {@link #recordEnd(ExecuteContext)} | + *Yes | + *Yes | + *Yes | + *No | + *
| {@link #resultEnd(ExecuteContext)} | + *Yes | + *Yes | + *Yes | + *No | + *
| {@link #fetchEnd(ExecuteContext)} | + *Yes | + *Yes | + *Yes | + *No | + *
| {@link #end(ExecuteContext)} | + *Yes | + *Yes | + *Yes | + *No | + *
* If nothing is specified, the default is to use {@link LoggerListener} and * {@link StopWatchListener} as the only event listeners. - *
- * For convenience, consider extending {@link DefaultExecuteListener} instead of
- * implementing this interface. This will prevent compilation errors in future
- * versions of jOOQ, when this interface might get new methods.
*
* @author Lukas Eder
*/
public interface ExecuteListener {
- void init(ExecuteContext ctx);
+ /**
+ * Called to initialise an ExecuteListener
+ *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseQueryPart
+ *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseQueryPart
+ *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..
+ * Overridable attributes in ExecuteContext:
+ *
SQL
+ * statement that is about to be executed. You can modify this statement
+ * freely.
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..
+ * Overridable attributes in ExecuteContext:
+ *
SQL
+ * statement that is about to be executed. You can modify this statement
+ * freely.
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.Statement from your JDBC driver wrapped in a
+ * java.sql.PreparedStatement when your jOOQ Query
+ * is being executed as {@link StatementType#STATIC_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ Routine
+ * Overridable attributes in ExecuteContext:
+ *
Statement, PreparedStatement, or
+ * CallableStatement that is about to be executed. You can
+ * modify this statement freely, or wrap {@link ExecuteContext#statement()}
+ * with your enriched statement wrapperPreparedStatement
+ *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ Routine
+ * Overridable attributes in ExecuteContext:
+ *
PreparedStatement, or CallableStatement that is
+ * about to be executed. You can modify this statement freely, or wrap
+ * {@link ExecuteContext#statement()} with your enriched statement wrapper
+ * Note that this method is not called when executing queries of type
+ * {@link StatementType#STATIC_STATEMENT}
+ */
void bindStart(ExecuteContext ctx);
+ /**
+ * Called after binding variables to the PreparedStatement
+ *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ Routine+ * Note that this method is not called when executing queries of type + * {@link StatementType#STATIC_STATEMENT} + */ void bindEnd(ExecuteContext ctx); + /** + * Called before executing a statement + *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.Statement from your JDBC driver wrapped in a
+ * java.sql.PreparedStatement when your jOOQ Query
+ * is being executed as {@link StatementType#STATIC_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ Routine
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.Statement from your JDBC driver wrapped in a
+ * java.sql.PreparedStatement when your jOOQ Query
+ * is being executed as {@link StatementType#STATIC_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ RoutineResultSet that
+ * is about to be fetched or null, if the Query
+ * returns no result set, or if a Routine is being executed.
+ * Overridable attributes in ExecuteContext:
+ *
ResultSet that is about to be fetched. You can modify this
+ * result set freely, or wrap {@link ExecuteContext#resultSet()} with your
+ * enriched result set wrapperResultSet.
+ *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.Statement from your JDBC driver wrapped in a
+ * java.sql.PreparedStatement when your jOOQ Query
+ * is being executed as {@link StatementType#STATIC_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ RoutineResultSet that
+ * is about to be fetched.
+ * Overridable attributes in ExecuteContext:
+ *
ResultSet that is about to be fetched. You can modify this
+ * result set freely, or wrap {@link ExecuteContext#resultSet()} with your
+ * enriched result set wrapper
+ * In case of multiple ResultSets with
+ * {@link ResultQuery#fetchMany()}, this is called several times, once per
+ * ResultSet
+ *
+ * Note that this method is not called when executing queries that do not
+ * return a result, or when executing routines.
+ */
void fetchStart(ExecuteContext ctx);
+ /**
+ * Called before fetching a set of records from a ResultSet
+ *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.Statement from your JDBC driver wrapped in a
+ * java.sql.PreparedStatement when your jOOQ Query
+ * is being executed as {@link StatementType#STATIC_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ RoutineResultSet that
+ * is about to be fetched.
+ * Note that this method is not called when executing queries that do not
+ * return a result, or when executing routines. This is also not called when
+ * fetching single records, with {@link Cursor#fetchOne()} for instance.
+ */
+ void resultStart(ExecuteContext ctx);
+
+ /**
+ * Called before fetching a record from a ResultSet
+ *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.Statement from your JDBC driver wrapped in a
+ * java.sql.PreparedStatement when your jOOQ Query
+ * is being executed as {@link StatementType#STATIC_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ RoutineResultSet that
+ * is about to be fetched.
+ * Note that this method is not called when executing queries that do not
+ * return a result, or when executing routines.
+ */
+ void recordStart(ExecuteContext ctx);
+
+ /**
+ * Called after fetching a record from a ResultSet
+ *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.Statement from your JDBC driver wrapped in a
+ * java.sql.PreparedStatement when your jOOQ Query
+ * is being executed as {@link StatementType#STATIC_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ RoutineResultSet that
+ * is about to be fetched.Record that
+ * was fetched.
+ * Note that this method is not called when executing queries that do not
+ * return a result, or when executing routines.
+ */
+ void recordEnd(ExecuteContext ctx);
+
+ /**
+ * Called after fetching a set of records from a ResultSet
+ *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.Statement from your JDBC driver wrapped in a
+ * java.sql.PreparedStatement when your jOOQ Query
+ * is being executed as {@link StatementType#STATIC_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ RoutineResultSet that
+ * is about to be fetched.Record that
+ * was fetched.
+ * Note that this method is not called when executing queries that do not
+ * return a result, or when executing routines. This is also not called when
+ * fetching single records, with {@link Cursor#fetchOne()} for instance.
+ */
+ void resultEnd(ExecuteContext ctx);
+
+ /**
+ * Called after fetching data from a ResultSet.
+ *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.Statement from your JDBC driver wrapped in a
+ * java.sql.PreparedStatement when your jOOQ Query
+ * is being executed as {@link StatementType#STATIC_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ RoutineStatement is already closed!ResultSet that
+ * was fetched. Note that the ResultSet is already closed!Record that
+ * was fetched.
+ * In case of multiple ResultSets with
+ * {@link ResultQuery#fetchMany()}, this is called several times, once per
+ * ResultSet
+ *
+ * Note that this method is not called when executing queries that do not + * return a result, or when executing routines. + */ void fetchEnd(ExecuteContext ctx); + + /** + * Called at the end of the execution lifecycle.. + *
+ * Available attributes from ExecuteContext:
+ *
Query object, if a
+ * jOOQ query is being executed or null otherwiseRoutine object, if
+ * a jOOQ routine is being executed or null otherwiseSQL statement
+ * that is about to be executed, or null if the
+ * SQL statement is unknown..PreparedStatement that is about to be executed, or
+ * null if no statement is known to jOOQ. This can be any of
+ * the following: java.sql.PreparedStatement from your JDBC driver when
+ * a jOOQ Query is being executed as
+ * {@link StatementType#PREPARED_STATEMENT}java.sql.Statement from your JDBC driver wrapped in a
+ * java.sql.PreparedStatement when your jOOQ Query
+ * is being executed as {@link StatementType#STATIC_STATEMENT}java.sql.CallableStatement when you are executing a
+ * jOOQ RoutineStatement is already closed!ResultSet that
+ * was fetched or null, if no result set was fetched. Note that
+ * if any ResultSet is already closed!Record that
+ * was fetched or null if no records were fetched.