You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by th...@apache.org on 2015/04/15 16:25:26 UTC

svn commit: r1673781 - in /commons/proper/dbutils/trunk/src: main/java/org/apache/commons/dbutils/ test/java/org/apache/commons/dbutils/

Author: thecarlhall
Date: Wed Apr 15 14:25:26 2015
New Revision: 1673781

URL: http://svn.apache.org/r1673781
Log:
DBUTILS-70 Add statement configuration for setting parameters on sql statements

Added:
    commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/StatementConfiguration.java
    commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/StatementConfigurationTest.java
Modified:
    commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java
    commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/QueryRunner.java
    commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java

Modified: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java
URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java?rev=1673781&r1=1673780&r2=1673781&view=diff
==============================================================================
--- commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java (original)
+++ commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/AbstractQueryRunner.java Wed Apr 15 14:25:26 2015
@@ -53,10 +53,16 @@ public abstract class AbstractQueryRunne
     protected final DataSource ds;
 
     /**
-     * Default constructor, sets pmdKnownBroken to false and ds to null.
+     * Configuration to use when preparing statements.
+     */
+    private final StatementConfiguration stmtConfig;
+
+    /**
+     * Default constructor, sets pmdKnownBroken to false, ds to null and stmtConfig to null.
      */
     public AbstractQueryRunner() {
         ds = null;
+        this.stmtConfig = null;
     }
 
     /**
@@ -72,6 +78,7 @@ public abstract class AbstractQueryRunne
     public AbstractQueryRunner(boolean pmdKnownBroken) {
         this.pmdKnownBroken = pmdKnownBroken;
         ds = null;
+        this.stmtConfig = null;
     }
 
     /**
@@ -84,6 +91,18 @@ public abstract class AbstractQueryRunne
      */
     public AbstractQueryRunner(DataSource ds) {
         this.ds = ds;
+        this.stmtConfig = null;
+    }
+
+    /**
+     * Constructor for QueryRunner that takes a <code>StatementConfiguration</code> to configure statements when
+     * preparing them.
+     *
+     * @param stmtConfig The configuration to apply to statements when they are prepared.
+     */
+    public AbstractQueryRunner(StatementConfiguration stmtConfig) {
+        this.ds = null;
+        this.stmtConfig = stmtConfig;
     }
 
     /**
@@ -104,6 +123,38 @@ public abstract class AbstractQueryRunne
     public AbstractQueryRunner(DataSource ds, boolean pmdKnownBroken) {
         this.pmdKnownBroken = pmdKnownBroken;
         this.ds = ds;
+        this.stmtConfig = null;
+    }
+
+    /**
+     * Constructor for QueryRunner that takes a <code>DataSource</code> to use and a <code>StatementConfiguration</code>.
+     *
+     * Methods that do not take a <code>Connection</code> parameter will retrieve connections from this
+     * <code>DataSource</code>.
+     *
+     * @param ds The <code>DataSource</code> to retrieve connections from.
+     * @param stmtConfig The configuration to apply to statements when they are prepared.
+     */
+    public AbstractQueryRunner(DataSource ds, StatementConfiguration stmtConfig) {
+        this.ds = ds;
+        this.stmtConfig = stmtConfig;
+    }
+
+    /**
+     * Constructor for QueryRunner that takes a <code>DataSource</code>, a <code>StatementConfiguration</code>, and
+     * controls the use of <code>ParameterMetaData</code>.  Methods that do not take a <code>Connection</code> parameter
+     * will retrieve connections from this <code>DataSource</code>.
+     *
+     * @param ds The <code>DataSource</code> to retrieve connections from.
+     * @param pmdKnownBroken Some drivers don't support {@link java.sql.ParameterMetaData#getParameterType(int) };
+     * if <code>pmdKnownBroken</code> is set to true, we won't even try it; if false, we'll try it,
+     * and if it breaks, we'll remember not to use it again.
+     * @param stmtConfig The configuration to apply to statements when they are prepared.
+     */
+    public AbstractQueryRunner(DataSource ds, boolean pmdKnownBroken, StatementConfiguration stmtConfig) {
+        this.pmdKnownBroken = pmdKnownBroken;
+        this.ds = ds;
+        this.stmtConfig = stmtConfig;
     }
 
     /**
@@ -152,7 +203,9 @@ public abstract class AbstractQueryRunne
     protected PreparedStatement prepareStatement(Connection conn, String sql)
             throws SQLException {
 
-        return conn.prepareStatement(sql);
+        PreparedStatement ps = conn.prepareStatement(sql);
+        configureStatement(ps);
+        return ps;
     }
 
     /**
@@ -181,7 +234,34 @@ public abstract class AbstractQueryRunne
     protected PreparedStatement prepareStatement(Connection conn, String sql, int returnedKeys)
             throws SQLException {
 
-        return conn.prepareStatement(sql, returnedKeys);
+        PreparedStatement ps = conn.prepareStatement(sql, returnedKeys);
+        configureStatement(ps);
+        return ps;
+    }
+
+    private void configureStatement(Statement stmt) throws SQLException {
+
+        if (stmtConfig != null) {
+            if (stmtConfig.isFetchDirectionSet()) {
+                stmt.setFetchDirection(stmtConfig.getFetchDirection());
+            }
+
+            if (stmtConfig.isFetchSizeSet()) {
+                stmt.setFetchSize(stmtConfig.getFetchSize());
+            }
+
+            if (stmtConfig.isMaxFieldSizeSet()) {
+                stmt.setMaxFieldSize(stmtConfig.getMaxFieldSize());
+            }
+
+            if (stmtConfig.isMaxRowsSet()) {
+                stmt.setMaxRows(stmtConfig.getMaxRows());
+            }
+
+            if (stmtConfig.isQueryTimeoutSet()) {
+                stmt.setQueryTimeout(stmtConfig.getQueryTimeout());
+            }
+        }
     }
 
     /**

Modified: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/QueryRunner.java
URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/QueryRunner.java?rev=1673781&r1=1673780&r2=1673781&view=diff
==============================================================================
--- commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/QueryRunner.java (original)
+++ commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/QueryRunner.java Wed Apr 15 14:25:26 2015
@@ -63,6 +63,16 @@ public class QueryRunner extends Abstrac
     }
 
     /**
+     * Constructor for QueryRunner that takes a <code>StatementConfiguration</code> to configure statements when
+     * preparing them.
+     *
+     * @param stmtConfig The configuration to apply to statements when they are prepared.
+     */
+    public QueryRunner(StatementConfiguration stmtConfig) {
+        super(stmtConfig);
+    }
+
+    /**
      * Constructor for QueryRunner that takes a <code>DataSource</code> and controls the use of <code>ParameterMetaData</code>.
      * Methods that do not take a <code>Connection</code> parameter will retrieve connections from this
      * <code>DataSource</code>.
@@ -77,6 +87,34 @@ public class QueryRunner extends Abstrac
     }
 
     /**
+     * Constructor for QueryRunner that takes a <code>DataSource</code> to use and a <code>StatementConfiguration</code>.
+     *
+     * Methods that do not take a <code>Connection</code> parameter will retrieve connections from this
+     * <code>DataSource</code>.
+     *
+     * @param ds The <code>DataSource</code> to retrieve connections from.
+     * @param stmtConfig The configuration to apply to statements when they are prepared.
+     */
+    public QueryRunner(DataSource ds, StatementConfiguration stmtConfig) {
+        super(ds, stmtConfig);
+    }
+
+    /**
+     * Constructor for QueryRunner that takes a <code>DataSource</code>, a <code>StatementConfiguration</code>, and
+     * controls the use of <code>ParameterMetaData</code>.  Methods that do not take a <code>Connection</code> parameter
+     * will retrieve connections from this <code>DataSource</code>.
+     *
+     * @param ds The <code>DataSource</code> to retrieve connections from.
+     * @param pmdKnownBroken Some drivers don't support {@link java.sql.ParameterMetaData#getParameterType(int) };
+     * if <code>pmdKnownBroken</code> is set to true, we won't even try it; if false, we'll try it,
+     * and if it breaks, we'll remember not to use it again.
+     * @param stmtConfig The configuration to apply to statements when they are prepared.
+     */
+    public QueryRunner(DataSource ds, boolean pmdKnownBroken, StatementConfiguration stmtConfig) {
+        super(ds, pmdKnownBroken, stmtConfig);
+    }
+
+    /**
      * Execute a batch of SQL INSERT, UPDATE, or DELETE queries.
      *
      * @param conn The Connection to use to run the query.  The caller is

Added: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/StatementConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/StatementConfiguration.java?rev=1673781&view=auto
==============================================================================
--- commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/StatementConfiguration.java (added)
+++ commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/StatementConfiguration.java Wed Apr 15 14:25:26 2015
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.dbutils;
+
+/**
+ * Configuration options for a {@link java.sql.Statement} when preparing statements in <code>QueryRunner</code>.
+ */
+public class StatementConfiguration {
+    private final Integer fetchDirection;
+    private final Integer fetchSize;
+    private final Integer maxFieldSize;
+    private final Integer maxRows;
+    private final Integer queryTimeout;
+
+    /**
+     * Constructor for <code>StatementConfiguration</code>.  For more flexibility, use {@link Builder}.
+     *
+     * @param fetchDirection The direction for fetching rows from database tables.
+     * @param fetchSize The number of rows that should be fetched from the database when more rows are needed.
+     * @param maxFieldSize The maximum number of bytes that can be returned for character and binary column values.
+     * @param maxRows The maximum number of rows that a <code>ResultSet</code> can produce.
+     * @param queryTimeout The number of seconds the driver will wait for execution.
+     */
+    public StatementConfiguration(Integer fetchDirection, Integer fetchSize, Integer maxFieldSize, Integer maxRows,
+                                  Integer queryTimeout) {
+        this.fetchDirection = fetchDirection;
+        this.fetchSize = fetchSize;
+        this.maxFieldSize = maxFieldSize;
+        this.maxRows = maxRows;
+        this.queryTimeout = queryTimeout;
+    }
+
+    /**
+     * Get the fetch direction.
+     *
+     * @return The direction to fetch or null if not set.
+     */
+    public Integer getFetchDirection() {
+        return fetchDirection;
+    }
+
+    /**
+     * Whether fetch direction is set.
+     *
+     * @return true if set, false otherwise.
+     */
+    public boolean isFetchDirectionSet() {
+        return fetchDirection != null;
+    }
+
+    /**
+     * Get the fetch size.
+     *
+     * @return The fetch size or null if not set.
+     */
+    public Integer getFetchSize() {
+        return fetchSize;
+    }
+
+    /**
+     * Whether fetch size is set.
+     *
+     * @return true if set, false otherwise.
+     */
+    public boolean isFetchSizeSet() {
+        return fetchSize != null;
+    }
+
+    /**
+     * Get the max field size.
+     *
+     * @return The max field size or null if not set.
+     */
+    public Integer getMaxFieldSize() {
+        return maxFieldSize;
+    }
+
+    /**
+     * Whether max field size is set.
+     *
+     * @return true if set, false otherwise.
+     */
+    public boolean isMaxFieldSizeSet() {
+        return maxFieldSize != null;
+    }
+
+    /**
+     * Get the max rows.
+     *
+     * @return The max rows or null if not set.
+     */
+    public Integer getMaxRows() {
+        return maxRows;
+    }
+
+    /**
+     * Whether max rows is set.
+     *
+     * @return true if set, false otherwise.
+     */
+    public boolean isMaxRowsSet() {
+        return maxRows != null;
+    }
+
+    /**
+     * Get the query timeout.
+     *
+     * @return The query timeout or null if not set.
+     */
+    public Integer getQueryTimeout() {
+        return queryTimeout;
+    }
+
+    /**
+     * Whether query timeout is set.
+     *
+     * @return true if set, false otherwise.
+     */
+    public boolean isQueryTimeoutSet() {
+        return queryTimeout != null;
+    }
+
+    /**
+     * Builder class for <code>StatementConfiguration</code> for more flexible construction.
+     */
+    public static final class Builder {
+        private Integer fetchDirection;
+        private Integer fetchSize;
+        private Integer maxRows;
+        private Integer queryTimeout;
+        private Integer maxFieldSize;
+
+        public Builder fetchDirection(final Integer fetchDirection) {
+            this.fetchDirection = fetchDirection;
+            return this;
+        }
+
+        public Builder fetchSize(final Integer fetchSize) {
+            this.fetchSize = fetchSize;
+            return this;
+        }
+
+        public Builder maxRows(final Integer maxRows) {
+            this.maxRows = maxRows;
+            return this;
+        }
+
+        public Builder queryTimeout(final Integer queryTimeout) {
+            this.queryTimeout = queryTimeout;
+            return this;
+        }
+
+        public Builder maxFieldSize(final Integer maxFieldSize) {
+            this.maxFieldSize = maxFieldSize;
+            return this;
+        }
+
+        public StatementConfiguration build() {
+            return new StatementConfiguration(fetchDirection, fetchSize, maxFieldSize, maxRows, queryTimeout);
+        }
+    }
+}

