package org.apache.torque.util;

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

import java.io.Serializable;
import java.sql.Connection;
import java.util.List;

import org.apache.torque.TorqueException;
import org.apache.torque.om.ObjectKey;
import org.apache.torque.om.mapper.RecordMapper;

/**
 * This is the base class for all Peer classes in the system.  Peer
 * classes are responsible for isolating all of the database access
 * for a specific business object.  They execute all of the SQL
 * against the database.  Over time this class has grown to include
 * utility methods which ease execution of cross-database queries and
 * the implementation of concrete Peers.
 *
 * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
 * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
 * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
 * @author <a href="mailto:stephenh@chase3000.com">Stephen Haberman</a>
 * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
 * @author <a href="mailto:vido@ldh.org">Augustin Vidovic</a>
 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
 * @version $Id: BasePeer.java 1415362 2012-11-29 20:33:52Z tfischer $
 *
 * @deprecated This class is not used any more as base class for the generated
 *             Peer classes and will be removed in a future version of Torque.
 */
@Deprecated
public abstract class BasePeer implements Serializable
{
    /**
     * Serial Version
     */
    private static final long serialVersionUID = -7702123730779032381L;

    /** The BasePeerImpl instance to delegate to. */
    private static BasePeerImpl<?> basePeerImpl;

    /**
     * Returns an instance of the implementation of the peer.
     * If no instance is currently cached, a new instance is created and cached.
     *
     * @return an instance of the implementation of the peer, not null.
     */
    @SuppressWarnings("unchecked")
    public static <T> BasePeerImpl<T> getBasePeerImpl()
    {
        BasePeerImpl<?> peerImplInstance = basePeerImpl;
        if (peerImplInstance == null)
        {
            peerImplInstance = new BasePeerImpl<T>();
            basePeerImpl = peerImplInstance;
        }
        return (BasePeerImpl<T>) peerImplInstance;
    }

    /**
     * Sets the implementation instance of this peer.
     *
     * @param basePeerImpl the implementation, or null to force creation of a
     *        new instance.
     */
    public static void setBasePeerImpl(BasePeerImpl<?> basePeerImpl)
    {
        BasePeer.basePeerImpl = basePeerImpl;
    }

    /**
     * Convenience method to create a String array of criteria keys.
     *
     * @param tableName Name of table.
     * @param columnNames A String[].
     * @return A String[].
     *
     * @deprecated This method is not used any more and will be removed in a
     *             future version of Torque.
     */
    @Deprecated
    public String[] initCriteriaKeys(
        String tableName,
        String[] columnNames)
    {
        return getBasePeerImpl().initCriteriaKeys(tableName, columnNames);
    }

    /**
     * Convenience method that uses straight JDBC to delete multiple rows.
     *
     * @param con A Connection.
     * @param table The table to delete records from.
     * @param column The column in the where clause.
     * @param value The value of the column.
     *
     * @return the number of deleted rows.
     *
     * @throws TorqueException Any exceptions caught during processing will be
     *         rethrown wrapped into a TorqueException.
     *
     * @deprecated The value is not SQL escaped.
     *             Better use doDelete(Criteria, String, Connection)
     *             for automatic escaping and more flexibility.
     *             This method will be removed in a future version of Torque.
     */
    @Deprecated
    public static int deleteAll(
        Connection con,
        String table,
        String column,
        int value)
        throws TorqueException
    {
        return getBasePeerImpl().deleteAll(con, table, column, value);
    }

    /**
     * Convenience method that uses straight JDBC to delete multiple
     * rows.  This method attempts to get the default database from
     * the pool.
     *
     * @param table The table to delete records from.
     * @param column The column in the where clause.
     * @param value The value of the column.
     *
     * @return the number of deleted rows.
     *
     * @throws TorqueException Any exceptions caught during processing will be
     *         rethrown wrapped into a TorqueException.
     *
     * @deprecated The value is not SQL escaped.
     *             Better use doDelete(Criteria, String)
     *             for automatic escaping and more flexibility.
     *             This method will be removed in a future version of Torque.
     */
    @Deprecated
    public static int deleteAll(String table, String column, int value)
        throws TorqueException
    {
        return getBasePeerImpl().deleteAll(table, column, value);
    }

    /**
     * Method to perform deletes based on conditions in a Criteria.
     *
     * @param criteria The criteria to use.
     *
     * @return the number of deleted rows.
     *
     * @throws TorqueException Any exceptions caught during processing will be
     *         rethrown wrapped into a TorqueException.
     *
     * @deprecated This method causes unexpected results when joins are used.
     *             Please use doDelete(org.apache.torque.criteria.Criteria,
     *                 TableMap).
     *             This method will be removed in a future version of Torque.
     */
    @Deprecated
    public static int doDelete(Criteria criteria) throws TorqueException
    {
        return getBasePeerImpl().doDelete(criteria);
    }

