/* 
 * 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;

/**
 * An interface for the custom mapping of an SQL <i>User Defined Type</i> (UDT)
 * to a Java class. The Java class object is added to the connection's type map
 * paired with the SQL name of the corresponding UDT.
 * <p>
 * Usually within an implementation of {@code SQLData}, there is a corresponding
 * field for every attribute of an SQL type, but only one field, if the type is
 * SQL {@code DISTINCT}. When the UDT is returned within a {@code ResultSet}, it
 * is accessed with the {@link ResultSet#getObject} method and is returned as an
 * object which is an instance of the class defined by the {@code SQLData}
 * mapping. The application can use this object just like any other Java object
 * and can store changes back into the database using the
 * {@link PreparedStatement#setObject} method which performs the reverse mapping
 * into the SQL {@code UDT}.
 * </p>
 * Normally the implementation of a custom mapping is generated by
 * a tool requiring the name of the SQL {@code UDT}, the name
 * of the class which it is going to be mapped to, and the field names to which
 * the UDT attributes are mapped. The tool can then implement the {@code
 * SQLData}, {@code readSQL}, and {@code writeSQL} methods. {@code readSQL} reads
 * attributes from an {@code SQLInput} object, and {@code writeSQL} writes them.
 * This is done via {@code SQLInput} and {@code SQLOutput} method calls
 * respectively.
 * <p>
 * Ordinarily an application would not call {@code SQLData} methods directly.
 * Similarly {@code SQLInput} and {@code SQLOutput} methods are not usually
 * called directly.
 * </p>
 * 
 * @since Android 1.0
 */
public interface SQLData {

    /**
     * Gets the SQL name of the <i>User Defined Type</i> (UDT) that this object
     * represents. This method, usually invoked by the JDBC driver, retrieves
     * the name of the UDT instance associated with this {@code SQLData} object.
     * 
     * @return a string with UDT type name for this object mapping, passed to
     *         {@code readSQL} when the object was created.
     * @throws SQLException
     *             if a database error occurs.
     * @since Android 1.0
     */
    public String getSQLTypeName() throws SQLException;

    /**
     * Reads data from the database into this object. This method follows these
     * steps:
     * <p>
     * <ul>
     * <li>Utilize the passed input stream to read the attributes or entries of
     * the SQL type</li>
     * <li>This is carried out by reading each entry from the input stream,
     * ordered as they are in the SQL definition.</li>
     * <li>Assign the data to the appropriate fields or elements. This is done
     * by calling the relevant reader method for the type involved (e.g. {@code
     * SQLInput.readString}, {@code SQLInputreadBigDecimal}). If the type is
     * distinct, then read its only data entry. For structured types, read every
     * entry.</li>
     * </ul>
     * </p>
     * <p>
     * The supplied input stream is typically initialized by the calling JDBC
     * driver with the type map before {@code readSQL} is called.
     * </p>
     * 
     * @param stream
     *            the {@code SQLInput} stream from which the type map data is
     *            read for the custom mapping.
     * @param typeName
     *            the SQL type name for the type which is being mapped.
     * @throws SQLException
     *             if a database error occurs.
     * @see SQLInput
     * @since Android 1.0
     */
    public void readSQL(SQLInput stream, String typeName) throws SQLException;

    /**
     * Writes the object to a supplied {@code SQLOutput} data stream, writing it
     * out as an SQL value to the data source.
     * <p>
     * This method follows the following steps:
     * <ul>
     * <li>Write each attribute of the SQL type to the output stream.</li>
     * <li>Write each item by calling a method on the output stream, in the
     * order they appear in the SQL definition of the type. Use the appropriate
     * {@code SQLOutput} methods (e.g. {@code writeInt}, {@code writeString}).
     * Write a single data element for a distinct type. For a structured type,
     * write a value for each attribute of the the SQL type.</li>
     * </ul>
     * </p>
     * 
     * @param stream
     *            the {@code SQLOutput} stream to use to write out the data for
     *            the custom mapping.
     * @throws SQLException
     *             if a database error occurs.
     * @see SQLOutput
     * @since Android 1.0
     */
    public void writeSQL(SQLOutput stream) throws SQLException;
}
