/* 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package java.sql;

import java.util.Calendar;
import java.net.URL;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;

/**
 * An interface for a precompiled SQL Statement.
 * <p>
 * An SQL Statement is put into a {@code PreparedStatement} and is precompiled
 * so that it can be executed efficiently multiple times.
 * </p>
 * <p>
 * Setter methods are supplied in the {@code PreparedStatement} interface for
 * the setting of {@code IN} parameters for the statement. The setter method
 * used for each {@code IN} parameter must match the parameter's type.
 * </p>
 *  
 * @since Android 1.0
 */
public interface PreparedStatement extends Statement {

    /**
     * Add a set of parameters to the {@code PreparedStatement}'s command batch.
     * 
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void addBatch() throws SQLException;

    /**
     * Clear the current parameter values.
     * <p>
     * Typically, parameter values are retained for multiple executions of the
     * {@code Statement}. Setting a parameter value replaces the previous value. This
     * method clears the values for all parameters, releasing all resources used
     * by those parameters.
     * </p>
     * 
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void clearParameters() throws SQLException;

    /**
     * Executes the SQL statement in this {@code PreparedStatement}.
     * <p>
     * A {@code PreparedStatement} may return multiple results. The execute
     * method executes the {@code PreparedStatement} and returns a flag 
     * indicating the kind of result produced by the action. The methods 
     * {@code getResultSet} or {@code getUpdateCount} are used to retrieve 
     * the first result, and the second and subsequent results are 
     * retrieved with {@code getMoreResults}.
     * </p>
     * 
     * @return {@code true} if the result of the execution is a {@code
     *         ResultSet}, {@code false} if there is no result or if the result
     *         is an update count.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public boolean execute() throws SQLException;

    /**
     * Executes the SQL query in the {@code PreparedStatement} and returns the
     * {@code ResultSet} generated by the query.
     * 
     * @return the {@code ResultSet} generated by the query, never {@code null}.
     * @throws SQLException
     *             if a database error happens or if the SQL statement does not
     *             produce a {@code ResultSet}.
     * @since Android 1.0
     */
    public ResultSet executeQuery() throws SQLException;

    /**
     * Invokes the SQL command contained within the prepared statement. This
     * must be {@code INSERT}, {@code UPDATE}, {@code DELETE}, or a command that
     * returns nothing.
     * 
     * @return the number of affected rows for {@code INSERT}, {@code UPDATE} or {@code
     *         DELETE} statements, {@code 0} for statements that return nothing.
     * @throws SQLException
     *             if a database error happens or if the SQL statement returns a
     *             {@code ResultSet}.
     * @since Android 1.0
     */
    public int executeUpdate() throws SQLException;

    /**
     * Returns a {@code ResultSetMetaData} describing the {@code
     * ResultSet} that would be produced by execution of the {@code PreparedStatement}.
     * <p>
     * It is possible to know the metadata for the {@code ResultSet} without
     * executing the {@code PreparedStatement}, because the {@code
     * PreparedStatement} is precompiled. As a result the metadata can be
     * queried ahead of time without actually executing the statement.
     * </p>
     * 
     * @return a {@code ResultSetMetaData} object with the information about the
     *         columns of the {@code ResultSet}, if the driver can return a
     *         {@code ResultSetMetaData}. {@code null} otherwise.
     * @throws SQLException
     *             if there is a database error.
     * @since Android 1.0
     */
    public ResultSetMetaData getMetaData() throws SQLException;

