    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.dbutils;
    018
    019import java.time.Duration;
    020
    021/**
    022 * Configuration options for a {@link java.sql.Statement} when preparing statements in {@code QueryRunner}.
    023 */
    024public class StatementConfiguration {
    025    /**
    026     * Builder class for {@code StatementConfiguration} for more flexible construction.
    027     */
    028    public static final class Builder {
    029        private Integer fetchDirection;
    030        private Integer fetchSize;
    031        private Integer maxRows;
    032        private Duration queryTimeout;
    033        private Integer maxFieldSize;
    034
    035        /**
    036         * @return A new and configured {@link StatementConfiguration}.
    037         */
    038        public StatementConfiguration build() {
    039            return new StatementConfiguration(fetchDirection, fetchSize, maxFieldSize, maxRows, queryTimeout);
    040        }
    041
    042        /**
    043         * @param fetchDirection The direction for fetching rows from database tables.
    044         * @return This builder for chaining.
    045         * @see StatementConfiguration#getFetchDirection()
    046         */
    047        public Builder fetchDirection(final Integer fetchDirection) {
    048            this.fetchDirection = fetchDirection;
    049            return this;
    050        }
    051
    052        /**
    053         * @param fetchSize The number of rows that should be fetched from the database when more rows are needed.
    054         * @return This builder for chaining.
    055         * @see StatementConfiguration#getFetchSize()
    056         */
    057        public Builder fetchSize(final Integer fetchSize) {
    058            this.fetchSize = fetchSize;
    059            return this;
    060        }
    061
    062        /**
    063         * @param maxFieldSize The maximum number of bytes that can be returned for character and binary column values.
    064         * @return This builder for chaining.
    065         * @see StatementConfiguration#getMaxFieldSize()
    066         */
    067        public Builder maxFieldSize(final Integer maxFieldSize) {
    068            this.maxFieldSize = maxFieldSize;
    069            return this;
    070        }
    071
    072        /**
    073         * @param maxRows The maximum number of rows that a {@code ResultSet} can produce.
    074         * @return This builder for chaining.
    075         * @see StatementConfiguration#getMaxRows()
    076         */
    077        public Builder maxRows(final Integer maxRows) {
    078            this.maxRows = maxRows;
    079            return this;
    080        }
    081
    082        /**
    083         * @param queryTimeout The number of seconds the driver will wait for execution.
    084         * @return This builder for chaining.
    085         * @see StatementConfiguration#getQueryTimeoutDuration()
    086         * @since 1.8.0
    087         */
    088        public Builder queryTimeout(final Duration queryTimeout) {
    089            this.queryTimeout = queryTimeout;
    090            return this;
    091        }
    092
    093        /**
    094         * @param queryTimeout The number of seconds the driver will wait for execution.
    095         * @return This builder for chaining.
    096         * @see StatementConfiguration#getQueryTimeout()
    097         * @deprecated Use {@link #queryTimeout(Duration)}.
    098         */
    099        @Deprecated
    100        public Builder queryTimeout(final Integer queryTimeout) {
    101            this.queryTimeout = queryTimeout != null ? Duration.ofSeconds(queryTimeout) : null;
    102            return this;
    103        }
    104    }
    105
    106    private final Integer fetchDirection;
    107    private final Integer fetchSize;
    108    private final Integer maxFieldSize;
    109    private final Integer maxRows;
    110    private final Duration queryTimeout;
    111
    112    /**
    113     * Constructor for {@code StatementConfiguration}.  For more flexibility, use {@link Builder}.
    114     *
    115     * @param fetchDirection The direction for fetching rows from database tables.
    116     * @param fetchSize The number of rows that should be fetched from the database when more rows are needed.
    117     * @param maxFieldSize The maximum number of bytes that can be returned for character and binary column values.
    118     * @param maxRows The maximum number of rows that a {@code ResultSet} can produce.
    119     * @param queryTimeout The number of seconds the driver will wait for execution.
    120     * @since 1.8.0
    121     */
    122    public StatementConfiguration(final Integer fetchDirection, final Integer fetchSize,
    123                                  final Integer maxFieldSize, final Integer maxRows,
    124                                  final Duration queryTimeout) {
    125        this.fetchDirection = fetchDirection;
    126        this.fetchSize = fetchSize;
    127        this.maxFieldSize = maxFieldSize;
    128        this.maxRows = maxRows;
    129        if (queryTimeout != null && queryTimeout.getSeconds() > Integer.MAX_VALUE) {
    130            throw new IllegalArgumentException(String.format("queryTimeout overflow: %d > %,d", queryTimeout.getSeconds(), Integer.MAX_VALUE));
    131        }
    132        this.queryTimeout = queryTimeout;
    133    }
    134
    135    /**
    136     * Constructor for {@code StatementConfiguration}.  For more flexibility, use {@link Builder}.
    137     *
    138     * @param fetchDirection The direction for fetching rows from database tables.
    139     * @param fetchSize The number of rows that should be fetched from the database when more rows are needed.
    140     * @param maxFieldSize The maximum number of bytes that can be returned for character and binary column values.
    141     * @param maxRows The maximum number of rows that a {@code ResultSet} can produce.
    142     * @param queryTimeout The number of seconds the driver will wait for execution.
    143     * @deprecated Use {@link StatementConfiguration#StatementConfiguration(Integer, Integer, Integer, Integer, Duration)}.
    144     */
    145    @Deprecated
    146    public StatementConfiguration(final Integer fetchDirection, final Integer fetchSize,
    147                                  final Integer maxFieldSize, final Integer maxRows,
    148                                  final Integer queryTimeout) {
    149        this(fetchDirection, fetchSize, maxFieldSize, maxRows, Duration.ofSeconds(queryTimeout));
    150    }
    151
    152    /**
    153     * Get the fetch direction.
    154     *
    155     * @return The direction to fetch or null if not set.
    156     */
    157    public Integer getFetchDirection() {
    158        return fetchDirection;
    159    }
    160
    161    /**
    162     * Get the fetch size.
    163     *
    164     * @return The fetch size or null if not set.
    165     */
    166    public Integer getFetchSize() {
    167        return fetchSize;
    168    }
    169
    170    /**
    171     * Get the max field size.
    172     *
    173     * @return The max field size or null if not set.
    174     */
    175    public Integer getMaxFieldSize() {
    176        return maxFieldSize;
    177    }
    178
    179    /**
    180     * Get the max rows.
    181     *
    182     * @return The max rows or null if not set.
    183     */
    184    public Integer getMaxRows() {
    185        return maxRows;
    186    }
    187
    188    /**
    189     * Get the query timeout.
    190     *
    191     * @return The query timeout or null if not set.
    192     * @deprecated Use {@link #getQueryTimeoutDuration()}.
    193     */
    194    @Deprecated
    195    public Integer getQueryTimeout() {
    196        return queryTimeout != null ? (int) queryTimeout.getSeconds() : null;
    197    }
    198
    199    /**
    200     * Get the query timeout.
    201     *
    202     * @return The query timeout or null if not set.
    203     * @since 1.8.0
    204     */
    205    public Duration getQueryTimeoutDuration() {
    206        return queryTimeout;
    207    }
    208
    209    /**
    210     * Whether fetch direction is set.
    211     *
    212     * @return true if set, false otherwise.
    213     */
    214    public boolean isFetchDirectionSet() {
    215        return fetchDirection != null;
    216    }
    217
    218    /**
    219     * Whether fetch size is set.
    220     *
    221     * @return true if set, false otherwise.
    222     */
    223    public boolean isFetchSizeSet() {
    224        return fetchSize != null;
    225    }
    226
    227    /**
    228     * Whether max field size is set.
    229     *
    230     * @return true if set, false otherwise.
    231     */
    232    public boolean isMaxFieldSizeSet() {
    233        return maxFieldSize != null;
    234    }
    235
    236    /**
    237     * Whether max rows is set.
    238     *
    239     * @return true if set, false otherwise.
    240     */
    241    public boolean isMaxRowsSet() {
    242        return maxRows != null;
    243    }
    244
    245    /**
    246     * Whether query timeout is set.
    247     *
    248     * @return true if set, false otherwise.
    249     */
    250    public boolean isQueryTimeoutSet() {
    251        return queryTimeout != null;
    252    }
    253}