    /**
     * Method to perform deletes based on conditions in a Criteria.
     *
     * @param criteria The criteria to use.
     *
     * @return the number of deleted rows.
     *
     * @throws TorqueException Any exceptions caught during processing will be
     *         rethrown wrapped into a TorqueException.
     * @deprecated This method causes unexpected results when joins are used.
     *             Please use doDelete(
     *                 org.apache.torque.criteria.Criteria, TableMap).
     *             This method will be removed in a future version of Torque.
     */
    @Deprecated
    public static int doDelete(org.apache.torque.criteria.Criteria criteria)
            throws TorqueException
    {
        return getBasePeerImpl().doDelete(criteria);
    }

    /**
     * Method to perform deletes based on conditions in a Criteria.
     *
     * @param criteria The criteria to use.
     * @param con A Connection.
     *
     * @return the number of deleted rows.
     *
     * @throws TorqueException Any exceptions caught during processing will be
     *         rethrown wrapped into a TorqueException.
     *
     * @deprecated This method causes unexpected results when joins are used.
     *             Please use doDelete(org.apache.torque.criteria.Criteria,
     *                 TableMap, Connection).
     *             This method will be removed in a future version of Torque.
     */
    @Deprecated
    public static int doDelete(Criteria criteria, Connection con)
        throws TorqueException
    {
        return getBasePeerImpl().doDelete(criteria, con);
    }

    /**
     * Method to perform deletes based on conditions in a Criteria.
     *
     * @param criteria The criteria to use.
     * @param con A Connection.
     *
     * @return the number of deleted rows.
     *
     * @throws TorqueException Any exceptions caught during processing will be
     *         rethrown wrapped into a TorqueException.
     *
     * @deprecated This method causes unexpected results when joins are used.
     *             Please use doDelete(org.apache.torque.criteria.Criteria,
     *                 TableMap, Connection).
     *             This method will be removed in a future version of Torque.
     */
    @Deprecated
    public static int doDelete(org.apache.torque.criteria.Criteria criteria,
            Connection con)
        throws TorqueException
    {
        return getBasePeerImpl().doDelete(criteria, con);
    }

    /**
     * Inserts a record into a database table.
     * <p>
     * If the primary key is included in Criteria, then that value will
     * be used to insert the row.
     * <p>
     * Otherwise, if the primary key can be generated automatically,
     * the generated key will be used for the insert and will be returned.
     * <p>
     * If no value is given for the primary key is defined and it cannot
     * be generated automatically or the table has no primary key,
     * the values will be inserted as specified and null will be returned.
     *
     * @param insertValues Contains the values to insert, not null.
     *
     * @return the primary key of the inserted row (if the table
     *         has a primary key) or null (if the table does not have
     *         a primary key).
     *
     * @throws TorqueException if a database error occurs.
     */
    public static ObjectKey doInsert(ColumnValues insertValues)
          throws TorqueException
    {
        return getBasePeerImpl().doInsert(insertValues);
    }

    /**
     * Inserts a record into a database table.
     * <p>
     * If the primary key is included in Criteria, then that value will
     * be used to insert the row.
     * <p>
     * Otherwise, if the primary key can be generated automatically,
     * the generated key will be used for the insert and will be returned.
     * <p>
     * If no value is given for the primary key is defined and it cannot
     * be generated automatically or the table has no primary key,
     * the values will be inserted as specified and null will be returned.
     *
     * @param insertValues Contains the values to insert, not null.
     * @param connection the connection to use for the insert, not null.
     *
     * @return the primary key of the inserted row (if the table
     *         has a primary key) or null (if the table does not have
     *         a primary key).
     *
     * @throws TorqueException if a database error occurs.
     */
    public static ObjectKey doInsert(
                ColumnValues insertValues,
                Connection connection)
            throws TorqueException
    {
        return getBasePeerImpl().doInsert(insertValues, connection);
    }

    /**
     * Selects rows from a database an maps them to objects.
     *
     * @param criteria A Criteria specifying the records to select, not null.
     * @param mapper The mapper creating the objects from the resultSet,
     *        not null.
     *
     * @return The results of the query, not null.
     *
     * @throws TorqueException if querying the database fails.
     *
     * @deprecated Please use doSelect(org.apache.torque.criteria.Criteria,
     *             RecordMapper, TableMap).
     *             This method will be removed in a future version of Torque.
     */
    @Deprecated
    public static <T> List<T> doSelect(
                Criteria criteria,
                RecordMapper<T> mapper)
            throws TorqueException
    {
        BasePeerImpl<T> bpi = getBasePeerImpl();
        return bpi.doSelect(criteria, mapper);
    }

