/*
 * Copyright (c) 1998, 2020 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.queries;

import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;

/**
 * <p><b>Purpose</b>:
 * Used for inserting or updating objects
 * WriteObjectQuery determines whether to perform a insert or an update on the database.
 *
 * <p><b>Responsibilities</b>:
 * <ul>
 * <li> Determines whether to perform a insert or an update on the database.
 * <li> Stores object in identity map for insert if required.
 * </ul>
 *
 * @author Yvon Lavoie
 * @since TOPLink/Java 1.0
 */
public class WriteObjectQuery extends ObjectLevelModifyQuery {
    public WriteObjectQuery() {
        super();
    }

    public WriteObjectQuery(Object objectToWrite) {
        this();
        setObject(objectToWrite);
    }

    public WriteObjectQuery(Call call) {
        this();
        setCall(call);
    }

    /**
     * INTERNAL:
     * Perform a does exist check to decide whether to perform an insert or update and
     * delegate the work to the mechanism.  Does exists check will also perform an
     * optimistic lock check if required.
     * @exception  DatabaseException - an error has occurred on the database
     * @exception  OptimisticLockException - an error has occurred using the optimistic lock feature
     * @return object - the object being written.
     */
    @Override
    public Object executeDatabaseQuery() throws DatabaseException, OptimisticLockException {
        if (getObjectChangeSet() != null) {
            return getQueryMechanism().executeWriteWithChangeSet();
        } else {
            return getQueryMechanism().executeWrite();
        }
    }

    /**
     * INTERNAL:
     * Perform a does exist check to decide whether to perform an insert or update and
     * delegate the work to the mechanism.
     */
    public void executeCommit() throws DatabaseException, OptimisticLockException {
        boolean doesExist;

        if (getSession().isUnitOfWork()) {
            doesExist = !((UnitOfWorkImpl)getSession()).isCloneNewObject(getObject());
            if (doesExist) {
                doesExist = ((UnitOfWorkImpl)getSession()).isObjectRegistered(getObject());
            }
        } else {
            //Initialize does exist query
            DoesExistQuery existQuery = (DoesExistQuery)this.descriptor.getQueryManager().getDoesExistQuery().clone();
            existQuery.setObject(getObject());
            existQuery.setPrimaryKey(getPrimaryKey());
            existQuery.setDescriptor(this.descriptor);
            existQuery.setTranslationRow(getTranslationRow());

            doesExist = ((Boolean)getSession().executeQuery(existQuery)).booleanValue();
        }

        // Do insert of update
        if (doesExist) {
            // Must do an update
            getQueryMechanism().updateObjectForWrite();
        } else {
            // Must do an insert
            getQueryMechanism().insertObjectForWrite();
        }
    }

    /**
     * INTERNAL:
     * Perform a does exist check to decide whether to perform an insert or update and
     * delegate the work to the mechanism.
     */
    public void executeCommitWithChangeSet() throws DatabaseException, OptimisticLockException {
        // Do insert of update
        if (!getObjectChangeSet().isNew()) {
            // Must do an update
            if (!getSession().getCommitManager().isCommitInPreModify(getObject())) {
                //If the changeSet is in the PreModify then it is in the process of being written
                getQueryMechanism().updateObjectForWriteWithChangeSet();
            }
        } else {
            // check whether the object is already being committed -
            // if it is and it is new, then a shallow insert must be done
            if (getSession().getCommitManager().isCommitInPreModify(getObject())) {
                // a shallow insert must be performed
                this.dontCascadeParts();
                getQueryMechanism().insertObjectForWrite();
                getSession().getCommitManager().markShallowCommit(object);
            } else {
                // Must do an insert
                getQueryMechanism().insertObjectForWrite();
            }
        }
    }

    /**
     * INTERNAL:
     * Returns the specific default redirector for this query type.  There are numerous default query redirectors.
     * See ClassDescriptor for their types.
     */
    @Override
    protected QueryRedirector getDefaultRedirector(){
        return descriptor.getDefaultQueryRedirector();
    }

    /**
     * PUBLIC:
     * Return if this is a write object query.
     */
    @Override
    public boolean isWriteObjectQuery() {
        return true;
    }

    /**
     * INTERNAL:
     * Prepare the receiver for execution in a session.
     */
    @Override
    public void prepareForExecution() throws QueryException {
        super.prepareForExecution();

        // Set the tranlation row, it may already be set in the custom query situation.
        // PERF: Only build the translation row for updates, as inserts do not have a where clause.
        if ((!isInsertObjectQuery()) && ((getTranslationRow() == null) || (getTranslationRow().isEmpty()))) {
            setTranslationRow(this.descriptor.getObjectBuilder().buildRowForTranslation(getObject(), getSession()));
        }
    }
}
