package de.renew.database.entitylayer;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Hashtable;


/**
 * The SQL dialect for the mSQL database system.
 */
public class MsqlDialect extends SQLDialect {

    /**
     * The empty default constructor for the MsqlDialect class.
     */
    public MsqlDialect() {}

    /**
     * Doesn't do anything, since the primary key
     * value is known before the INSERT statement.
     * See also:
     * {@link #setUniquePrimaryKeyValueBeforeInsert(Connection, Entity, Hashtable)}
     *
     * @param connection The connection to determine
     * the primary key from (if necessary).
     * @param entity The entity to set the primary key into.
     * @param values The values hashtable of the entity.
     */
    @Override
    protected void setUniquePrimaryKeyValueAfterInsert(
        Connection connection, Entity entity, Hashtable<String, Object> values)
    {}

    /**
     * Sets the primary key value before a save
     * method's INSERT statement.
     * See also:
     * {@link #setUniquePrimaryKeyValueAfterInsert(Connection, Entity, Hashtable)}
     *
     * @param connection The connection to determine
     * the primary key from.
     * @param entity The entity to set the primary key into.
     * @param values The values hashtable of the entity.
     */
    @Override
    protected void setUniquePrimaryKeyValueBeforeInsert(
        Connection connection, Entity entity, Hashtable<String, Object> values) throws SQLException
    {
        Attribute[] primaryKey = entity.getPrimaryKey();
        if (primaryKey.length != 1) {
            throw new IllegalStateException(
                "Auto-set primary key works only"
                    + " on tables with exactly one primary key attribute.\n" + entity.getTableName()
                    + " is not such a table.");
        }
        synchronized (entity.getClass()) {
            Statement statement = null;
            ResultSet resultSet = null;

            try {
                StringBuffer query = new StringBuffer();
                query.append("select _seq from ");
                query.append(entity.getTableName());
                statement = connection.createStatement();
                resultSet = statement.executeQuery(query.toString());

                if (resultSet.next()) {
                    entity.setValue(primaryKey[0].getName(), resultSet.getInt(1));
                }
            } finally {
                if (resultSet != null) {
                    resultSet.close();
                }

                if (statement != null) {
                    statement.close();
                }
            }
        }
    }
}