    /**
     * Selects rows from a database an maps them to objects.
     *
     * @param criteria A Criteria specifying the records to select, not null.
     * @param mapper The mapper creating the objects from the resultSet,
     *        not null.
     *
     * @return The results of the query, not null.
     *
     * @throws TorqueException if querying the database fails.
     */
    public static <T> List<T> doSelect(
                org.apache.torque.criteria.Criteria criteria,
                RecordMapper<T> mapper)
            throws TorqueException
    {
        BasePeerImpl<T> bpi = getBasePeerImpl();
        return bpi.doSelect(criteria, mapper);
    }

    /**
     * Selects rows from a database an maps them to objects.
     *
     * @param criteria A Criteria specifying the records to select, not null.
     * @param mapper The mapper creating the objects from the resultSet,
     *        not null.
     * @param connection the database connection for selecting records,
     *        not null.
     *
     * @return The results of the query, not null.
     * @throws TorqueException Error performing database query.
     *
     * @deprecated Please use doSelect(org.apache.torque.criteria.Criteria,
     *             RecordMapper, TableMap, Connection).
     *             This method will be removed in a future version of Torque.
     */
    @Deprecated
    public static <T> List<T> doSelect(
            Criteria criteria,
            RecordMapper<T> mapper,
            Connection connection)
        throws TorqueException
    {
        BasePeerImpl<T> bpi = getBasePeerImpl();
        return bpi.doSelect(
                criteria,
                mapper,
                connection);
    }

    /**
     * Selects rows from a database an maps them to objects.
     *
     * @param criteria A Criteria specifying the records to select, not null.
     * @param mapper The mapper creating the objects from the resultSet,
     *        not null.
     * @param connection the database connection for selecting records,
     *        not null.
     *
     * @return The results of the query, not null.
     * @throws TorqueException Error performing database query.
     */
    public static <T> List<T> doSelect(
            org.apache.torque.criteria.Criteria criteria,
            RecordMapper<T> mapper,
            Connection connection)
        throws TorqueException
    {
        BasePeerImpl<T> bpi = getBasePeerImpl();
        return bpi.doSelect(
                criteria,
                mapper,
                connection);
    }

    /**
     * Selects rows from a database an maps them to objects.
     *
     * @param query the sql query to execute, not null.
     * @param mapper The mapper creating the objects from the resultSet,
     *        not null.
     * @param dbName The name of the database to create the connection for,
     *        or null for the default SDB.
     *
     * @return The results of the query, not null.
     *
     * @throws TorqueException if querying the database fails.
     */
    public static <T> List<T> doSelect(
                String query,
                RecordMapper<T> mapper,
                String dbName)
            throws TorqueException
    {
        BasePeerImpl<T> bpi = getBasePeerImpl();
        return bpi.doSelect(
                query,
                mapper,
                dbName);
    }

    /**
     * Selects rows from a database an maps them to objects.
     *
     * @param query the SQL Query to execute, not null.
     * @param mapper The mapper creating the objects from the resultSet,
     *        not null.
     * @param connection the database connection, not null.
     *
     * @return The results of the query, not null.
     *
     * @throws TorqueException if querying the database fails.
     */
    public static <T> List<T> doSelect(
                String query,
                RecordMapper<T> mapper,
                Connection connection)
            throws TorqueException
    {
        BasePeerImpl<T> bpi = getBasePeerImpl();
        return bpi.doSelect(
                query,
                mapper,
                connection);
    }

    /**
     * Selects at most a single row from a database an maps them to objects.
     *
     * @param criteria A Criteria specifying the records to select, not null.
     * @param mapper The mapper creating the objects from the resultSet,
     *        not null.
     *
     * @return The selected row, or null if no records was selected.
     *
     * @throws TorqueException if querying the database fails.
     */
    public static <T> T doSelectSingleRecord(
                org.apache.torque.criteria.Criteria criteria,
                RecordMapper<T> mapper)
            throws TorqueException
    {
        BasePeerImpl<T> bpi = getBasePeerImpl();
        return bpi.doSelectSingleRecord(
                criteria,
                mapper);
    }

