| // SPDX-License-Identifier: LGPL-2.1-or-later |
| // Copyright (c) 2012-2014 Monty Program Ab |
| // Copyright (c) 2015-2021 MariaDB Corporation Ab |
| |
| package org.mariadb.jdbc; |
| |
| import java.io.InputStream; |
| import java.io.Reader; |
| import java.math.BigDecimal; |
| import java.net.URL; |
| import java.sql.*; |
| import java.sql.Date; |
| import java.sql.ParameterMetaData; |
| import java.util.*; |
| import java.util.concurrent.locks.ReentrantLock; |
| import org.mariadb.jdbc.client.ColumnDecoder; |
| import org.mariadb.jdbc.client.util.Parameters; |
| import org.mariadb.jdbc.codec.*; |
| import org.mariadb.jdbc.export.ExceptionFactory; |
| import org.mariadb.jdbc.export.Prepare; |
| import org.mariadb.jdbc.plugin.Codec; |
| import org.mariadb.jdbc.plugin.codec.*; |
| import org.mariadb.jdbc.util.ParameterList; |
| |
| /** Common methods for prepare statement, for client and server prepare statement. */ |
| public abstract class BasePreparedStatement extends Statement implements PreparedStatement { |
| |
| /** parameters */ |
| protected Parameters parameters; |
| |
| /** batching parameters */ |
| protected List<Parameters> batchParameters; |
| |
| /** prepare statement sql command */ |
| protected final String sql; |
| |
| /** PREPARE command result */ |
| protected Prepare prepareResult = null; |
| |
| /** |
| * Constructor |
| * |
| * @param sql sql command |
| * @param con connection |
| * @param lock thread safe lock |
| * @param canUseServerTimeout indicate if server can support server timeout |
| * @param canUseServerMaxRows indicate if server can support max rows |
| * @param autoGeneratedKeys indicate if automatif generated key retrival is required |
| * @param resultSetType resultset type |
| * @param resultSetConcurrency resultset concurrency |
| * @param defaultFetchSize default fetch size |
| */ |
| public BasePreparedStatement( |
| String sql, |
| Connection con, |
| ReentrantLock lock, |
| boolean canUseServerTimeout, |
| boolean canUseServerMaxRows, |
| int autoGeneratedKeys, |
| int resultSetType, |
| int resultSetConcurrency, |
| int defaultFetchSize) { |
| super( |
| con, |
| lock, |
| canUseServerTimeout, |
| canUseServerMaxRows, |
| autoGeneratedKeys, |
| resultSetType, |
| resultSetConcurrency, |
| defaultFetchSize); |
| this.sql = sql; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuilder sb = new StringBuilder("sql:'" + sql + "'"); |
| sb.append(", parameters:["); |
| for (int i = 0; i < parameters.size(); i++) { |
| org.mariadb.jdbc.client.util.Parameter param = parameters.get(i); |
| if (param == null) { |
| sb.append("null"); |
| } else { |
| sb.append(param.bestEffortStringValue(con.getContext())); |
| } |
| if (i != parameters.size() - 1) { |
| sb.append(","); |
| } |
| } |
| sb.append("]"); |
| return sb.toString(); |
| } |
| |
| /** |
| * Set PREPARE result |
| * |
| * @param prepareResult prepare result |
| */ |
| public void setPrepareResult(Prepare prepareResult) { |
| this.prepareResult = prepareResult; |
| } |
| |
| /** |
| * Get cached metadata list |
| * |
| * @return metadata list |
| */ |
| public ColumnDecoder[] getMeta() { |
| return this.prepareResult.getColumns(); |
| } |
| |
| /** |
| * update cached metadata list |
| * |
| * @param ci metadata columns |
| */ |
| public void updateMeta(ColumnDecoder[] ci) { |
| this.prepareResult.setColumns(ci); |
| } |
| |
| public abstract boolean execute() throws SQLException; |
| |
| public abstract ResultSet executeQuery() throws SQLException; |
| |
| public abstract int executeUpdate() throws SQLException; |
| |
| public abstract long executeLargeUpdate() throws SQLException; |
| |
| public abstract void addBatch() throws SQLException; |
| |
| public abstract ResultSetMetaData getMetaData() throws SQLException; |
| |
| public abstract ParameterMetaData getParameterMetaData() throws SQLException; |
| |
| /** |
| * Set all parameters |
| * |
| * @param parameters parameters |
| */ |
| public void setParameters(Parameters parameters) { |
| this.parameters = parameters; |
| } |
| |
| /** |
| * Set parameter |
| * |
| * @param index parameter index |
| * @param param parameter |
| */ |
| public void setParameter(int index, org.mariadb.jdbc.client.util.Parameter param) { |
| parameters.set(index, param); |
| } |
| |
| @Override |
| public abstract int[] executeBatch() throws SQLException; |
| |
| @Override |
| public abstract long[] executeLargeBatch() throws SQLException; |
| |
| // *************************************************************************************************** |
| // methods inherited from Statement that are disabled |
| // *************************************************************************************************** |
| |
| @Override |
| public void addBatch(String sql) throws SQLException { |
| throw exceptionFactory().create("addBatch(String sql) cannot be called on preparedStatement"); |
| } |
| |
| @Override |
| public boolean execute(String sql) throws SQLException { |
| throw exceptionFactory().create("execute(String sql) cannot be called on preparedStatement"); |
| } |
| |
| @Override |
| public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { |
| throw exceptionFactory() |
| .create("execute(String sql, int autoGeneratedKeys) cannot be called on preparedStatement"); |
| } |
| |
| @Override |
| public boolean execute(String sql, int[] columnIndexes) throws SQLException { |
| throw exceptionFactory() |
| .create("execute(String sql, int[] columnIndexes) cannot be called on preparedStatement"); |
| } |
| |
| @Override |
| public boolean execute(String sql, String[] columnNames) throws SQLException { |
| throw exceptionFactory() |
| .create("execute(String sql, String[] columnNames) cannot be called on preparedStatement"); |
| } |
| |
| @Override |
| public ResultSet executeQuery(String sql) throws SQLException { |
| throw exceptionFactory() |
| .create("executeQuery(String sql) cannot be called on preparedStatement"); |
| } |
| |
| @Override |
| public int executeUpdate(String sql) throws SQLException { |
| throw exceptionFactory() |
| .create("executeUpdate(String sql) cannot be called on preparedStatement"); |
| } |
| |
| @Override |
| public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { |
| throw exceptionFactory() |
| .create( |
| "executeUpdate(String sql, int autoGeneratedKeys) cannot be called on" |
| + " preparedStatement"); |
| } |
| |
| @Override |
| public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { |
| throw exceptionFactory() |
| .create( |
| "executeUpdate(String sql, int[] columnIndexes) cannot be called on preparedStatement"); |
| } |
| |
| @Override |
| public int executeUpdate(String sql, String[] columnNames) throws SQLException { |
| throw exceptionFactory() |
| .create( |
| "executeUpdate(String sql, String[] columnNames) cannot be called on" |
| + " preparedStatement"); |
| } |
| |
| @Override |
| public long executeLargeUpdate(String sql) throws SQLException { |
| throw exceptionFactory() |
| .create("executeLargeUpdate(String sql) cannot be called on preparedStatement"); |
| } |
| |
| @Override |
| public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException { |
| throw exceptionFactory() |
| .create( |
| "executeLargeUpdate(String sql, int autoGeneratedKeys) cannot be called on" |
| + " preparedStatement"); |
| } |
| |
| @Override |
| public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException { |
| throw exceptionFactory() |
| .create( |
| "executeLargeUpdate(String sql, int[] columnIndexes) cannot be called on" |
| + " preparedStatement"); |
| } |
| |
| @Override |
| public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException { |
| throw exceptionFactory() |
| .create( |
| "executeLargeUpdate(String sql, String[] columnNames) cannot be called on" |
| + " preparedStatement"); |
| } |
| |
| // *************************************************************************************************** |
| // Setters |
| // *************************************************************************************************** |
| |
| private void checkIndex(int index) throws SQLException { |
| if (index <= 0) { |
| throw exceptionFactory().create(String.format("wrong parameter index %s", index)); |
| } |
| } |
| |
| /** |
| * Sets the designated parameter to SQL <code>NULL</code>. |
| * |
| * <p><B>Note:</B> You must specify the parameter's SQL type. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param sqlType the SQL type code defined in <code>java.sql.Types</code> |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if <code>sqlType</code> is a <code>ARRAY</code>, <code> |
| * BLOB</code>, <code>CLOB</code>, <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code> |
| * NCHAR</code>, <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, <code> |
| * REF</code>, <code>ROWID</code>, <code>SQLXML</code> or <code>STRUCT</code> data type and |
| * the JDBC driver does not support this data type |
| */ |
| @Override |
| public void setNull(int parameterIndex, int sqlType) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, Parameter.NULL_PARAMETER); |
| } |
| |
| /** |
| * Sets the designated parameter to the given Java <code>boolean</code> value. The driver converts |
| * this to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setBoolean(int parameterIndex, boolean x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new NonNullParameter<>(BooleanCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given Java <code>byte</code> value. The driver converts |
| * this to an SQL <code>TINYINT</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setByte(int parameterIndex, byte x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new NonNullParameter<>(ByteCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given Java <code>short</code> value. The driver converts |
| * this to an SQL <code>SMALLINT</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setShort(int parameterIndex, short x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new NonNullParameter<>(ShortCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given Java <code>int</code> value. The driver converts |
| * this to an SQL <code>INTEGER</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setInt(int parameterIndex, int x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new NonNullParameter<>(IntCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given Java <code>long</code> value. The driver converts |
| * this to an SQL <code>BIGINT</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setLong(int parameterIndex, long x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new NonNullParameter<>(LongCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given Java <code>float</code> value. The driver converts |
| * this to an SQL <code>REAL</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setFloat(int parameterIndex, float x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new NonNullParameter<>(FloatCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given Java <code>double</code> value. The driver converts |
| * this to an SQL <code>DOUBLE</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setDouble(int parameterIndex, double x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new NonNullParameter<>(DoubleCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.math.BigDecimal</code> value. The driver |
| * converts this to an SQL <code>NUMERIC</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(BigDecimalCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given Java <code>String</code> value. The driver converts |
| * this to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value (depending on the |
| * argument's size relative to the driver's limits on <code>VARCHAR</code> values) when it sends |
| * it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setString(int parameterIndex, String x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StringCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given Java array of bytes. The driver converts this to an |
| * SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code> (depending on the argument's size |
| * relative to the driver's limits on <code>VARBINARY</code> values) when it sends it to the |
| * database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setBytes(int parameterIndex, byte[] x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(ByteArrayCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.sql.Date</code> value using the default |
| * time zone of the virtual machine that is running the application. The driver converts this to |
| * an SQL <code>DATE</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setDate(int parameterIndex, Date x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(DateCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.sql.Time</code> value. The driver |
| * converts this to an SQL <code>TIME</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setTime(int parameterIndex, Time x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(TimeCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value. The driver |
| * converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(TimestampCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given input stream, which will have the specified number |
| * of bytes. When a very large ASCII value is input to a <code>LONGVARCHAR</code> parameter, it |
| * may be more practical to send it via a <code>java.io.InputStream</code>. Data will be read from |
| * the stream as needed until end-of-file is reached. The JDBC driver will do any necessary |
| * conversion from ASCII to the database char format. |
| * |
| * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own |
| * subclass that implements the standard interface. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the Java input stream that contains the ASCII parameter value |
| * @param length the number of bytes in the stream |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, (long) length)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given input stream, which will have the specified number |
| * of bytes. |
| * |
| * <p>When a very large Unicode value is input to a <code>LONGVARCHAR</code> parameter, it may be |
| * more practical to send it via a <code>java.io.InputStream</code> object. The data will be read |
| * from the stream as needed until end-of-file is reached. The JDBC driver will do any necessary |
| * conversion from Unicode to the database char format. |
| * |
| * <p>The byte format of the Unicode stream must be a Java UTF-8, as defined in the Java Virtual |
| * Machine Specification. |
| * |
| * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own |
| * subclass that implements the standard interface. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x a <code>java.io.InputStream</code> object that contains the Unicode parameter value |
| * @param length the number of bytes in the stream |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @deprecated Use {@code setCharacterStream} |
| */ |
| @Override |
| @Deprecated |
| public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, (long) length)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given input stream, which will have the specified number |
| * of bytes. When a very large binary value is input to a <code>LONGVARBINARY</code> parameter, it |
| * may be more practical to send it via a <code>java.io.InputStream</code> object. The data will |
| * be read from the stream as needed until end-of-file is reached. |
| * |
| * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own |
| * subclass that implements the standard interface. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the java input stream which contains the binary parameter value |
| * @param length the number of bytes in the stream |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| */ |
| @Override |
| public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, (long) length)); |
| } |
| |
| /** |
| * Clears the current parameter values immediately. |
| * |
| * <p>In general, parameter values remain in force for repeated use of a statement. Setting a |
| * parameter value automatically clears its previous value. However, in some cases it is useful to |
| * immediately release the resources used by the current parameter values; this can be done by |
| * calling the method <code>clearParameters</code>. |
| * |
| * @throws SQLException if a database access error occurs or this method is called on a closed |
| * <code>PreparedStatement</code> |
| */ |
| @Override |
| public void clearParameters() throws SQLException { |
| checkNotClosed(); |
| parameters = new ParameterList(); |
| } |
| |
| /** |
| * Sets the value of the designated parameter with the given object. |
| * |
| * <p>This method is similar to {@link #setObject(int parameterIndex, Object x, int targetSqlType, |
| * int scaleOrLength)}, except that it assumes a scale of zero. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the object containing the input parameter value |
| * @param targetSqlType the SQL type (as defined in java.sql.Types) to be sent to the database |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed |
| * PreparedStatement |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified |
| * targetSqlType |
| * @see Types |
| */ |
| @Override |
| public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { |
| setInternalObject(parameterIndex, x, targetSqlType, null); |
| } |
| |
| /** |
| * Sets the value of the designated parameter using the given object. |
| * |
| * <p>The JDBC specification specifies a standard mapping from Java <code>Object</code> types to |
| * SQL types. The given argument will be converted to the corresponding SQL type before being sent |
| * to the database. |
| * |
| * <p>Note that this method may be used to pass datatabase- specific abstract data types, by using |
| * a driver-specific Java type. |
| * |
| * <p>If the object is of a class implementing the interface <code>SQLData</code>, the JDBC driver |
| * should call the method <code>SQLData.writeSQL</code> to write it to the SQL data stream. If, on |
| * the other hand, the object is of a class implementing <code>Ref</code>, <code>Blob</code>, |
| * <code>Clob</code>, <code>NClob</code>, <code>Struct</code>, <code>java.net.URL</code>, <code> |
| * RowId</code>, <code>SQLXML</code> or <code>Array</code>, the driver should pass it to the |
| * database as a value of the corresponding SQL type. |
| * |
| * <p><b>Note:</b> Not all databases allow for a non-typed Null to be sent to the backend. For |
| * maximum portability, the <code>setNull</code> or the <code> |
| * setObject(int parameterIndex, Object x, int sqlType)</code> method should be used instead of |
| * <code>setObject(int parameterIndex, Object x)</code>. |
| * |
| * <p><b>Note:</b> This method throws an exception if there is an ambiguity, for example, if the |
| * object is of a class implementing more than one of the interfaces named above. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the object containing the input parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs; this method is called on a closed <code> |
| * PreparedStatement</code> or the type of the given object is ambiguous |
| */ |
| @Override |
| public void setObject(int parameterIndex, Object x) throws SQLException { |
| setInternalObject(parameterIndex, x, null, null); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>Reader</code> object, which is the given |
| * number of characters long. When a very large UNICODE value is input to a <code>LONGVARCHAR |
| * </code> parameter, it may be more practical to send it via a <code>java.io.Reader</code> |
| * object. The data will be read from the stream as needed until end-of-file is reached. The JDBC |
| * driver will do any necessary conversion from UNICODE to the database char format. |
| * |
| * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own |
| * subclass that implements the standard interface. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param reader the <code>java.io.Reader</code> object that contains the Unicode data |
| * @param length the number of characters in the stream |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @since 1.2 |
| */ |
| @Override |
| public void setCharacterStream(int parameterIndex, Reader reader, int length) |
| throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set( |
| parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader, (long) length)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>REF(<structured-type>)</code> value. The |
| * driver converts this to an SQL <code>REF</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x an SQL <code>REF</code> value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.2 |
| */ |
| @Override |
| public void setRef(int parameterIndex, Ref x) throws SQLException { |
| throw exceptionFactory().notSupported("REF parameter are not supported"); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.sql.Blob</code> object. The driver |
| * converts this to an SQL <code>BLOB</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.2 |
| */ |
| @Override |
| public void setBlob(int parameterIndex, Blob x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(BlobCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.sql.Clob</code> object. The driver |
| * converts this to an SQL <code>CLOB</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.2 |
| */ |
| @Override |
| public void setClob(int parameterIndex, Clob x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(ClobCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.sql.Array</code> object. The driver |
| * converts this to an SQL <code>ARRAY</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x an <code>Array</code> object that maps an SQL <code>ARRAY</code> value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.2 |
| */ |
| @Override |
| public void setArray(int parameterIndex, Array x) throws SQLException { |
| throw exceptionFactory().notSupported("Array parameter are not supported"); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.sql.Date</code> value, using the given |
| * <code>Calendar</code> object. The driver uses the <code>Calendar</code> object to construct an |
| * SQL <code>DATE</code> value, which the driver then sends to the database. With a <code>Calendar |
| * </code> object, the driver can calculate the date taking into account a custom timezone. If no |
| * <code>Calendar</code> object is specified, the driver uses the default timezone, which is that |
| * of the virtual machine running the application. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @param cal the <code>Calendar</code> object the driver will use to construct the date |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @since 1.2 |
| */ |
| @Override |
| public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new ParameterWithCal<>(DateCodec.INSTANCE, x, cal)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.sql.Time</code> value, using the given |
| * <code>Calendar</code> object. The driver uses the <code>Calendar</code> object to construct an |
| * SQL <code>TIME</code> value, which the driver then sends to the database. With a <code>Calendar |
| * </code> object, the driver can calculate the time taking into account a custom timezone. If no |
| * <code>Calendar</code> object is specified, the driver uses the default timezone, which is that |
| * of the virtual machine running the application. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @param cal the <code>Calendar</code> object the driver will use to construct the time |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @since 1.2 |
| */ |
| @Override |
| public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new ParameterWithCal<>(TimeCodec.INSTANCE, x, cal)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.sql.Timestamp</code> value, using the |
| * given <code>Calendar</code> object. The driver uses the <code>Calendar</code> object to |
| * construct an SQL <code>TIMESTAMP</code> value, which the driver then sends to the database. |
| * With a <code>Calendar</code> object, the driver can calculate the timestamp taking into account |
| * a custom timezone. If no <code>Calendar</code> object is specified, the driver uses the default |
| * timezone, which is that of the virtual machine running the application. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @param cal the <code>Calendar</code> object the driver will use to construct the timestamp |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @since 1.2 |
| */ |
| @Override |
| public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new ParameterWithCal<>(TimestampCodec.INSTANCE, x, cal)); |
| } |
| |
| /** |
| * Sets the designated parameter to SQL <code>NULL</code>. This version of the method <code> |
| * setNull</code> should be used for user-defined types and REF type parameters. Examples of |
| * user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and named array types. |
| * |
| * <p><B>Note:</B> To be portable, applications must give the SQL type code and the |
| * fully-qualified SQL type name when specifying a NULL user-defined or REF parameter. In the case |
| * of a user-defined type the name is the type name of the parameter itself. For a REF parameter, |
| * the name is the type name of the referenced type. If a JDBC driver does not need the type code |
| * or type name information, it may ignore it. |
| * |
| * <p>Although it is intended for user-defined and Ref parameters, this method may be used to set |
| * a null parameter of any JDBC type. If the parameter does not have a user-defined or REF type, |
| * the given typeName is ignored. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param sqlType a value from <code>java.sql.Types</code> |
| * @param typeName the fully-qualified name of an SQL user-defined type; ignored if the parameter |
| * is not a user-defined type or REF |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if <code>sqlType</code> is a <code>ARRAY</code>, <code> |
| * BLOB</code>, <code>CLOB</code>, <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code> |
| * NCHAR</code>, <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>, <code> |
| * REF</code>, <code>ROWID</code>, <code>SQLXML</code> or <code>STRUCT</code> data type and |
| * the JDBC driver does not support this data type or if the JDBC driver does not support this |
| * method |
| * @since 1.2 |
| */ |
| @Override |
| public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, Parameter.NULL_PARAMETER); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.net.URL</code> value. The driver converts |
| * this to an SQL <code>DATALINK</code> value when it sends it to the database. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the <code>java.net.URL</code> object to be set |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.4 |
| */ |
| @Override |
| public void setURL(int parameterIndex, URL x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StringCodec.INSTANCE, x.toString())); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.sql.RowId</code> object. The driver |
| * converts this to an SQL <code>ROWID</code> value when it sends it to the database |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setRowId(int parameterIndex, RowId x) throws SQLException { |
| throw exceptionFactory().notSupported("RowId parameter are not supported"); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>String</code> object. The driver converts this |
| * to an SQL <code>NCHAR</code> or <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value |
| * (depending on the argument's size relative to the driver's limits on <code>NVARCHAR</code> |
| * values) when it sends it to the database. |
| * |
| * @param parameterIndex of the first parameter is 1, the second is 2, ... |
| * @param value the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if the driver does not support national character sets; if the driver can detect |
| * that a data conversion error could occur; if a database access error occurs; or this method |
| * is called on a closed <code>PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setNString(int parameterIndex, String value) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StringCodec.INSTANCE, value)); |
| } |
| |
| /** |
| * Sets the designated parameter to a <code>Reader</code> object. The <code>Reader</code> reads |
| * the data till end-of-file is reached. The driver does the necessary conversion from Java |
| * character format to the national character set in the database. |
| * |
| * @param parameterIndex of the first parameter is 1, the second is 2, ... |
| * @param value the parameter value |
| * @param length the number of characters in the parameter data. |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if the driver does not support national character sets; if the driver can detect |
| * that a data conversion error could occur; if a database access error occurs; or this method |
| * is called on a closed <code>PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setNCharacterStream(int parameterIndex, Reader value, long length) |
| throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, value, length)); |
| } |
| |
| /** |
| * Sets the designated parameter to a <code>java.sql.NClob</code> object. The driver converts this |
| * to an SQL <code>NCLOB</code> value when it sends it to the database. |
| * |
| * @param parameterIndex of the first parameter is 1, the second is 2, ... |
| * @param value the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if the driver does not support national character sets; if the driver can detect |
| * that a data conversion error could occur; if a database access error occurs; or this method |
| * is called on a closed <code>PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setNClob(int parameterIndex, NClob value) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(ClobCodec.INSTANCE, value)); |
| } |
| |
| /** |
| * Sets the designated parameter to a <code>Reader</code> object. The reader must contain the |
| * number of characters specified by length otherwise a <code>SQLException</code> will be |
| * generated when the <code>PreparedStatement</code> is executed. This method differs from the |
| * <code>setCharacterStream (int, Reader, int)</code> method because it informs the driver that |
| * the parameter value should be sent to the server as a <code>CLOB</code>. When the <code> |
| * setCharacterStream</code> method is used, the driver may have to do extra work to determine |
| * whether the parameter data should be sent to the server as a <code>LONGVARCHAR</code> or a |
| * <code>CLOB</code> |
| * |
| * @param parameterIndex index of the first parameter is 1, the second is 2, ... |
| * @param reader An object that contains the data to set the parameter value to. |
| * @param length the number of characters in the parameter data. |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs; this method is called on a closed <code> |
| * PreparedStatement</code> or if the length specified is less than zero. |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader, length)); |
| } |
| |
| /** |
| * Sets the designated parameter to a <code>InputStream</code> object. The inputstream must |
| * contain the number of characters specified by length otherwise a <code>SQLException</code> will |
| * be generated when the <code>PreparedStatement</code> is executed. This method differs from the |
| * <code>setBinaryStream (int, InputStream, int)</code> method because it informs the driver that |
| * the parameter value should be sent to the server as a <code>BLOB</code>. When the <code> |
| * setBinaryStream</code> method is used, the driver may have to do extra work to determine |
| * whether the parameter data should be sent to the server as a <code>LONGVARBINARY</code> or a |
| * <code>BLOB</code> |
| * |
| * @param parameterIndex index of the first parameter is 1, the second is 2, ... |
| * @param inputStream An object that contains the data to set the parameter value to. |
| * @param length the number of bytes in the parameter data. |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs; this method is called on a closed <code> |
| * PreparedStatement</code>; if the length specified is less than zero or if the number of |
| * bytes in the inputstream does not match the specified length. |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setBlob(int parameterIndex, InputStream inputStream, long length) |
| throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, inputStream, length)); |
| } |
| |
| /** |
| * Sets the designated parameter to a <code>Reader</code> object. The reader must contain the |
| * number of characters specified by length otherwise a <code>SQLException</code> will be |
| * generated when the <code>PreparedStatement</code> is executed. This method differs from the |
| * <code>setCharacterStream (int, Reader, int)</code> method because it informs the driver that |
| * the parameter value should be sent to the server as a <code>NCLOB</code>. When the <code> |
| * setCharacterStream</code> method is used, the driver may have to do extra work to determine |
| * whether the parameter data should be sent to the server as a <code>LONGNVARCHAR</code> or a |
| * <code>NCLOB</code> |
| * |
| * @param parameterIndex index of the first parameter is 1, the second is 2, ... |
| * @param reader An object that contains the data to set the parameter value to. |
| * @param length the number of characters in the parameter data. |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if the length specified is less than zero; if the driver does not support |
| * national character sets; if the driver can detect that a data conversion error could occur; |
| * if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader, length)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver |
| * converts this to an SQL <code>XML</code> value when it sends it to the database. |
| * |
| * @param parameterIndex index of the first parameter is 1, the second is 2, ... |
| * @param xmlObject a <code>SQLXML</code> object that maps an SQL <code>XML</code> value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs; this method is called on a closed <code> |
| * PreparedStatement</code> or the <code>java.xml.transform.Result</code>, <code>Writer</code> |
| * or <code>OutputStream</code> has not been closed for the <code>SQLXML</code> object |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { |
| throw exceptionFactory().notSupported("SQLXML parameter are not supported"); |
| } |
| |
| private ExceptionFactory exceptionFactory() { |
| return con.getExceptionFactory().of(this); |
| } |
| |
| /** |
| * Sets the value of the designated parameter with the given object. |
| * |
| * <p>If the second argument is an <code>InputStream</code> then the stream must contain the |
| * number of bytes specified by scaleOrLength. If the second argument is a <code>Reader</code> |
| * then the reader must contain the number of characters specified by scaleOrLength. If these |
| * conditions are not true the driver will generate a <code>SQLException</code> when the prepared |
| * statement is executed. |
| * |
| * <p>The given Java object will be converted to the given targetSqlType before being sent to the |
| * database. |
| * |
| * <p>If the object has a custom mapping (is of a class implementing the interface <code>SQLData |
| * </code>), the JDBC driver should call the method <code>SQLData.writeSQL</code> to write it to |
| * the SQL data stream. If, on the other hand, the object is of a class implementing <code>Ref |
| * </code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>, <code>Struct</code>, <code> |
| * java.net.URL</code>, or <code>Array</code>, the driver should pass it to the database as a |
| * value of the corresponding SQL type. |
| * |
| * <p>Note that this method may be used to pass database-specific abstract data types. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the object containing the input parameter value |
| * @param targetSqlType the SQL type (as defined in java.sql.Types) to be sent to the database. |
| * The scale argument may further qualify this type. |
| * @param scaleOrLength for <code>java.sql.Types.DECIMAL</code> or <code> |
| * java.sql.Types.NUMERIC types</code>, this is the number of digits after the decimal point. |
| * For Java Object types <code>InputStream</code> and <code>Reader</code>, this is the length |
| * of the data in the stream or reader. For all other types, this value will be ignored. |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs; this method is called on a closed <code> |
| * PreparedStatement</code> or if the Java Object specified by x is an InputStream or Reader |
| * object and the value of the scale parameter is less than zero |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified |
| * targetSqlType |
| * @see Types |
| */ |
| @Override |
| public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) |
| throws SQLException { |
| setInternalObject(parameterIndex, x, targetSqlType, (long) scaleOrLength); |
| } |
| |
| @SuppressWarnings({"unchecked", "rawtypes"}) |
| private void setInternalObject( |
| int parameterIndex, Object obj, Integer targetSqlType, Long scaleOrLength) |
| throws SQLException { |
| checkIndex(parameterIndex); |
| if (obj == null) { |
| parameters.set(parameterIndex - 1, Parameter.NULL_PARAMETER); |
| return; |
| } |
| |
| if (targetSqlType != null) { |
| // target type is defined. |
| // in case of not corresponding data type, converting |
| switch (targetSqlType) { |
| case Types.ARRAY: |
| case Types.DATALINK: |
| case Types.JAVA_OBJECT: |
| case Types.REF: |
| case Types.ROWID: |
| case Types.SQLXML: |
| case Types.STRUCT: |
| throw exceptionFactory().notSupported("Type not supported"); |
| default: |
| break; |
| } |
| |
| if (obj instanceof String || obj instanceof Character) { |
| if (targetSqlType == Types.BLOB) { |
| throw exceptionFactory() |
| .create( |
| String.format( |
| "Cannot convert a %s to a Blob", |
| obj instanceof String ? "string" : "character")); |
| } |
| String str = obj instanceof String ? (String) obj : ((Character) obj).toString(); |
| try { |
| switch (targetSqlType) { |
| case Types.BIT: |
| case Types.BOOLEAN: |
| setBoolean(parameterIndex, !("false".equalsIgnoreCase(str) || "0".equals(str))); |
| return; |
| case Types.TINYINT: |
| setByte(parameterIndex, Byte.parseByte(str)); |
| return; |
| case Types.SMALLINT: |
| setShort(parameterIndex, Short.parseShort(str)); |
| return; |
| case Types.INTEGER: |
| setInt(parameterIndex, Integer.parseInt(str)); |
| return; |
| case Types.DOUBLE: |
| case Types.FLOAT: |
| setDouble(parameterIndex, Double.valueOf(str)); |
| return; |
| case Types.REAL: |
| setFloat(parameterIndex, Float.valueOf(str)); |
| return; |
| case Types.BIGINT: |
| setLong(parameterIndex, Long.valueOf(str)); |
| return; |
| case Types.DECIMAL: |
| case Types.NUMERIC: |
| setBigDecimal(parameterIndex, new BigDecimal(str)); |
| return; |
| case Types.CLOB: |
| case Types.NCLOB: |
| case Types.CHAR: |
| case Types.VARCHAR: |
| case Types.LONGVARCHAR: |
| case Types.NCHAR: |
| case Types.NVARCHAR: |
| case Types.LONGNVARCHAR: |
| setString(parameterIndex, str); |
| return; |
| case Types.TIMESTAMP: |
| if (str.startsWith("0000-00-00")) { |
| setTimestamp(parameterIndex, null); |
| } else { |
| setTimestamp(parameterIndex, Timestamp.valueOf(str)); |
| } |
| return; |
| case Types.TIME: |
| setTime(parameterIndex, Time.valueOf((String) obj)); |
| return; |
| default: |
| throw exceptionFactory() |
| .create(String.format("Could not convert [%s] to %s", str, targetSqlType)); |
| } |
| } catch (IllegalArgumentException e) { |
| throw exceptionFactory() |
| .create( |
| String.format("Could not convert [%s] to java.sql.Type %s", str, targetSqlType), |
| "HY000", |
| e); |
| } |
| } else if (obj instanceof Number) { |
| Number bd = (Number) obj; |
| switch (targetSqlType) { |
| case Types.TINYINT: |
| setByte(parameterIndex, bd.byteValue()); |
| return; |
| case Types.SMALLINT: |
| setShort(parameterIndex, bd.shortValue()); |
| return; |
| case Types.INTEGER: |
| setInt(parameterIndex, bd.intValue()); |
| return; |
| case Types.BIGINT: |
| setLong(parameterIndex, bd.longValue()); |
| return; |
| case Types.FLOAT: |
| case Types.DOUBLE: |
| setDouble(parameterIndex, bd.doubleValue()); |
| return; |
| case Types.REAL: |
| setFloat(parameterIndex, bd.floatValue()); |
| return; |
| case Types.DECIMAL: |
| case Types.NUMERIC: |
| if (obj instanceof BigDecimal) { |
| setBigDecimal(parameterIndex, (BigDecimal) obj); |
| } else if (obj instanceof Double || obj instanceof Float) { |
| setDouble(parameterIndex, bd.doubleValue()); |
| } else { |
| setLong(parameterIndex, bd.longValue()); |
| } |
| return; |
| case Types.BIT: |
| setBoolean(parameterIndex, bd.shortValue() != 0); |
| return; |
| case Types.CHAR: |
| case Types.VARCHAR: |
| setString(parameterIndex, bd.toString()); |
| return; |
| default: |
| throw exceptionFactory() |
| .create(String.format("Could not convert [%s] to %s", bd, targetSqlType)); |
| } |
| } else if (obj instanceof byte[]) { |
| if (targetSqlType == Types.BINARY |
| || targetSqlType == Types.VARBINARY |
| || targetSqlType == Types.LONGVARBINARY) { |
| setBytes(parameterIndex, (byte[]) obj); |
| return; |
| } else if (targetSqlType == Types.BLOB) { |
| setBlob(parameterIndex, new MariaDbBlob((byte[]) obj)); |
| } else { |
| throw exceptionFactory() |
| .create("Can only convert a byte[] to BINARY, VARBINARY, LONGVARBINARY or BLOB type"); |
| } |
| } |
| } |
| |
| // in case parameter still not set, defaulting to object type |
| for (Codec<?> codec : con.getContext().getConf().codecs()) { |
| if (codec.canEncode(obj)) { |
| Parameter p = new Parameter(codec, obj, scaleOrLength); |
| parameters.set(parameterIndex - 1, p); |
| return; |
| } |
| } |
| |
| throw new SQLException(String.format("Type %s not supported type", obj.getClass().getName())); |
| } |
| |
| /** |
| * Sets the designated parameter to the given input stream, which will have the specified number |
| * of bytes. When a very large ASCII value is input to a <code>LONGVARCHAR</code> parameter, it |
| * may be more practical to send it via a <code>java.io.InputStream</code>. Data will be read from |
| * the stream as needed until end-of-file is reached. The JDBC driver will do any necessary |
| * conversion from ASCII to the database char format. |
| * |
| * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own |
| * subclass that implements the standard interface. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the Java input stream that contains the ASCII parameter value |
| * @param length the number of bytes in the stream |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @since 1.6 |
| */ |
| @Override |
| public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, length)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given input stream, which will have the specified number |
| * of bytes. When a very large binary value is input to a <code>LONGVARBINARY</code> parameter, it |
| * may be more practical to send it via a <code>java.io.InputStream</code> object. The data will |
| * be read from the stream as needed until end-of-file is reached. |
| * |
| * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own |
| * subclass that implements the standard interface. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the java input stream which contains the binary parameter value |
| * @param length the number of bytes in the stream |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @since 1.6 |
| */ |
| @Override |
| public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x, length)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>Reader</code> object, which is the given |
| * number of characters long. When a very large UNICODE value is input to a <code>LONGVARCHAR |
| * </code> parameter, it may be more practical to send it via a <code>java.io.Reader</code> |
| * object. The data will be read from the stream as needed until end-of-file is reached. The JDBC |
| * driver will do any necessary conversion from UNICODE to the database char format. |
| * |
| * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own |
| * subclass that implements the standard interface. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param reader the <code>java.io.Reader</code> object that contains the Unicode data |
| * @param length the number of characters in the stream |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @since 1.6 |
| */ |
| @Override |
| public void setCharacterStream(int parameterIndex, Reader reader, long length) |
| throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader, length)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given input stream. When a very large ASCII value is input |
| * to a <code>LONGVARCHAR</code> parameter, it may be more practical to send it via a <code> |
| * java.io.InputStream</code>. Data will be read from the stream as needed until end-of-file is |
| * reached. The JDBC driver will do any necessary conversion from ASCII to the database char |
| * format. |
| * |
| * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own |
| * subclass that implements the standard interface. |
| * |
| * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more |
| * efficient to use a version of <code>setAsciiStream</code> which takes a length parameter. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the Java input stream that contains the ASCII parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given input stream. When a very large binary value is |
| * input to a <code>LONGVARBINARY</code> parameter, it may be more practical to send it via a |
| * <code>java.io.InputStream</code> object. The data will be read from the stream as needed until |
| * end-of-file is reached. |
| * |
| * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own |
| * subclass that implements the standard interface. |
| * |
| * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more |
| * efficient to use a version of <code>setBinaryStream</code> which takes a length parameter. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the java input stream which contains the binary parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, x)); |
| } |
| |
| /** |
| * Sets the designated parameter to the given <code>Reader</code> object. When a very large |
| * UNICODE value is input to a <code>LONGVARCHAR</code> parameter, it may be more practical to |
| * send it via a <code>java.io.Reader</code> object. The data will be read from the stream as |
| * needed until end-of-file is reached. The JDBC driver will do any necessary conversion from |
| * UNICODE to the database char format. |
| * |
| * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own |
| * subclass that implements the standard interface. |
| * |
| * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more |
| * efficient to use a version of <code>setCharacterStream</code> which takes a length parameter. |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param reader the <code>java.io.Reader</code> object that contains the Unicode data |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed <code> |
| * PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader)); |
| } |
| |
| /** |
| * Sets the designated parameter to a <code>Reader</code> object. The <code>Reader</code> reads |
| * the data till end-of-file is reached. The driver does the necessary conversion from Java |
| * character format to the national character set in the database. |
| * |
| * <p><B>Note:</B> This stream object can either be a standard Java stream object or your own |
| * subclass that implements the standard interface. |
| * |
| * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more |
| * efficient to use a version of <code>setNCharacterStream</code> which takes a length parameter. |
| * |
| * @param parameterIndex of the first parameter is 1, the second is 2, ... |
| * @param value the parameter value |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if the driver does not support national character sets; if the driver can detect |
| * that a data conversion error could occur; if a database access error occurs; or this method |
| * is called on a closed <code>PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, value)); |
| } |
| |
| /** |
| * Sets the designated parameter to a <code>Reader</code> object. This method differs from the |
| * <code>setCharacterStream (int, Reader)</code> method because it informs the driver that the |
| * parameter value should be sent to the server as a <code>CLOB</code>. When the <code> |
| * setCharacterStream</code> method is used, the driver may have to do extra work to determine |
| * whether the parameter data should be sent to the server as a <code>LONGVARCHAR</code> or a |
| * <code>CLOB</code> |
| * |
| * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more |
| * efficient to use a version of <code>setClob</code> which takes a length parameter. |
| * |
| * @param parameterIndex index of the first parameter is 1, the second is 2, ... |
| * @param reader An object that contains the data to set the parameter value to. |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs; this method is called on a closed <code> |
| * PreparedStatement</code>or if parameterIndex does not correspond to a parameter marker in |
| * the SQL statement |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setClob(int parameterIndex, Reader reader) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader)); |
| } |
| |
| /** |
| * Sets the designated parameter to a <code>InputStream</code> object. This method differs from |
| * the <code>setBinaryStream (int, InputStream)</code> method because it informs the driver that |
| * the parameter value should be sent to the server as a <code>BLOB</code>. When the <code> |
| * setBinaryStream</code> method is used, the driver may have to do extra work to determine |
| * whether the parameter data should be sent to the server as a <code>LONGVARBINARY</code> or a |
| * <code>BLOB</code> |
| * |
| * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more |
| * efficient to use a version of <code>setBlob</code> which takes a length parameter. |
| * |
| * @param parameterIndex index of the first parameter is 1, the second is 2, ... |
| * @param inputStream An object that contains the data to set the parameter value to. |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs; this method is called on a closed <code> |
| * PreparedStatement</code> or if parameterIndex does not correspond to a parameter marker in |
| * the SQL statement, |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(StreamCodec.INSTANCE, inputStream)); |
| } |
| |
| /** |
| * Sets the designated parameter to a <code>Reader</code> object. This method differs from the |
| * <code>setCharacterStream (int, Reader)</code> method because it informs the driver that the |
| * parameter value should be sent to the server as a <code>NCLOB</code>. When the <code> |
| * setCharacterStream</code> method is used, the driver may have to do extra work to determine |
| * whether the parameter data should be sent to the server as a <code>LONGNVARCHAR</code> or a |
| * <code>NCLOB</code> |
| * |
| * <p><B>Note:</B> Consult your JDBC driver documentation to determine if it might be more |
| * efficient to use a version of <code>setNClob</code> which takes a length parameter. |
| * |
| * @param parameterIndex index of the first parameter is 1, the second is 2, ... |
| * @param reader An object that contains the data to set the parameter value to. |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if the driver does not support national character sets; if the driver can detect |
| * that a data conversion error could occur; if a database access error occurs or this method |
| * is called on a closed <code>PreparedStatement</code> |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method |
| * @since 1.6 |
| */ |
| @Override |
| public void setNClob(int parameterIndex, Reader reader) throws SQLException { |
| checkIndex(parameterIndex); |
| parameters.set(parameterIndex - 1, new Parameter<>(ReaderCodec.INSTANCE, reader)); |
| } |
| |
| /** |
| * Sets the value of the designated parameter with the given object. |
| * |
| * <p>If the second argument is an {@code InputStream} then the stream must contain the number of |
| * bytes specified by scaleOrLength. If the second argument is a {@code Reader} then the reader |
| * must contain the number of characters specified by scaleOrLength. If these conditions are not |
| * true the driver will generate a {@code SQLException} when the prepared statement is executed. |
| * |
| * <p>The given Java object will be converted to the given targetSqlType before being sent to the |
| * database. |
| * |
| * <p>If the object has a custom mapping (is of a class implementing the interface {@code |
| * SQLData}), the JDBC driver should call the method {@code SQLData.writeSQL} to write it to the |
| * SQL data stream. If, on the other hand, the object is of a class implementing {@code Ref}, |
| * {@code Blob}, {@code Clob}, {@code NClob}, {@code Struct}, {@code java.net.URL}, or {@code |
| * Array}, the driver should pass it to the database as a value of the corresponding SQL type. |
| * |
| * <p>Note that this method may be used to pass database-specific abstract data types. |
| * |
| * <p>The default implementation will throw {@code SQLFeatureNotSupportedException} |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the object containing the input parameter value |
| * @param targetSqlType the SQL type to be sent to the database. The scale argument may further |
| * qualify this type. |
| * @param scaleOrLength for {@code java.sql.JDBCType.DECIMAL} or {@code java.sql.JDBCType.NUMERIC |
| * types}, this is the number of digits after the decimal point. For Java Object types {@code |
| * InputStream} and {@code Reader}, this is the length of the data in the stream or reader. |
| * For all other types, this value will be ignored. |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed {@code |
| * PreparedStatement} or if the Java Object specified by x is an InputStream or Reader object |
| * and the value of the scale parameter is less than zero |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified |
| * targetSqlType |
| * @see JDBCType |
| * @see SQLType |
| * @since 1.8 |
| */ |
| @Override |
| public void setObject(int parameterIndex, Object x, SQLType targetSqlType, int scaleOrLength) |
| throws SQLException { |
| setInternalObject( |
| parameterIndex, |
| x, |
| targetSqlType == null ? null : targetSqlType.getVendorTypeNumber(), |
| (long) scaleOrLength); |
| } |
| |
| /** |
| * Sets the value of the designated parameter with the given object. |
| * |
| * <p>This method is similar to {@link #setObject(int parameterIndex, Object x, SQLType |
| * targetSqlType, int scaleOrLength)}, except that it assumes a scale of zero. |
| * |
| * <p>The default implementation will throw {@code SQLFeatureNotSupportedException} |
| * |
| * @param parameterIndex the first parameter is 1, the second is 2, ... |
| * @param x the object containing the input parameter value |
| * @param targetSqlType the SQL type to be sent to the database |
| * @throws SQLException if parameterIndex does not correspond to a parameter marker in the SQL |
| * statement; if a database access error occurs or this method is called on a closed {@code |
| * PreparedStatement} |
| * @throws SQLFeatureNotSupportedException if the JDBC driver does not support the specified |
| * targetSqlType |
| * @see JDBCType |
| * @see SQLType |
| * @since 1.8 |
| */ |
| @Override |
| public void setObject(int parameterIndex, Object x, SQLType targetSqlType) throws SQLException { |
| setInternalObject( |
| parameterIndex, |
| x, |
| targetSqlType == null ? null : targetSqlType.getVendorTypeNumber(), |
| null); |
| } |
| } |