/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.queries;

import java.util.Enumeration;
import java.util.Vector;

import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.internal.databaseaccess.DatasourceCall;
import org.eclipse.persistence.internal.expressions.SQLModifyStatement;
import org.eclipse.persistence.internal.expressions.SQLStatement;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.sessions.SessionProfiler;
/**
 * <p><b>Purpose</b>:
 * Mechanism used for all  statement objects.
 * <p><b>Responsibilities</b>:
 * Executes the appropriate statement.
 *
 * @author Yvon Lavoie
 * @since TOPLink/Java 1.0
 */
public class StatementQueryMechanism extends CallQueryMechanism {
    protected SQLStatement sqlStatement;

    /** Normally only a single statement is used, however multiple table may require multiple statements on write. */
    protected Vector sqlStatements;

    public StatementQueryMechanism() {
    }

    /**
     * INTERNAL:
     * Return a new mechanism for the query
     * @param query - owner of mechanism
     */
    public StatementQueryMechanism(DatabaseQuery query) {
        super(query);
    }

    /**
     * Return a new mechanism for the query
     * @param query - owner of mechanism
     * @param statement - sql statement
     */
    public StatementQueryMechanism(DatabaseQuery query, SQLStatement statement) {
        super(query);
        this.sqlStatement = statement;
    }

    /**
     * The statement is no longer require after prepare so can be released.
     */
    public void clearStatement() {
        // Only clear the statement if it is an expression query, otherwise the statement may still be needed.
    }

    /**
     * Clone the mechanism for the specified query clone.
     */
    @Override
    public DatabaseQueryMechanism clone(DatabaseQuery queryClone) {
        StatementQueryMechanism clone = (StatementQueryMechanism)super.clone(queryClone);
        if ((!hasMultipleStatements()) && (getSQLStatement() != null)) {
            clone.setSQLStatement((SQLStatement)sqlStatement.clone());
        } else {
            Vector currentStatements = getSQLStatements();
            if (currentStatements != null) {
                Vector statementClone = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(currentStatements.size());
                Enumeration enumtr = currentStatements.elements();
                while (enumtr.hasMoreElements()) {
                    statementClone.addElement(((SQLStatement)enumtr.nextElement()).clone());
                }
                clone.setSQLStatements(statementClone);
            }
        }
        return clone;
    }

    /**
     * INTERNAL:
     * delete the object
     * @exception  DatabaseException - an error has occurred on the database.
     * @return the row count.
     */
    @Override
    public Integer deleteObject() throws DatabaseException {
        // Prepare the calls if not already set (prepare may not have had the modify row).
        if ((this.call == null) && (!hasMultipleCalls())) {
            prepareDeleteObject();
            if ((this.call == null) && (!hasMultipleCalls())) {
                return 1;// Must be 1 otherwise locking error will occur.
            }
        }

        return super.deleteObject();
    }

    /**
     * Update the object
     * @exception  DatabaseException - an error has occurred on the database.
     * @return the row count.
     */
    @Override
    public Integer executeNoSelect() throws DatabaseException {
        // Prepare the calls if not already set (prepare may not have had the modify row).
        if ((this.call == null) && (!hasMultipleCalls())) {
            prepareExecuteNoSelect();
        }

        return super.executeNoSelect();
    }

    /**
     * Return the selection criteria for the statement.
     */
    @Override
    public Expression getSelectionCriteria() {
        return getSQLStatement().getWhereClause();
    }

    /**
     * INTERNAL:
     * Return the sqlStatement
     */
    public SQLStatement getSQLStatement() {
        return sqlStatement;
    }

    /**
     * Normally only a single statement is used, however multiple table may require multiple statements on write.
     * This is lazy initialied to conserv space.
     */
    public Vector getSQLStatements() {
        if (sqlStatements == null) {
            sqlStatements = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(3);
        }
        return sqlStatements;
    }

    /**
     * Normally only a single statement is used, however multiple table may require multiple statements on write.
     * This is lazy initialized to conserve space.
     */
    public boolean hasMultipleStatements() {
        return (sqlStatements != null) && (!sqlStatements.isEmpty());
    }

    /**
     * Insert the object
     * @exception  DatabaseException - an error has occurred on the database.
     */
    @Override
    public void insertObject() throws DatabaseException {
        // Prepare the calls if not already set (prepare may not have had the modify row).
        if ((this.call == null) && (!hasMultipleCalls())) {
            prepareInsertObject();
        }

        super.insertObject();
    }

    /**
     * Insert the object if the reprepare flag is set, first reprepare the query.
     * Added for CR#3237
     * @param reprepare whether to reprepare the query.
     */
    @Override
    public void insertObject(boolean reprepare) {
        if (reprepare) {
            // Clear old calls, and reprepare.
            setCalls(null);
            trimFieldsForInsert();
            prepareInsertObject();
        }
        insertObject();
    }

    /**
     * INTERNAL
     * Remove a potential sequence number field and invoke the ReturningPolicy trimModifyRowsForInsert method
     */
    public void trimFieldsForInsert() {
        getDescriptor().getObjectBuilder().trimFieldsForInsert(getSession(), getModifyRow());
    }

    /**
     * Return true if this is a call query mechanism
     */
    @Override
    public boolean isCallQueryMechanism() {
        return false;
    }

    /**
     * Return true if this is a statement query mechanism
     */
    @Override
    public boolean isStatementQueryMechanism() {
        return true;
    }