    /**
     * Selects at most a single row from a database an maps them to objects.
     *
     * @param criteria A Criteria specifying the records to select, not null.
     * @param mapper The mapper creating the objects from the resultSet,
     *        not null.
     * @param connection the database connection, not null.
     *
     * @return The selected row, or null if no records was selected.
     *
     * @throws TorqueException if querying the database fails.
     */
    public static <T> T doSelectSingleRecord(
                org.apache.torque.criteria.Criteria criteria,
                RecordMapper<T> mapper,
                Connection connection)
            throws TorqueException
    {
        BasePeerImpl<T> bpi = getBasePeerImpl();
        return bpi.doSelectSingleRecord(
                criteria,
                mapper,
                connection);
    }

    /**
     * Updates rows in the DB.  Checks if a <i>single</i> primary key
     * is specified in the updateValues object and uses it to perform
     * the update.  If no primary key is specified
     * or the table has multiple primary keys, an Exception will be thrown.
     * <p>
     * Use this method for performing an update of the kind:
     * <p>
     * "WHERE primary_key_id = someValue"
     * <p>
     * To perform an update on a table with multiple primary keys or
     * an update with non-primary key fields in the WHERE
     * clause, use doUpdate(ColumnValues, Criteria).
     *
     * @param updateValues Which columns to update with which values
     *        for which primary key value, not null.
     *
     * @return the number of affected rows.
     *
     * @throws TorqueException Any exceptions caught during processing will be
     *         rethrown wrapped into a TorqueException.
     */
    public static int doUpdate(ColumnValues updateValues)
            throws TorqueException
    {
        return getBasePeerImpl().doUpdate(updateValues);
    }

    /**
     * Updates rows in the DB.  Checks if a <i>single</i> primary key
     * is specified in the updateValues object and uses it to perform
     * the update.  If no primary key is specified
     * or the table has multiple primary keys, an Exception will be thrown.
     * <p>
     * Use this method for performing an update of the kind:
     * <p>
     * "WHERE primary_key_id = someValue"
     * <p>
     * To perform an update on a table with multiple primary keys or
     * an update with non-primary key fields in the WHERE
     * clause, use doUpdate(ColumnValues, Criteria, Connection).
     *
     * @param updateValues Which columns to update with which values
     *        for which primary key value, not null.
     * @param connection the database connection to use.
     *
     * @return the number of affected rows.
     *
     * @throws TorqueException Any exceptions caught during processing will be
     *         rethrown wrapped into a TorqueException.
     */
    public static int doUpdate(
                ColumnValues updateValues,
                Connection connection)
            throws TorqueException
    {
        return getBasePeerImpl().doUpdate(updateValues, connection);
    }

    /**
     * Executes an update against the database. The rows to be updated
     * are selected using <code>criteria</code> and updated using the values
     * in <code>updateValues</code>.
     *
     * @param selectCriteria selects which rows of which table
     *        should be updated, not null.
     * @param updateValues Which columns to update with which values, not null.
     *
     * @return the number of affected rows.
     *
     * @throws TorqueException if updating fails.
     *
     * @deprecated Please use doUpdate(
     *                 org.apache.torque.criteria.Criteria, ColumnValues).
     *             This method will be removed in a future version of Torque.
     */
    @Deprecated
    public static int doUpdate(
                Criteria selectCriteria,
                ColumnValues updateValues)
            throws TorqueException
    {
        return getBasePeerImpl().doUpdate(selectCriteria, updateValues);
    }

    /**
     * Executes an update against the database. The rows to be updated
     * are selected using <code>criteria</code> and updated using the values
     * in <code>updateValues</code>.
     *
     * @param selectCriteria selects which rows of which table
     *        should be updated, not null.
     * @param updateValues Which columns to update with which values, not null.
     *
     * @return the number of affected rows.
     *
     * @throws TorqueException if updating fails.
     */
    public static int doUpdate(
                org.apache.torque.criteria.Criteria selectCriteria,
                ColumnValues updateValues)
            throws TorqueException
    {
        return getBasePeerImpl().doUpdate(selectCriteria, updateValues);
    }

    /**
     * Executes an update against the database. The rows to be updated
     * are selected using <code>criteria</code> and updated using the values
     * in <code>updateValues</code>.
     *
     * @param criteria selects which rows of which table should be updated.
     * @param updateValues Which columns to update with which values, not null.
     * @param connection the database connection to use, not null.
     *
     * @return the number of affected rows.
     *
     * @throws TorqueException if updating fails.
     *
     * @deprecated Please use doUpdate(org.apache.torque.criteria.Criteria,
     *                 ColumnValues, Connection).
     *             This method will be removed in a future version of Torque.
     */
    @Deprecated
    public static int doUpdate(
                Criteria criteria,
                ColumnValues updateValues,
                Connection connection)
            throws TorqueException
    {
        return getBasePeerImpl().doUpdate(criteria, updateValues, connection);
    }

