/** * * Copyright (c) 2006-2017, Speedment, Inc. All Rights Reserved. * * Licensed 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 com.speedment.runtime.core.db; import com.speedment.runtime.config.Dbms; import com.speedment.runtime.core.internal.manager.sql.SqlInsertStatement; import com.speedment.runtime.core.stream.parallel.ParallelStrategy; import com.speedment.runtime.field.Field; import java.sql.*; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.function.Consumer; import java.util.stream.Stream; /** * A DbmsOperationHandler provides the interface between Speedment and an * underlying {@link Dbms} for when running queries. * * @author Per Minborg * @author Emil Forslund * @since 2.0.0 */ public interface DbmsOperationHandler { /** * Eagerly executes a SQL query and subsequently maps each row in the * ResultSet using a provided mapper and return a Stream of the mapped * objects. The ResultSet is eagerly consumed so that all elements in the * ResultSet are read before the Stream produces any objects. If no objects * are present or if an SQLException is thrown internally, an {@code empty} * stream is returned. * * @param <T> the type of the objects in the stream to return * @param dbms the dbms to send it to * @param sql the SQL command to execute * @param rsMapper the mapper to use when iterating over the ResultSet * @return a stream of the mapped objects */ default <T> Stream<T> executeQuery( Dbms dbms, String sql, SqlFunction<ResultSet, T> rsMapper) { return executeQuery(dbms, sql, Collections.emptyList(), rsMapper); } /** * Eagerly executes a SQL query and subsequently maps each row in the * {@link ResultSet} using a provided mapper and return a stream of the * mapped objects. The {@code ResultSet} is eagerly consumed. If no objects * are present or if an {@link SQLException} is thrown internally, an * {@code empty} stream is returned. * * @param <T> the type of the objects in the stream to return * @param dbms the dbms to send it to * @param sql the non-null SQL command to execute * @param values non-null values to use for "?" parameters in the sql * command * @param rsMapper the non-null mapper to use when iterating over the * {@link ResultSet} * @return a stream of the mapped objects */ <T> Stream<T> executeQuery( Dbms dbms, String sql, List<?> values, SqlFunction<ResultSet, T> rsMapper ); /** * Lazily Executes a SQL query and subsequently maps each row in the * {@link ResultSet} using a provided mapper and return a stream of the * mapped objects. The {@code ResultSet} is lazily consumed so that the * stream will consume the {@code ResultSet} as the objects are consumed. If * no objects are present, an {@code empty} stream is returned. * * @param <T> the type of the objects in the Stream to return * @param dbms the dbms to send it to * @param sql the non-null SQL command to execute * @param values non-null List of objects to use for "?" parameters in the * SQL command * @param rsMapper the non-null mapper to use when iterating over the * {@link ResultSet} * @param parallelStrategy strategy to use if constructing a parallel stream * @return a stream of the mapped objects */ <T> AsynchronousQueryResult<T> executeQueryAsync( Dbms dbms, String sql, List<?> values, SqlFunction<ResultSet, T> rsMapper, ParallelStrategy parallelStrategy ); /** * Executes an SQL update command. Generated key(s) following an insert * command (if any) will be feed to the provided Consumer. * * @param <ENTITY> the type of the entity from which the fields come * * @param dbms the dbms to send it to * @param sql the non-null SQL command to execute * @param values a non-null list * @param generatedKeyFields list of the generated fields * @param generatedKeyConsumer non-null List of objects to use for "?" * parameters in the SQL command * @throws SQLException if an error occurs */ <ENTITY> void executeInsert( Dbms dbms, String sql, List<?> values, Collection<Field<ENTITY>> generatedKeyFields, Consumer<List<Long>> generatedKeyConsumer ) throws SQLException; /** * Executes an SQL update command. Generated key(s) following an insert * command (if any) will be feed to the provided Consumer. * * @param dbms the dbms to send it to * @param sql the non-null SQL command to execute * @param values a non-null list * @throws SQLException if an error occurs */ void executeUpdate(Dbms dbms, String sql, List<?> values) throws SQLException; /** * Executes an SQL delete command. Generated key(s) following an insert * command (if any) will be feed to the provided Consumer. * * @param dbms the dbms to send it to * @param sql the non-null SQL command to execute * @param values a non-null list * @throws SQLException if an error occurs */ void executeDelete(Dbms dbms, String sql, List<?> values) throws SQLException; /** * Constructs an object that implements the <code>Clob</code> interface. The * object returned initially contains no data. The * <code>setAsciiStream</code>, <code>setCharacterStream</code> and * <code>setString</code> methods of the <code>Clob</code> interface may be * used to add data to the <code>Clob</code>. * * @param dbms the database to create it for * @return An object that implements the <code>Clob</code> interface * @throws SQLException if an object that implements the <code>Clob</code> * interface can not be constructed, this method is called on a closed * connection or a database access error occurs. * @exception SQLFeatureNotSupportedException if the JDBC driver does not * support this data type * * @since 2.3.2 */ Clob createClob(Dbms dbms) throws SQLException; /** * Constructs an object that implements the <code>Blob</code> interface. The * object returned initially contains no data. The * <code>setBinaryStream</code> and <code>setBytes</code> methods of the * <code>Blob</code> interface may be used to add data to the * <code>Blob</code>. * * @param dbms the database to create it for * @return An object that implements the <code>Blob</code> interface * @throws SQLException if an object that implements the <code>Blob</code> * interface can not be constructed, this method is called on a closed * connection or a database access error occurs. * @exception SQLFeatureNotSupportedException if the JDBC driver does not * support this data type * * @since 2.3.2 */ Blob createBlob(Dbms dbms) throws SQLException; /** * Constructs an object that implements the <code>NClob</code> interface. * The object returned initially contains no data. The * <code>setAsciiStream</code>, <code>setCharacterStream</code> and * <code>setString</code> methods of the <code>NClob</code> interface may be * used to add data to the <code>NClob</code>. * * @param dbms the database to create it for * @return An object that implements the <code>NClob</code> interface * @throws SQLException if an object that implements the <code>NClob</code> * interface can not be constructed, this method is called on a closed * connection or a database access error occurs. * @exception SQLFeatureNotSupportedException if the JDBC driver does not * support this data type * * @since 2.3.2 */ NClob createNClob(Dbms dbms) throws SQLException; /** * Constructs an object that implements the <code>SQLXML</code> interface. * The object returned initially contains no data. The * <code>createXmlStreamWriter</code> object and <code>setString</code> * method of the <code>SQLXML</code> interface may be used to add data to * the <code>SQLXML</code> object. * * @param dbms the database to create it for * @return An object that implements the <code>SQLXML</code> interface * @throws SQLException if an object that implements the <code>SQLXML</code> * interface can not be constructed, this method is called on a closed * connection or a database access error occurs. * @exception SQLFeatureNotSupportedException if the JDBC driver does not * support this data type * * @since 2.3.2 */ SQLXML createSQLXML(Dbms dbms) throws SQLException; /** * Factory method for creating Array objects. * <p> * <b>Note: </b>When <code>createArrayOf</code> is used to create an array * object that maps to a primitive data type, then it is * implementation-defined whether the <code>Array</code> object is an array * of that primitive data type or an array of <code>Object</code>. * <p> * <b>Note: </b>The JDBC driver is responsible for mapping the elements * <code>Object</code> array to the default JDBC SQL type defined in * java.sql.Types for the given class of <code>Object</code>. The default * mapping is specified in Appendix B of the JDBC specification. If the * resulting JDBC type is not the appropriate type for the given typeName * then it is implementation defined whether an <code>SQLException</code> is * thrown or the driver supports the resulting conversion. * * @param dbms the database to create it for * @param typeName the SQL name of the type the elements of the array map * to. The typeName is a database-specific name which may be the name of a * built-in type, a user-defined type or a standard SQL type supported by * this database. This is the value returned by * <code>Array.getBaseTypeName</code> * @param elements the elements that populate the returned object * @return an Array object whose elements map to the specified SQL type * @throws SQLException if a database error occurs, the JDBC type is not * appropriate for the typeName and the conversion is not supported, the * typeName is null or this method is called on a closed connection * @throws SQLFeatureNotSupportedException if the JDBC driver does not * support this data type * * @since 2.3.2 */ Array createArray(Dbms dbms, String typeName, Object[] elements) throws SQLException; /** * Factory method for creating Struct objects. * * @param dbms the database to create it for * @param typeName the SQL type name of the SQL structured type that this * <code>Struct</code> object maps to. The typeName is the name of a * user-defined type that has been defined for this database. It is the * value returned by <code>Struct.getSQLTypeName</code>. * @param attributes the attributes that populate the returned object * @return a Struct object that maps to the given SQL type and is populated * with the given attributes * @throws SQLException if a database error occurs, the typeName is null or * this method is called on a closed connection * @throws SQLFeatureNotSupportedException if the JDBC driver does not * support this data type * * @since 2.3.2 */ Struct createStruct(Dbms dbms, String typeName, Object[] attributes) throws SQLException; /** * Configures a select statement for optimum read performance. This is * necessary for some database types such as MySQL or else large ResutlSets * may consume the entire heap. * * @param statement to configure * @throws java.sql.SQLException if the configuration fails */ default void configureSelect(PreparedStatement statement) throws SQLException { // Do nothing by default } /** * Configures a ResultSet for optimum read performance. * * @param resultSet to configure * @throws java.sql.SQLException if the configuration fails */ default void configureSelect(ResultSet resultSet) throws SQLException { // Do nothing by default } <ENTITY> void handleGeneratedKeys(PreparedStatement ps, SqlInsertStatement<ENTITY> sqlStatement) throws SQLException; }