From fff0d5e52956dcf773dec69033a482539d0d9b69 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Fri, 24 Feb 2012 14:06:27 +0000 Subject: [PATCH] [#1157] Add SQL / JDBC tracing capabilities in addition to logging - Added integration tests for using ExecuteListener with BatchSingle --- .../_/testcases/ExecuteListenerTests.java | 213 ++++++++++++++++++ .../src/org/jooq/test/jOOQAbstractTest.java | 12 + .../main/java/org/jooq/ExecuteContext.java | 8 +- .../main/java/org/jooq/impl/BatchSingle.java | 2 +- .../org/jooq/impl/DefaultExecuteContext.java | 12 + 5 files changed, 240 insertions(+), 7 deletions(-) diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/ExecuteListenerTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/ExecuteListenerTests.java index 98376ebd52..65ad1e0f9c 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/ExecuteListenerTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/ExecuteListenerTests.java @@ -40,6 +40,8 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; +import static org.jooq.impl.Factory.param; import static org.jooq.impl.Factory.val; import java.util.ArrayList; @@ -401,4 +403,215 @@ extends BaseTest bindStart = new ArrayList(); + public static List bindEnd = new ArrayList(); + public static int executeStart; + public static int executeEnd; + public static int end; + + public static Queue ids = new LinkedList(asList(1, 2)); + + @SuppressWarnings("serial") + private void checkBase(ExecuteContext ctx) { + assertNull(ctx.query()); + assertNotNull(ctx.batchQueries()); + assertTrue(ctx.batchQueries()[0].toString().contains("insert")); + assertEquals(1, ctx.batchSQL().length); + + assertEquals("Bar", ctx.getData("Foo")); + assertEquals("Baz", ctx.getData("Bar")); + assertEquals(new HashMap() {{ + put("Foo", "Bar"); + put("Bar", "Baz"); + }}, ctx.getData()); + + assertNull(ctx.routine()); + assertNull(ctx.resultSet()); + assertNull(ctx.record()); + assertNull(ctx.result()); + + assertEquals(ExecuteType.BATCH, ctx.type()); + } + + private void checkSQL(ExecuteContext ctx, boolean patched) { + assertTrue(ctx.batchSQL()[0].contains("insert")); + + if (patched) { + assertTrue(ctx.batchSQL()[0].contains("values (")); + } + } + + @SuppressWarnings("unused") + private void checkStatement(ExecuteContext ctx, boolean patched) { + assertNotNull(ctx.statement()); + } + + @Override + public void start(ExecuteContext ctx) { + start = ++callbackCount; + checkBase(ctx); + + assertNull(ctx.batchSQL()[0]); + assertNull(ctx.sql()); + assertNull(ctx.statement()); + } + + @Override + public void renderStart(ExecuteContext ctx) { + renderStart = ++callbackCount; + checkBase(ctx); + + assertNull(ctx.batchSQL()[0]); + assertNull(ctx.sql()); + assertNull(ctx.statement()); + } + + @Override + public void renderEnd(ExecuteContext ctx) { + renderEnd = ++callbackCount; + checkBase(ctx); + checkSQL(ctx, false); + + assertNull(ctx.statement()); + + ctx.sql(ctx.sql().replaceFirst("values\\s+", "values ")); + checkSQL(ctx, true); + } + + @Override + public void prepareStart(ExecuteContext ctx) { + prepareStart = ++callbackCount; + checkBase(ctx); + checkSQL(ctx, true); + + assertNull(ctx.statement()); + } + + @Override + public void prepareEnd(ExecuteContext ctx) { + prepareEnd = ++callbackCount; + checkBase(ctx); + checkSQL(ctx, true); + + checkStatement(ctx, false); + // TODO Patch statement + checkStatement(ctx, true); + } + + @Override + public void bindStart(ExecuteContext ctx) { + bindStart.add(++callbackCount); + checkBase(ctx); + checkSQL(ctx, true); + checkStatement(ctx, true); + } + + @Override + public void bindEnd(ExecuteContext ctx) { + bindEnd.add(++callbackCount); + checkBase(ctx); + checkSQL(ctx, true); + checkStatement(ctx, true); + } + + @Override + public void executeStart(ExecuteContext ctx) { + executeStart = ++callbackCount; + checkBase(ctx); + checkSQL(ctx, true); + checkStatement(ctx, true); + } + + @Override + public void executeEnd(ExecuteContext ctx) { + executeEnd = ++callbackCount; + checkBase(ctx); + checkSQL(ctx, true); + checkStatement(ctx, true); + } + + @Override + public void fetchStart(ExecuteContext ctx) { + fail(); + } + + @Override + public void resultStart(ExecuteContext ctx) { + fail(); + } + + @Override + public void recordStart(ExecuteContext ctx) { + fail(); + } + + @Override + public void recordEnd(ExecuteContext ctx) { + fail(); + } + + @Override + public void resultEnd(ExecuteContext ctx) { + fail(); + } + + @Override + public void fetchEnd(ExecuteContext ctx) { + fail(); + } + + @Override + public void end(ExecuteContext ctx) { + end = ++callbackCount; + checkBase(ctx); + checkSQL(ctx, true); + checkStatement(ctx, true); + } + } } diff --git a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java index 77667fb209..78cf931d29 100644 --- a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java +++ b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java @@ -382,9 +382,16 @@ public abstract class jOOQAbstractTest< log.info("TEST STATISTICS"); log.info("---------------"); + int total = 0; for (ExecuteType type : ExecuteType.values()) { + Integer count = TestStatisticsListener.STATISTICS.get(type); + if (count != null) total += count; + log.info(type.name(), TestStatisticsListener.STATISTICS.get(type) + " executions"); } + + log.info("---------------"); + log.info("Total", total); } public final Connection getConnection() { @@ -1342,6 +1349,11 @@ public abstract class jOOQAbstractTest< new ExecuteListenerTests(this).testExecuteListenerOnResultQuery(); } + @Test + public void testExecuteListenerOnBatchSingle() throws Exception { + new ExecuteListenerTests(this).testExecuteListenerOnBatchSingle(); + } + @Test public void testLoader() throws Exception { new LoaderTests(this).testLoader(); diff --git a/jOOQ/src/main/java/org/jooq/ExecuteContext.java b/jOOQ/src/main/java/org/jooq/ExecuteContext.java index 6470dda46b..c324b43df3 100644 --- a/jOOQ/src/main/java/org/jooq/ExecuteContext.java +++ b/jOOQ/src/main/java/org/jooq/ExecuteContext.java @@ -65,12 +65,8 @@ public interface ExecuteContext extends Configuration { /** * The jOOQ {@link Query} that is being executed or null if the - * query is unknown or if there was no jOOQ Query - *

- * If {@link #batchQueries()} returns several Query objects, - * this will always return the currently rendered / prepared - * Query, or null, if no Query is - * currently being rendered / prepared + * query is unknown, if it is a batch query, or if there was no jOOQ + * Query * * @see #routine() * @see #batchQueries() diff --git a/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java b/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java index 70f790a1a5..12dca5596c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java +++ b/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java @@ -70,7 +70,7 @@ class BatchSingle implements BatchBindStep { public final int[] execute() { Connection connection = create.getConnection(); - ExecuteContext ctx = new DefaultExecuteContext(create, query); + ExecuteContext ctx = new DefaultExecuteContext(create, new Query[] { query }); ExecuteListener listener = new ExecuteListeners(ctx); try { diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultExecuteContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultExecuteContext.java index c5ea6fd51e..e946d0b9c6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultExecuteContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultExecuteContext.java @@ -114,12 +114,23 @@ class DefaultExecuteContext extends AbstractConfiguration implements ExecuteCont @Override public final ExecuteType type() { + + // This can only be a routine if (routine != null) { return ExecuteType.ROUTINE; } + + // This can only be a BatchSingle execution + else if (batchQueries.length == 1 && query == null) { + return ExecuteType.BATCH; + } + + // This can only be a BatchMultiple execution else if (batchQueries.length > 1) { return ExecuteType.BATCH; } + + // Any other type of query else if (query != null) { if (query instanceof ResultQuery) { return ExecuteType.READ; @@ -136,6 +147,7 @@ class DefaultExecuteContext extends AbstractConfiguration implements ExecuteCont } } + // No query available return ExecuteType.OTHER; }