    /**
     * Executes an update against the database. The rows to be updated
     * are selected using <code>criteria</code> and updated using the values
     * in <code>updateValues</code>.
     *
     * @param criteria selects which rows of which table should be updated.
     * @param updateValues Which columns to update with which values, not null.
     * @param connection the database connection to use, not null.
     *
     * @return the number of affected rows.
     *
     * @throws TorqueException if updating fails.
     */
    public static int doUpdate(
                org.apache.torque.criteria.Criteria criteria,
                ColumnValues updateValues,
                Connection connection)
            throws TorqueException
    {
        return getBasePeerImpl().doUpdate(criteria, updateValues, connection);
    }

    /**
     * Utility method which executes a given SQL statement.  This
     * method should be used for update, insert, and delete
     * statements.  Use executeQuery() for selects.
     *
     * @param statementString A String with the SQL statement to execute.
     * @return The number of rows affected.
     * @throws TorqueException Any exceptions caught during processing will be
     *         rethrown wrapped into a TorqueException.
     */
    public static int executeStatement(String statementString)
            throws TorqueException
    {
        return getBasePeerImpl().executeStatement(statementString);
    }

    /**
     * Utility method which executes a given sql statement.  This
     * method should be used for update, insert, and delete
     * statements.  Use executeQuery() for selects.
     *
     * @param statementString A String with the sql statement to execute.
     * @param dbName Name of database to connect to.
     * @return The number of rows affected.
     * @throws TorqueException Any exceptions caught during processing will be
     *         rethrown wrapped into a TorqueException.
     */
    public static int executeStatement(String statementString, String dbName)
            throws TorqueException
    {
        return getBasePeerImpl().executeStatement(
                statementString,
                dbName,
                null);
    }

    /**
     * Utility method which executes a given sql statement.  This
     * method should be used for update, insert, and delete
     * statements.  Use executeQuery() for selects.
     *
     * @param statementString A String with the sql statement to execute.
     * @param con A Connection.
     * @return The number of rows affected.
     * @throws TorqueException Any exceptions caught during processing will be
     *         rethrown wrapped into a TorqueException.
     */
    public static int executeStatement(String statementString, Connection con)
            throws TorqueException
    {
        return getBasePeerImpl().executeStatement(statementString, con, null);
    }

    /**
     * Checks all columns in the criteria to see whether
     * booleanchar and booleanint columns are queried with a boolean.
     * If yes, the query values are mapped onto values the database
     * does understand, i.e. 0 and 1 for booleanints and N and Y for
     * booleanchar columns.
     *
     * @param criteria The criteria to be checked for booleanint and booleanchar
     *        columns.
     * @throws TorqueException if the database map for the criteria cannot be
     *         retrieved.
     *
     * @deprecated Please use correctBooleans(
     *                 org.apache.torque.criteria.Criteria, TableMap).
     *             This method will be removed in a future version of Torque.
     */
    @Deprecated
    public static void correctBooleans(
                Criteria criteria)
            throws TorqueException
    {
        getBasePeerImpl().correctBooleans(criteria);
    }

    /**
     * Checks all columns in the criteria to see whether
     * booleanchar and booleanint columns are queried with a boolean.
     * If yes, the query values are mapped onto values the database
     * does understand, i.e. 0 and 1 for booleanints and N and Y for
     * booleanchar columns.
     *
     * @param criteria The criteria to be checked for booleanint and booleanchar
     *        columns.
     * @throws TorqueException if the database map for the criteria cannot be
     *         retrieved.
     */
    public static void correctBooleans(
                org.apache.torque.criteria.Criteria criteria)
            throws TorqueException
    {
        getBasePeerImpl().correctBooleans(criteria);
    }

    /**
     * Checks all columns in the criteria to see whether
     * booleanchar and booleanint columns are queried with a boolean.
     * If yes, the query values are mapped onto values the database
     * does understand, i.e. 0 and 1 for booleanints and N and Y for
     * booleanchar columns.
     *
     * @param columnValues The value to be checked for booleanint
     *        and booleanchar columns.
     * @throws TorqueException if the database map for the criteria cannot be
     *         retrieved.
     */
    public static void correctBooleans(
            ColumnValues columnValues)
        throws TorqueException
    {
        getBasePeerImpl().correctBooleans(columnValues);
    }
}
