[#1578] Change configuration of ExecuteListeners in Configuration.

Listeners instances should be provided, not classes
This commit is contained in:
Lukas Eder 2013-02-04 20:39:43 +01:00
parent be484c39bf
commit 86e581c869
16 changed files with 89 additions and 70 deletions

View File

@ -706,7 +706,7 @@ public abstract class BaseTest<
protected Executor create(Settings settings) {
Executor create = delegate.create(settings);
create.getSettings().getExecuteListeners().add(TestStatisticsListener.class.getName());
create.getExecuteListeners().add(new TestStatisticsListener());
return create;
}

View File

@ -47,7 +47,7 @@ public class TestStatisticsListener extends DefaultExecuteListener {
public static Map<ExecuteType, Integer> STATISTICS = new HashMap<ExecuteType, Integer>();
@Override
public void start(ExecuteContext ctx) {
public synchronized void start(ExecuteContext ctx) {
Integer count = STATISTICS.get(ctx.type());
if (count == null) {

View File

@ -41,6 +41,7 @@ import java.sql.ResultSet;
import java.util.Collections;
import java.util.Random;
import org.jooq.ExecuteListener;
import org.jooq.Record1;
import org.jooq.Record2;
import org.jooq.Record3;
@ -119,7 +120,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
Executor create = create();
create.getSettings().setExecuteLogging(false);
create.getSettings().setExecuteListeners(Collections.<String>emptyList());
create.setExecuteListeners(Collections.<ExecuteListener>emptyList());
// Dry-run to avoid side-effects
testBenchmarkFullExecution(create, 1);

View File

@ -63,7 +63,6 @@ import org.jooq.Record6;
import org.jooq.Result;
import org.jooq.TableRecord;
import org.jooq.UpdatableRecord;
import org.jooq.conf.Settings;
import org.jooq.conf.SettingsTools;
import org.jooq.impl.DefaultExecuteListener;
import org.jooq.impl.Executor;
@ -100,8 +99,8 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
@Test
public void testExecuteListenerCustomException() throws Exception {
Executor create = create(new Settings()
.withExecuteListeners(CustomExceptionListener.class.getName()));
Executor create = create();
create.getExecuteListeners().add(new CustomExceptionListener());
try {
create.fetch("invalid sql");
@ -120,8 +119,8 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
@Test
public void testExecuteListenerOnResultQuery() throws Exception {
Executor create = create(new Settings()
.withExecuteListeners(ResultQueryListener.class.getName()));
Executor create = create();
create.getExecuteListeners().add(new ResultQueryListener());
create.setData("Foo", "Bar");
create.setData("Bar", "Baz");
@ -459,8 +458,8 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
jOOQAbstractTest.reset = false;
Executor create = create(new Settings()
.withExecuteListeners(BatchSingleListener.class.getName()));
Executor create = create();
create.getExecuteListeners().add(new BatchSingleListener());
create.setData("Foo", "Bar");
create.setData("Bar", "Baz");
@ -668,8 +667,8 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
public void testExecuteListenerOnBatchMultiple() {
jOOQAbstractTest.reset = false;
Executor create = create(new Settings()
.withExecuteListeners(BatchMultipleListener.class.getName()));
Executor create = create();
create.getExecuteListeners().add(new BatchMultipleListener());
create.setData("Foo", "Bar");
create.setData("Bar", "Baz");
@ -889,7 +888,8 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
@Test
public void testExecuteListenerFetchLazyTest() throws Exception {
Executor create = create(new Settings().withExecuteListeners(FetchLazyListener.class.getName()));
Executor create = create();
create.getExecuteListeners().add(new FetchLazyListener());
FetchLazyListener.reset();
create.selectFrom(TAuthor()).fetch();

View File

@ -232,7 +232,9 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
// [#1191] Check execution capabilities with new features in ExecuteListener
ConnectionProviderListener.c = create().getConnectionProvider().acquire();
try {
q = create(new Settings().withExecuteListeners(ConnectionProviderListener.class.getName()))
Executor create = create();
create.getExecuteListeners().add(new ConnectionProviderListener());
q = create
.selectFrom(TAuthor())
.orderBy(TAuthor_LAST_NAME());
q = runSerialisation(q);

View File

@ -60,9 +60,9 @@ import org.jooq.ResultQuery;
import org.jooq.Select;
import org.jooq.TableRecord;
import org.jooq.UpdatableRecord;
import org.jooq.conf.Settings;
import org.jooq.exception.DataAccessException;
import org.jooq.impl.DefaultExecuteListener;
import org.jooq.impl.Executor;
import org.jooq.test.BaseTest;
import org.jooq.test.jOOQAbstractTest;
import org.jooq.tools.reflect.Reflect;
@ -97,11 +97,12 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
@Test
public void testKeepStatement() throws Exception {
Settings settings = new Settings().withExecuteListeners(KeepStatementListener.class.getName());
Executor create = create();
create.getExecuteListeners().add(new KeepStatementListener());
// [#385] By default, new statements are created for every execution
KeepStatementListener.reset();
ResultQuery<Record1<Integer>> query = create(settings).select(val(1));
ResultQuery<Record1<Integer>> query = create.select(val(1));
assertEquals(1, query.fetchOne(0));
assertEquals(2, query.bind(1, 2).fetchOne(0));

View File

@ -774,12 +774,12 @@ public abstract class jOOQAbstractTest<
Settings settings = SettingsTools.defaultSettings()
.withRenderSchema(renderSchema)
.withRenderMapping(new RenderMapping()
.withDefaultSchema(defaultSchema))
.withExecuteListeners(
TestStatisticsListener.class.getName(),
PrettyPrinter.class.getName());
.withDefaultSchema(defaultSchema));
return create(settings);
Executor create = create(settings);
create.getExecuteListeners().add(new TestStatisticsListener());
create.getExecuteListeners().add(new PrettyPrinter());
return create;
}
protected final SQLDialect getDialect() {

View File

@ -36,6 +36,7 @@
package org.jooq;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.jooq.conf.Settings;
@ -138,4 +139,8 @@ public interface Configuration extends Serializable {
*/
Object setData(String key, Object value);
List<ExecuteListener> getExecuteListeners();
void setExecuteListeners(List<ExecuteListener> listeners);
}

View File

@ -54,10 +54,10 @@ import org.jooq.tools.StopWatchListener;
* <p>
* <code>ExecuteListener</code> is a base type for loggers, debuggers,
* profilers, data collectors that can be hooked into a jOOQ {@link Executor}
* using the {@link Settings#getExecuteListeners()} property, passing
* using the {@link Configuration#getExecuteListeners()} property, passing
* <code>Settings</code> to
* {@link Executor#Executor(java.sql.Connection, SQLDialect, Settings)}. jOOQ
* will use those settings at the beginning of a query execution event to
* will use that configuration at the beginning of a query execution event to
* instanciate all the provided listeners. In other words, listeners have the
* same lifetime as a single query execution, and can thus be used to store
* state between the moment when a query execution starts, and the moment when a

View File

@ -35,10 +35,12 @@
*/
package org.jooq.impl;
import java.util.List;
import java.util.Map;
import org.jooq.Configuration;
import org.jooq.ConnectionProvider;
import org.jooq.ExecuteListener;
import org.jooq.SQLDialect;
import org.jooq.conf.Settings;
@ -96,4 +98,16 @@ abstract class AbstractConfiguration implements Configuration {
public final Object setData(String key, Object value) {
return configuration.setData(key, value);
}
@Override
public final List<ExecuteListener> getExecuteListeners() {
return configuration.getExecuteListeners();
}
@Override
public final void setExecuteListeners(List<ExecuteListener> listeners) {
configuration.setExecuteListeners(listeners);
}
}

View File

@ -38,7 +38,6 @@ package org.jooq.impl;
import static org.jooq.conf.SettingsTools.executeStaticStatements;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -51,8 +50,6 @@ import org.jooq.Configuration;
import org.jooq.ExecuteContext;
import org.jooq.Query;
import org.jooq.UpdatableRecord;
import org.jooq.conf.Settings;
import org.jooq.conf.SettingsTools;
import org.jooq.exception.DataAccessException;
/**
@ -96,18 +93,18 @@ class BatchCRUD implements Batch {
private final int[] executePrepared() {
Map<String, List<Query>> queries = new LinkedHashMap<String, List<Query>>();
Settings work = create.getSettings();
Settings orig = SettingsTools.clone(work);
Boolean executeLogging = create.getSettings().isExecuteLogging();
QueryCollector collector = new QueryCollector();
try {
// [#1537] Communicate with UpdatableRecordImpl
create.setData(Utils.DATA_OMIT_RETURNING_CLAUSE, true);
// Add the QueryCollector to intercept query execution after rendering
work.setExecuteListeners(Arrays.asList(QueryCollector.class.getName()));
create.getExecuteListeners().add(collector);
// [#1529] Avoid DEBUG logging of single INSERT / UPDATE statements
work.setExecuteLogging(false);
create.getSettings().setExecuteLogging(false);
for (int i = 0; i < records.length; i++) {
Configuration previous = ((AttachableInternal) records[i]).getConfiguration();
@ -142,8 +139,8 @@ class BatchCRUD implements Batch {
finally {
create.getData().remove(Utils.DATA_OMIT_RETURNING_CLAUSE);
work.setExecuteListeners(orig.getExecuteListeners());
work.setExecuteLogging(orig.isExecuteLogging());
create.getExecuteListeners().remove(collector);
create.getSettings().setExecuteLogging(executeLogging);
}
// Execute one batch statement for each identical SQL statement. Every
@ -174,12 +171,10 @@ class BatchCRUD implements Batch {
private final int[] executeStatic() {
List<Query> queries = new ArrayList<Query>();
Settings work = create.getSettings();
Settings orig = SettingsTools.clone(work);
QueryCollector collector = new QueryCollector();
try {
work.setExecuteListeners(Arrays.asList(QueryCollector.class.getName()));
create.getExecuteListeners().add(collector);
for (int i = 0; i < records.length; i++) {
Configuration previous = ((AttachableInternal) records[i]).getConfiguration();
@ -203,7 +198,7 @@ class BatchCRUD implements Batch {
// Restore the original factory
finally {
work.setExecuteListeners(orig.getExecuteListeners());
create.getExecuteListeners().remove(collector);
}
// Resulting statements can be batch executed in their requested order

View File

@ -38,13 +38,16 @@ package org.jooq.impl;
import static org.jooq.SQLDialect.SQL99;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXB;
import org.jooq.Configuration;
import org.jooq.ConnectionProvider;
import org.jooq.ExecuteListener;
import org.jooq.SQLDialect;
import org.jooq.conf.Settings;
import org.jooq.conf.SettingsTools;
@ -67,6 +70,7 @@ class DefaultConfiguration implements Configuration {
private final org.jooq.SchemaMapping mapping;
private final Settings settings;
private final Map<String, Object> data;
private List<ExecuteListener> listeners;
@SuppressWarnings("deprecation")
DefaultConfiguration() {
@ -80,6 +84,7 @@ class DefaultConfiguration implements Configuration {
this.settings = settings != null ? settings : SettingsTools.defaultSettings();
this.mapping = new org.jooq.SchemaMapping(this.settings);
this.data = data != null ? data : new HashMap<String, Object>();
this.listeners = new ArrayList<ExecuteListener>();
}
/**
@ -139,6 +144,22 @@ class DefaultConfiguration implements Configuration {
return data.put(key, value);
}
/**
* {@inheritDoc}
*/
@Override
public final List<ExecuteListener> getExecuteListeners() {
return listeners;
}
/**
* {@inheritDoc}
*/
@Override
public final void setExecuteListeners(List<ExecuteListener> listeners) {
this.listeners = listeners != null ? listeners : new ArrayList<ExecuteListener>();
}
@Override
public String toString() {
StringWriter writer = new StringWriter();

View File

@ -383,6 +383,16 @@ public class Executor implements Configuration {
return configuration.getConnectionProvider();
}
@Override
public final List<ExecuteListener> getExecuteListeners() {
return configuration.getExecuteListeners();
}
@Override
public final void setExecuteListeners(List<ExecuteListener> listeners) {
configuration.setExecuteListeners(listeners);
}
// -------------------------------------------------------------------------
// XXX Convenience methods accessing the underlying Connection
// -------------------------------------------------------------------------

View File

@ -834,27 +834,13 @@ final class Utils {
result.add(new LoggerListener());
}
for (String listener : configuration.getSettings().getExecuteListeners()) {
result.add(getListener(listener));
for (ExecuteListener listener : configuration.getExecuteListeners()) {
result.add(listener);
}
return result;
}
private static final ExecuteListener getListener(String name) {
try {
// [#1572] Loading classes like this is needed for class loading to
// work with OSGi. [#1578] The current implementation of loading
// ExecuteListeners will be reworked in jOOQ 3.0, though
Class<?> type = Thread.currentThread().getContextClassLoader().loadClass(name);
return (ExecuteListener) Reflect.accessible(type.getDeclaredConstructor()).newInstance();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Wrap a piece of SQL code in parentheses, if not wrapped already
*/

View File

@ -35,9 +35,6 @@
<!-- When set to true, this will add jOOQ's default logging ExecuteListeners -->
<element name="executeLogging" type="boolean" minOccurs="0" maxOccurs="1" default="true"/>
<!-- The event listeners to be notified upon execution events -->
<element name="executeListeners" type="jooq-runtime:ExecuteListeners" minOccurs="0" maxOccurs="1"/>
<!-- Whether store() and delete() methods should be executed with optimistic locking -->
<element name="executeWithOptimisticLocking" type="boolean" minOccurs="0" maxOccurs="1" default="false"/>
@ -150,12 +147,4 @@
<enumeration value="UPPER"/>
</restriction>
</simpleType>
<complexType name="ExecuteListeners">
<sequence>
<!-- An event listener implementing org.jooq.ExecuteListener -->
<element name="executeListener" type="string" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</schema>

View File

@ -77,10 +77,5 @@ public class SettingsTest {
Settings settings2 = SettingsTools.clone(settings1);
assertEquals(settings1.isAttachRecords(), settings2.isAttachRecords());
assertEquals(settings1.getExecuteListeners(), settings2.getExecuteListeners());
// Check if clone makes a deep-copy
settings1.getExecuteListeners().add("asdf");
assertEquals(settings1.getExecuteListeners().size(), settings2.getExecuteListeners().size() + 1);
}
}