Modified: commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java
URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java?rev=1673781&r1=1673780&r2=1673781&view=diff
==============================================================================
--- commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java (original)
+++ commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/QueryRunnerTest.java Wed Apr 15 14:25:26 2015
@@ -519,6 +519,19 @@ public class QueryRunnerTest {
         callUpdateWithException("unit", "test");
     }
 
+    @Test
+    public void testStatementConfiguration() throws Exception {
+        StatementConfiguration stmtConfig = new StatementConfiguration(1, 2, 3, 4, 5);
+        QueryRunner queryRunner = new QueryRunner(stmtConfig);
+        queryRunner.prepareStatement(conn, "select 1");
+
+        verify(stmt).setFetchDirection(eq(1));
+        verify(stmt).setFetchSize(eq(2));
+        verify(stmt).setMaxFieldSize(eq(3));
+        verify(stmt).setMaxRows(eq(4));
+        verify(stmt).setQueryTimeout(eq(5));
+    }
+
     //
     // Random tests
     //

Added: commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/StatementConfigurationTest.java
URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/StatementConfigurationTest.java?rev=1673781&view=auto
==============================================================================
--- commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/StatementConfigurationTest.java (added)
+++ commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/StatementConfigurationTest.java Wed Apr 15 14:25:26 2015
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.dbutils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+
+public class StatementConfigurationTest {
+    /**
+     * Test that an empty builder yields null values for all configuration settings.
+     */
+    @Test
+    public void testEmptyBuilder() {
+        StatementConfiguration config = new StatementConfiguration.Builder().build();
+
+        assertNull(config.getFetchDirection());
+        assertNull(config.getFetchSize());
+        assertNull(config.getMaxFieldSize());
+        assertNull(config.getMaxRows());
+        assertNull(config.getQueryTimeout());
+    }
+
+    /**
+     * Test that a builder with all values set yields like values in the constructed configuration.
+     */
+    @Test
+    public void testBuilder() {
+        StatementConfiguration.Builder builder = new StatementConfiguration.Builder()
+                .fetchDirection(1)
+                .fetchSize(2)
+                .maxFieldSize(3)
+                .maxRows(4)
+                .queryTimeout(5);
+        StatementConfiguration config = builder.build();
+
+        assertEquals(Integer.valueOf(1), config.getFetchDirection());
+        assertEquals(Integer.valueOf(2), config.getFetchSize());
+        assertEquals(Integer.valueOf(3), config.getMaxFieldSize());
+        assertEquals(Integer.valueOf(4), config.getMaxRows());
+        assertEquals(Integer.valueOf(5), config.getQueryTimeout());
+    }
+
+    /**
+     * Test that the constructor of <code>StatementConfiguration</code> correctly sets all values.
+     */
+    @Test
+    public void testConstructor() {
+        StatementConfiguration config = new StatementConfiguration(1, 2, 3, 4, 5);
+
+        assertEquals(Integer.valueOf(1), config.getFetchDirection());
+        assertEquals(Integer.valueOf(2), config.getFetchSize());
+        assertEquals(Integer.valueOf(3), config.getMaxFieldSize());
+        assertEquals(Integer.valueOf(4), config.getMaxRows());
+        assertEquals(Integer.valueOf(5), config.getQueryTimeout());
+    }
+}