/*
 * 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 java.util.*;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.expressions.*;

/**
 * PUBLIC:
 * A Query Class used to perform a bulk update using TopLink's expression framework.
 * This class is provided to help optimize performance. It can be used in place
 * of reading in all the objects to be changed and issuing single updates per
 * instance. With this approach a single SQL UPDATE statement can be issued and
 * then, based on the Expression provided, any objects in the cache that are
 * effected by the update can be invalidated.
 * <p>
 * Notes: <ul>
 * <li>By default, if a UOW is being used, this query will be deferred until the UOW commits.
 * <li>UpdateAllQuery does not support foreign key updates
 * unless the relationship is 1-1 (without back pointers.)</ul>
 * <p>
 * <b>Example of Usage:</b> Adding an area code. <br>
 * <code>
 * UpdateAllQuery updateQuery = new UpdateAllQuery(Employee.class);   <br>
 * updateQuery.setSelectionCriteria(eb.get("areaCode").isNull());     <br>
 * updateQuery.addUpdate(eb.get("areaCode"), "613");                  <br>
 * </code>
 *
 * @author Guy Pelletier
 * @since  March 1, 2004
 */
public class UpdateAllQuery extends ModifyAllQuery {

    protected HashMap m_updateClauses;

    /**
     * PUBLIC:
     * Constructs a default update all query.
     */
    public UpdateAllQuery() {
        super();
    }

    /**
     * PUBLIC:
     * Constructs an update all query for the Class type specified.
     * @param referenceClass Class
     */
    public UpdateAllQuery(Class referenceClass) {
        super(referenceClass);
    }

    /**
     * PUBLIC:
     * Constructs an update all query for the specified Class type and selection criteria.
     * @param referenceClass Class type to be considered
     * @param selectionCriteria Expression
     */
    public UpdateAllQuery(Class referenceClass, Expression selectionCriteria) {
        super(referenceClass, selectionCriteria);
    }

    /**
     * PUBLIC:
     * Constructs an update all query for the Class type specified and the given
     * ExpressionBuilder. This sets the default builder which is used for all associated
     * expressions in the query.<br>
     * @param referenceClass Class type to be considered
     * @param expressionBuilder ExpressionBuilder
     */
    public UpdateAllQuery(Class referenceClass, ExpressionBuilder expressionBuilder) {
        super(referenceClass);
        this.defaultBuilder = expressionBuilder;
    }

    /**
     * PUBLIC:
     * Adds the update (SET) clause to the query. Uses default ExpressionBuilder.
     * @param field Expression Object level representation of a database query 'where' clause
     * @param value Object, the new value
     */
    public void addUpdate(Expression field, Object value) {
        addUpdateInternal(field, value);
    }

    /**
     * PUBLIC:
     * Adds the update (SET) clause to the query. Uses default ExpressionBuilder.
     * @param attributeName String, the name of the attribute
     * @param value Object, the new value
     */
    public void addUpdate(String attributeName, Object value) {
        addUpdateInternal(attributeName, value);
    }

    /**
     * PUBLIC:
     * Adds the update (SET) clause to the query. This method ensures that
     * the builder has the session and reference class set for both given Expressions.
     * Uses default ExpressionBuilder.
     * @param field Expression, representation of a database query 'where' clause that describes the field
     * @param value Expression, representation of a database query 'where' clause that describes the new value
     */
    public void addUpdate(Expression field, Expression value) {
        addUpdateInternal(field, value);
    }

    /**
     * PUBLIC:
     * Adds the update (SET) clause to the query. Uses default ExpressionBuilder.
     * @param attributeName String, the name of the attribute
     * @param value Expression, the new value
     */
    public void addUpdate(String attributeName, Expression value) {
        addUpdateInternal(attributeName, value);
    }

    /**
     * INTERNAL:
     */
    protected void addUpdateInternal(Object fieldObject, Object valueObject) {
        if(fieldObject == null) {
            throw QueryException.updateAllQueryAddUpdateFieldIsNull(this);
        }
        if(m_updateClauses == null) {
            m_updateClauses = new HashMap();
        }
        m_updateClauses.put(fieldObject, valueObject);
    }

    /**
     * INTERNAL:
     * Issue the SQL to the database and then merge into the cache.
     * If we are within a UoW, the merge to the cache must not be done until
     * the UoW merges into the parent. The UoW will trigger the merge to occur
     * at the correct time and will ensure the cache setting is set to none at
     * that time.
     */
    @Override
    public Object executeDatabaseQuery() throws DatabaseException {
        result = getQueryMechanism().updateAll();// fire the SQL to the database
        mergeChangesIntoSharedCache();
        return result;
    }

    /**
     * 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.getDefaultUpdateObjectQueryRedirector();
    }

    /**
     * INTERNAL:
     * Return the updates stored for an update all query
     */
    public HashMap getUpdateClauses() {
        return m_updateClauses;
    }

    /**
     * INTERNAL:
     * Return true if this is an update all query.
     */
    @Override
    public boolean isUpdateAllQuery() {
        return true;
    }

    /**
     * INTERNAL:
     */
    @Override
    protected void prepare() throws QueryException {
        super.prepare();// will tell the query mechanism to prepare itself as well.

        Class referenceClass = getReferenceClass();

        // Check the reference class, must be set
        if (referenceClass == null) {
            throw QueryException.referenceClassMissing(this);
        }

        // Check the descriptor is set, if not try to get it from the session
        if (getDescriptor() == null) {
            ClassDescriptor desc = getSession().getDescriptor(referenceClass);

            if (desc == null) {
                throw QueryException.descriptorIsMissing(referenceClass, this);
            }

            setDescriptor(desc);
        }

        ClassDescriptor descriptor = getDescriptor();

        // Check the descriptor for an aggregate
        if (descriptor.isAggregateDescriptor()) {
            throw QueryException.aggregateObjectCannotBeDeletedOrWritten(descriptor, this);
        }

        // Check that the update statement is set. That is the bare minimum,
        // the user can execute this query without a selection criteria though.
        if ((getUpdateClauses() == null || getUpdateClauses().isEmpty()) && isExpressionQuery()) {
            throw QueryException.updateStatementsNotSpecified();
        }

        getQueryMechanism().prepareUpdateAll();
    }
    /**
     * INTERNAL:
     * Initialize the expression builder which should be used for this query. If
     * there is a where clause, use its expression builder.
     * If after this method defaultBuilder is still null,
     * then initializeDefaultBuilder method will generate and cache it.
     */
    @Override
    protected void initializeQuerySpecificDefaultBuilder() {
        super.initializeQuerySpecificDefaultBuilder();
        if(this.defaultBuilder == null && m_updateClauses != null) {
            Iterator it = m_updateClauses.values().iterator();
            while(it.hasNext() ) {
                Object value = it.next();
                if(value != null) {
                    if(value instanceof Expression) {
                        Expression valueExpression = (Expression)value;
                        this.defaultBuilder = valueExpression.getBuilder();
                        if(this.defaultBuilder != null) {
                            return;
                        }
                    }
                }
            }
            it = m_updateClauses.keySet().iterator();
            while(it.hasNext() ) {
                Object field = it.next();
                if(field instanceof Expression) {
                    Expression fieldExpression = (Expression)field;
                    this.defaultBuilder = fieldExpression.getBuilder();
                    if(this.defaultBuilder != null) {
                        return;
                    }
                }
            }
        }
    }
}