    /**
     * Gets information about the parameters of the {@code PreparedStatement}.
     * 
     * @return a {@code ParameterMetaData} object which holds information about
     *         the number, type, and properties of the parameters of this {@code
     *         PreparedStatement}.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public ParameterMetaData getParameterMetaData() throws SQLException;

    /**
     * Sets the value of a specified parameter to the supplied {@code Array}.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theArray
     *            a {@code java.sql.Array} giving the new value of the parameter at {@code
     *            parameterIndex}.
     * @throws SQLException
     *             if a database error happens.
     * @see Array
     * @since Android 1.0
     */
    public void setArray(int parameterIndex, Array theArray)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to the content of a supplied
     * {@code InputStream}, which has a specified number of bytes.
     * <p>
     * This is a good method for setting an SQL {@code LONVARCHAR} parameter
     * where the length of the data is large. Data is read from the {@code
     * InputStream} until end-of-file is reached or the specified number of
     * bytes is copied.
     * </p>
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theInputStream
     *            the ASCII {@code InputStream} carrying the data to which the
     *            parameter at {@code parameterIndex} is set.
     * @param length
     *            the number of bytes in the {@code InputStream} to copy to the
     *            parameter.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setAsciiStream(int parameterIndex, InputStream theInputStream,
            int length) throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code
     * java.math.BigDecimal} value.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theBigDecimal
     *            the value to which the parameter at {@code parameterIndex} is
     *            set.
     * @throws SQLException
     *             if a database error happens.
     * @see java.math.BigDecimal
     * @since Android 1.0
     */
    public void setBigDecimal(int parameterIndex, BigDecimal theBigDecimal)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to the content of a supplied
     * binary {@code InputStream}, which has a specified number of bytes.
     * <p>
     * Use this method when a large amount of data needs to be set into a
     * {@code LONGVARBINARY} parameter.
     * </p>
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theInputStream
     *            the binary {@code InputStream} carrying the data to update the
     *            parameter.
     * @param length
     *            the number of bytes in the {@code InputStream} to copy to the
     *            parameter.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setBinaryStream(int parameterIndex, InputStream theInputStream,
            int length) throws SQLException;

    /**
     * Sets the value of a specified parameter to the given {@code Blob} object.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theBlob
     *            the {@code java.sql.Blob} to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     * @see Blob
     */
    public void setBlob(int parameterIndex, Blob theBlob) throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code boolean}
     * value.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theBoolean
     *            the boolean value to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setBoolean(int parameterIndex, boolean theBoolean)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code byte} value.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theByte
     *            the byte value to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setByte(int parameterIndex, byte theByte) throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied array of bytes. The
     * array is mapped to a {@code VARBINARY} or {@code LONGVARBINARY} in the
     * database.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theBytes
     *            the array of bytes to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setBytes(int parameterIndex, byte[] theBytes)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to the character content of a
     * {@code Reader} object, with the specified length of character data.
     * <p>
     * Data is read from the {@code
     * Reader} until end-of-file is reached or the specified number of
     * characters are copied.
     * </p>
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1
     * @param reader
     *            the {@code java.io.Reader} containing the character data.
     * @param length
     *            the number of characters to be read.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setCharacterStream(int parameterIndex, Reader reader, int length)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to the given {@code Clob} object.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theClob
     *            a {@code java.sql.Clob} holding the data to which the
     *            parameter at {@code parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setClob(int parameterIndex, Clob theClob) throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code
     * java.sql.Date} value.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theDate
     *            a {@code java.sql.Date} to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setDate(int parameterIndex, Date theDate) throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code
     * java.sql.Date} value, using a supplied {@code Calendar} to map the Date.
     * The {@code Calendar} allows the application to control the timezone used
     * to compute the SQL {@code DATE} in the database - without the supplied
     * {@code Calendar}, the driver uses the default timezone of the Java
     * virtual machine.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theDate
     *            a {@code java.sql.Date} to which the parameter at {@code
     *            parameterIndex} is set.
     * @param cal
     *            a {@code Calendar} to use to construct the SQL {@code DATE}
     *            value.
     * @throws SQLException
     *             if a database error happens.
     * @see Date
     * @see java.util.Calendar
     * @since Android 1.0
     */
    public void setDate(int parameterIndex, Date theDate, Calendar cal)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code double}
     * value.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theDouble
     *            the {@code double} value to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setDouble(int parameterIndex, double theDouble)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to to a supplied {@code float}
     * value.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theFloat
     *            the {@code float} value to update the parameter.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setFloat(int parameterIndex, float theFloat)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code int} value.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theInt
     *            the {@code int} value to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setInt(int parameterIndex, int theInt) throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code long} value.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theLong
     *            the {@code long} value to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setLong(int parameterIndex, long theLong) throws SQLException;

    /**
     * Sets the value of a specified parameter to SQL {@code NULL}. Don't use
     * this version of {@code setNull} for <i>User Defined Types</i> (UDT) or
     * for REF type parameters.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param sqlType
     *            the SQL type of the parameter, as defined in {@code
     *            java.sql.Types}.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setNull(int parameterIndex, int sqlType) throws SQLException;

    /**
     * Sets the value of a specified parameter to SQL {@code NULL}. This version
     * of {@code setNull} should be used for <i>User Defined Types</i> (UDTs)
     * and also REF types. UDTs can be {@code STRUCT}, {@code DISTINCT}, {@code
     * JAVA_OBJECT} and named array types.
     * <p>
     * Applications must provide the SQL type code and also a fully qualified
     * SQL type name when supplying a {@code NULL} UDT or REF. For a UDT, the
     * type name is the type name of the parameter itself, but for a REF
     * parameter the type name is the type name of the referenced type.
     * </p>
     * 
     * @param paramIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param sqlType
     *            the SQL type of the parameter, as defined in {@code
     *            java.sql.Types}.
     * @param typeName
     *            the fully qualified name of a UDT or REF type - ignored if the
     *            parameter is not a UDT.
     * @throws SQLException
     *             if a database error happens.
     * @see Types
     * @since Android 1.0
     */
    public void setNull(int paramIndex, int sqlType, String typeName)
            throws SQLException;

    /**
     * Sets the value of a specified parameter using a supplied object.
     * <p>
     * There is a standard mapping from Java types to SQL types, defined in the
     * JDBC specification. The passed object is then transformed into the
     * appropriate SQL type, and then transferred to the database. {@code
     * setObject} can be used to pass abstract data types unique to the
     * database, by using a JDBC driver specific Java type. If the object's
     * class implements the interface {@code SQLData}, the JDBC driver calls
     * {@code SQLData.writeSQL} to write it to the SQL data stream. If the
     * object's class implements {@code Ref}, {@code Blob}, {@code Clob},
     * {@code Struct}, or {@code Array}, the driver passes it to the database as
     * a value of the corresponding SQL type.
     * </p>
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theObject
     *            the object containing the value to which the parameter at
     *            {@code parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setObject(int parameterIndex, Object theObject)
            throws SQLException;

    /**
     * Sets the value of a specified parameter using a supplied object.
     * <p>
     * The object is converted to the given {@code targetSqlType} before it is
     * sent to the database. If the object has a custom mapping (its class
     * implements the interface {@code SQLData}), the JDBC driver will call the method
     * {@code SQLData.writeSQL} to write it to the SQL data stream. If the
     * object's class implements {@code Ref}, {@code Blob}, {@code Clob},
     * {@code Struct}, or {@code Array}, the driver will pass it to the database
     * in the form of the relevant SQL type.
     * </p>
     * 
     * @param parameterIndex
     *            the parameter index, where the first parameter has index 1.
     * @param theObject
     *            the Object containing the value to which the parameter at
     *            {@code parameterIndex} is set.
     * @param targetSqlType
     *            the SQL type to send to the database, as defined in {@code
     *            java.sql.Types}.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setObject(int parameterIndex, Object theObject,
            int targetSqlType) throws SQLException;

    /**
     * Sets the value of a specified parameter using a supplied object.
     * <p>
     * The object is converted to the given {@code targetSqlType} before it is
     * sent to the database. If the object has a custom mapping (its class
     * implements the interface {@code SQLData}), the JDBC driver will call the method
     * {@code SQLData.writeSQL} to write it to the SQL data stream. If the
     * object's class implements {@code Ref}, {@code Blob}, {@code Clob},
     * {@code Struct}, or {@code Array}, the driver will pass it to the database
     * in the form of the relevant SQL type.
     * </p>
     * 
     * @param parameterIndex
     *            the parameter index, where the first parameter has index 1.
     * @param theObject
     *            the Object containing the value to which the parameter at
     *            {@code parameterIndex} is set.
     * @param targetSqlType
     *            the SQL type to send to the database, as defined in {@code
     *            java.sql.Types}.
     * @param scale
     *            the number of digits after the decimal point - only applies to
     *            the types {@code java.sql.Types.DECIMAL} and {@code
     *            java.sql.Types.NUMERIC} - ignored for all other types.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setObject(int parameterIndex, Object theObject,
            int targetSqlType, int scale) throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code
     * REF(<structured-type>)} value. This is stored as an SQL {@code REF}.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theRef
     *            a {@code java.sql.Ref} value to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @see Ref
     * @since Android 1.0
     */
    public void setRef(int parameterIndex, Ref theRef) throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code short}
     * value.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theShort
     *            a {@code short} value to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setShort(int parameterIndex, short theShort)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied string.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theString
     *            the value to which the parameter at {@code parameterIndex} is
     *            set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setString(int parameterIndex, String theString)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code
     * java.sql.Time} value.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theTime
     *            a {@code java.sql.Time} value to which the parameter at
     *            {@code parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setTime(int parameterIndex, Time theTime) throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code
     * java.sql.Time} value, using a supplied {@code Calendar}.
     * <p>
     * The driver uses the supplied {@code Calendar} to create the SQL {@code
     * TIME} value, which allows it to use a custom timezone - otherwise the
     * driver uses the default timezone of the Java virtual machine.
     * </p>
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has 
     *            index 1.
     * @param theTime
     *            a {@code java.sql.Time} value to which the parameter at
     *            {@code parameterIndex} is set.
     * @param cal
     *            a {@code Calendar} to use to construct the SQL {@code TIME}
     *            value.
     * @throws SQLException
     *             if a database error happens.
     * @see Time
     * @see java.util.Calendar
     * @since Android 1.0
     */
    public void setTime(int parameterIndex, Time theTime, Calendar cal)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied java.sql.Timestamp
     * value.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theTimestamp
     *            the java.sql.Timestamp value to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @since Android 1.0
     */
    public void setTimestamp(int parameterIndex, Timestamp theTimestamp)
            throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code
     * java.sql.Timestamp} value, using the supplied {@code Calendar}.
     * <p>
     * The driver uses the supplied {@code Calendar} to create the SQL {@code
     * TIMESTAMP} value, which allows it to use a custom timezone - otherwise
     * the driver uses the default timezone of the Java virtual machine.
     * </p>
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theTimestamp
     *            the {@code java.sql.Timestamp} value to which the parameter at
     *            {@code parameterIndex} is set.
     * @param cal
     *            a {@code Calendar} to use to construct the SQL {@code
     *            TIMESTAMP} value
     * @throws SQLException
     *             if a database error happens.
     * @see Timestamp
     * @see java.util.Calendar
     * @since Android 1.0
     */
    public void setTimestamp(int parameterIndex, Timestamp theTimestamp,
            Calendar cal) throws SQLException;

    /**
     * Sets the value of a specified parameter to the characters from a supplied
     * {@code InputStream}, with a specified number of bytes.
     * 
     * @deprecated Use {@link #setCharacterStream(int, Reader, int)}
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theInputStream
     *            the {@code InputStream} with the character data to which the
     *            parameter at {@code parameterIndex} is set.
     * @param length
     *            the number of bytes to read from the {@code InputStream}.
     * @throws SQLException
     *             if a database error happens.
     */
    @Deprecated
    public void setUnicodeStream(int parameterIndex,
            InputStream theInputStream, int length) throws SQLException;

    /**
     * Sets the value of a specified parameter to a supplied {@code
     * java.net.URL}.
     * 
     * @param parameterIndex
     *            the parameter number index, where the first parameter has
     *            index 1.
     * @param theURL
     *            the {@code URL} to which the parameter at {@code
     *            parameterIndex} is set.
     * @throws SQLException
     *             if a database error happens.
     * @see URL
     * @since Android 1.0
     */
    public void setURL(int parameterIndex, URL theURL) throws SQLException;
}
