/*
 * 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.
 */
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.
     */
    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>
     * The supplied input stream is typically initialized by the calling JDBC
     * driver with the type map before {@code readSQL} is called.
     *
     * @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
     */
    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>
     *
     * @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
     */
    public void writeSQL(SQLOutput stream) throws SQLException;
}
