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}