    /**
     * INTERNAL:
     * This is different from 'prepareForExecution' in that this is called on the original query,
     * and the other is called on the copy of the query.
     * This query is copied for concurrency so this prepare can only setup things that
     * will apply to any future execution of this query.
     */
    @Override
    public void prepare() {
        if ((!hasMultipleStatements()) && (getSQLStatement() == null)) {
            throw QueryException.sqlStatementNotSetProperly(getQuery());
        }

        // Cannot call super yet as the call is not built.
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    @Override
    public void prepareCursorSelectAllRows() {
        setCallFromStatement();
        // The statement is no longer require so can be released.
        clearStatement();

        super.prepareCursorSelectAllRows();
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    @Override
    public void prepareDeleteAll() {
        setCallFromStatement();
        // The statement is no longer require so can be released.
        clearStatement();

        super.prepareDeleteAll();
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    @Override
    public void prepareDeleteObject() {
        setCallFromStatement();
        // The statement is no longer require so can be released.
        clearStatement();

        super.prepareDeleteObject();
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    @Override
    public void prepareDoesExist(DatabaseField field) {
        setCallFromStatement();
        // The statement is no longer require so can be released.
        clearStatement();

        getCall().returnOneRow();
        prepareCall();
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    @Override
    public void prepareExecuteNoSelect() {
        setCallFromStatement();
        // The statement is no longer require so can be released.
        clearStatement();

        super.prepareExecuteNoSelect();
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    @Override
    public void prepareExecuteSelect() {
        setCallFromStatement();
        // The statement is no longer require so can be released.
        clearStatement();

        super.prepareExecuteSelect();
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    @Override
    public void prepareInsertObject() {
        // Require modify row to prepare.
        if (getModifyRow() == null) {
            return;
        }

        if (hasMultipleStatements()) {
            for (Enumeration statementEnum = getSQLStatements().elements();
                     statementEnum.hasMoreElements();) {
                ((SQLModifyStatement)statementEnum.nextElement()).setModifyRow(getModifyRow());
            }
        } else if (getSQLStatement() != null) {
            ((SQLModifyStatement)getSQLStatement()).setModifyRow(getModifyRow());
        }
        setCallFromStatement();
        // The statement is no longer require so can be released.
        clearStatement();

        super.prepareInsertObject();
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    @Override
    public void prepareSelectAllRows() {
        setCallFromStatement();
        // The statement is no longer require so can be released.
        clearStatement();

        super.prepareSelectAllRows();
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    @Override
    public void prepareSelectOneRow() {
        setCallFromStatement();
        // The statement is no longer require so can be released.
        clearStatement();

        super.prepareSelectOneRow();
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    @Override
    public void prepareUpdateObject() {
        // Require modify row to prepare.
        if (getModifyRow() == null) {
            return;
        }

        if (hasMultipleStatements()) {
            for (Enumeration statementEnum = getSQLStatements().elements();
                     statementEnum.hasMoreElements();) {
                ((SQLModifyStatement)statementEnum.nextElement()).setModifyRow(getModifyRow());
            }
        } else if (getSQLStatement() != null) {
            ((SQLModifyStatement)getSQLStatement()).setModifyRow(getModifyRow());
        }
        setCallFromStatement();
        // The statement is no longer require so can be released.
        clearStatement();

        super.prepareUpdateObject();
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    @Override
    public void prepareUpdateAll() {
        setCallFromStatement();// Will build an SQLUpdateAllStatement
        clearStatement();// The statement is no longer require so can be released.
        super.prepareUpdateAll();
    }

    /**
     * Pre-build the SQL call from the statement.
     */
    protected void setCallFromStatement() {
        // Profile SQL generation.
        getSession().startOperationProfile(SessionProfiler.SqlGeneration, getQuery(), SessionProfiler.ALL);
        try {
            if (hasMultipleStatements()) {
                for (Enumeration statementEnum = getSQLStatements().elements(); statementEnum.hasMoreElements();) {
                    DatasourceCall call = null;
                    if (getDescriptor() != null) {
                        call = getDescriptor().buildCallFromStatement((SQLStatement)statementEnum.nextElement(), getQuery(), getExecutionSession());
                    } else {
                        call = ((SQLStatement)statementEnum.nextElement()).buildCall(getExecutionSession());
                    }

                    // In case of update call may be null if no update required.
                    if (call != null) {
                        addCall(call);
                    }
                }
            } else {
                DatasourceCall call = null;
                if (getDescriptor() != null) {
                    call = getDescriptor().buildCallFromStatement(getSQLStatement(), getQuery(), getExecutionSession());
                } else {
                    call = getSQLStatement().buildCall(getExecutionSession());
                }

                // In case of update call may be null if no update required.
                if (call != null) {
                    setCall(call);
                }
            }
        } finally {
            // Profile SQL generation.
            getSession().endOperationProfile(SessionProfiler.SqlGeneration, getQuery(), SessionProfiler.ALL);
        }
    }

    /**
     * Set the sqlStatement
     */
    public void setSQLStatement(SQLStatement statement) {
        this.sqlStatement = statement;
    }

    /**
     * Normally only a single statement is used, however multiple table may require multiple statements on write.
     * This is lazy initialized to conserve space.
     */
    protected void setSQLStatements(Vector sqlStatements) {
        this.sqlStatements = sqlStatements;
    }

    /**
     * Update the object
     * @exception  DatabaseException - an error has occurred on the database.
     * @return the row count.
     */
    @Override
    public Integer updateObject() throws DatabaseException {
        // Prepare the calls if not already set (prepare may not have had the modify row).
        if ((this.call == null) && (!hasMultipleCalls())) {
            prepareUpdateObject();
            if ((this.call == null) && (!hasMultipleCalls())) {
                return 1;// Must be 1 otherwise locking error will occur.
            }
        }

        return super.updateObject();
    }
}
