/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (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.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * 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 com.queplix.core.utils.sql;

import com.queplix.core.jxb.entity.types.SqlSType;
import com.queplix.core.jxb.sqlwrapper.Property;
import com.queplix.core.utils.sql.error.SQLDeleteConflictException;
import com.queplix.core.utils.sql.error.SQLDuplicateKeyException;
import com.queplix.core.utils.sql.error.SQLIndexConflictException;
import com.queplix.core.utils.sql.parser.BinaryParser;
import com.queplix.core.utils.sql.parser.DateParser;
import com.queplix.core.utils.sql.parser.FloatParser;
import com.queplix.core.utils.sql.parser.IntParser;
import com.queplix.core.utils.sql.parser.LongParser;
import com.queplix.core.utils.sql.parser.MemoParser;
import com.queplix.core.utils.sql.parser.SqlTypeParser;
import com.queplix.core.utils.sql.parser.StringParser;
import com.queplix.core.utils.sql.parser.TimeParser;
import com.queplix.core.utils.sql.parser.TimestampParser;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * Defines the wrapper for SQL operations.
 *
 * @author [ALB] Baranov Andrey
 * @author [ONZ] Oleg N. Zhovtanyuk
 * @version $Revision: 1.1.1.1 $ $Date: 2005/09/12 15:31:20 $
 */
public interface SqlWrapper
        extends java.io.Serializable {

    // =============================== Initialization

    public void init(Property[] properties);

    // =============================== Connections and SQL statements management

    /**
     * Makes connection to the database.
     *
     * @return new database connection
     */
    public Connection doConnection();

    /**
     * Makes connection to the database with autocommit flag.
     *
     * @param autocommit make auto commit or not
     * @return new database connection
     */
    public Connection doConnection(boolean autocommit);

    /**
     * Makes SQL statement.
     *
     * @param con connection to the database
     * @return sql <code>Statement</code>
     */
    public Statement doStatement(Connection con);

    /**
     * Prepares SQL statement.
     *
     * @param con connection to the database
     * @param sql sql query
     * @return sql <code>PreparedStatement</code>
     */
    public PreparedStatement doPreparedStatement(Connection con, String sql);

    /**
     * Closes connection to the database.
     *
     * @param con SQL <code>Connection</code>
     */
    public void closeConnection(Connection con);

    /**
     * Closes SQL statement.
     *
     * @param stat sql <code>Statement</code>
     */
    public void closeConnection(Statement stat);

    /**
     * Closes SQL statement and connection to the database.
     *
     * @param con  SQL <code>Connection</code>
     * @param stat SQL <code>Statement</code>
     */
    public void closeConnection(Connection con, Statement stat);

    /**
     * Close SQL result set.
     *
     * @param rs SQL <code>ResultSet</code>
     */
    public void closeResultSet(ResultSet rs);

    // ================================================== SQL queries management

    /**
     * Executes SQL query and return <code>ResultSet</code> object.
     *
     * @param stat sql <code>Statement</code>
     * @param sql  SQL query
     * @return SQL <code>ResultSet</code>
     * @throws SQLException
     */
    public ResultSet executeQuery(Statement stat, String sql)
            throws SQLException;

    /**
     * Executes SQL query and return <code>ResultSet</code> object.
     *
     * @param stat SQL <code>PreparedStatement</code>
     * @return SQL <code>ResultSet</code>
     * @throws SQLException
     */
    public ResultSet executeQuery(PreparedStatement stat)
            throws SQLException;

    /**
     * Executes SQL query without returning <code>ResultSet</code> object.
     *
     * @param stat SQL <code>Statement</code>
     * @param sql  SQL query
     * @return number of records affected
     * @throws SQLDuplicateKeyException
     * @throws SQLIndexConflictException
     * @throws SQLDeleteConflictException
     * @throws SQLException
     */
    public int executeUpdate(Statement stat, String sql)
            throws SQLDuplicateKeyException, SQLIndexConflictException,
            SQLDeleteConflictException, SQLException;

    /**
     * Executes SQL query without returning <code>ResultSet</code> object.
     *
     * @param stat SQL <code>PreparedStatement</code>
     * @return number of records affected
     * @throws SQLDuplicateKeyException
     * @throws SQLIndexConflictException
     * @throws SQLDeleteConflictException
     * @throws SQLException
     */
    public int executeUpdate(PreparedStatement stat)
            throws SQLDuplicateKeyException, SQLIndexConflictException,
            SQLDeleteConflictException, SQLException;

    /**
     * Executes SQL query and return one parameter as result.
     *
     * @param con     database connection
     * @param sql     SQL query
     * @param sqltype type of SQL parameter
     * @return one value
     * @throws SQLException
     */
    public String executeSql(Connection con, String sql, int sqltype)
            throws SQLException;

    /**
     * Executes SQL query and return one parameter as result. Get field value
     * (fieldName) from table (tableName) by pkey.
     *
     * @param con       current connection to database
     * @param tableName name of table for select query
     * @param fieldName name of field that value will be returned
     * @param pkeyName  primary key name
     * @param pkey      primary key for select query
     * @return table field value
     * @throws SQLException
     */
    public String executeSql(Connection con, String tableName, String fieldName,
                             String pkeyName, long pkey)
            throws SQLException;

    /**
     * Executes SQL query and return one parameter as result. Get field value
     * (fieldName) from table (tableName) by pkey.
     *
     * @param con       current connection to database
     * @param tableName name of table for select query
     * @param fieldName name of field that value will be returned
     * @param pkeyName  primary key name
     * @param pkey      primary key for select query
     * @return table field value
     * @throws SQLException
     */
    public String executeSql(Connection con, String tableName, String fieldName,
                             String pkeyName, String pkey)
            throws SQLException;

    // ==================================================== Data parsers getters

    /**
     * Integer number parser instance getter.
     *
     * @return new IntParser object
     */
    public IntParser getIntParser();

    /**
     * Long number parser instance getter.
     *
     * @return new LongParser object
     */
    public LongParser getLongParser();

    /**
     * Float number parser instance getter.
     *
     * @return new FloatParser object
     */
    public FloatParser getFloatParser();

    /**
     * String data parser instance getter.
     *
     * @return new StringParser object
     */
    public StringParser getStringParser();

    /**
     * Timestamp parser instance getter.
     *
     * @return new TimestampParser object
     */
    public TimestampParser getTimestampParser();

    /**
     * Date parser instance getter.
     *
     * @return new DateParser object
     */
    public DateParser getDateParser();

    /**
     * Time parser instance getter.
     *
     * @return new TimeParser object
     */
    public TimeParser getTimeParser();

    /**
     * MEMO data parser instance getter.
     *
     * @return new MemoParser object
     */
    public MemoParser getMemoParser();

    /**
     * MEMO LONG data parser instance getter.
     *
     * @return new MemoParser object
     */
    public MemoParser getMemoLongParser();

    /**
     * Binary data parser instance getter.
     *
     * @return new BinaryParser object
     */
    public BinaryParser getBinaryParser();

    /**
     * Get parser by data type.
     *
     * @param sqltype sql type
     * @return parser
     */
    public SqlTypeParser getParser(int sqltype);

    // ============================================================ Misc methods

    /**
     * Gets the next primary key value for the given database table.
     *
     * @param con   database connection
     * @param table table to get the key for
     * @return unique primary key value
     * @throws SQLException
     * @see #getNextKey(Connection,String,int)
     */
    public long getNextKey(Connection con, String table)
            throws SQLException;

    /**
     * Gets the next primary key value for the given database table.
     * <p/>
     * Also &quot;reserves&quot; the range of values. Usage pattern:
     * <pre>
     *   SqlWrapper sqlWrapper = sqlWrapperFactory.getSqlWarapper();
     * </pre>
     * </p>
     *
     * @param con   database connection
     * @param table table to get the key for
     * @param range index range (1..N)
     * @return unique primary key value
     * @throws SQLException
     */
    public long getNextKey(Connection con, String table, int range)
            throws SQLException;

    /**
     * Gets the next database sequence value for the given sequence table.
     *
     * @param con  database connection
     * @param name sequence name
     * @return unique key value
     * @throws SQLException
     */
    public long getNextSeq(Connection con, String name)
            throws SQLException;

    /**
     * Get soundex code for <code>str</code>
     *
     * @param con connection to DB
     * @param str string
     * @return soundex code
     * @throws SQLException
     */
    public String getSoundex(Connection con, String str)
            throws SQLException;

    /**
     * Get current user database schema
     *
     * @param con connection to DB
     * @return current schema
     * @throws SQLException
     */
    public String getCurrentSchema(Connection con)
            throws SQLException;

    /**
     * Map sql type on Efield sql type
     *
     * @param sqlType       sql type
     * @param sqlColumnSize sql column size
     * @return Efield field type or NULL if none found
     * @throws SQLException
     */
    public SqlSType typeMapping(int sqlType, int sqlColumnSize)
            throws SQLException;

}
