Package org.jpox.store.mapped.expression

Source Code of org.jpox.store.mapped.expression.AggregateExpression

/**********************************************************************
Copyright (c) 2004 Erik Bengtson and others. All rights reserved.
Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0

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.

Contributors:
2005 Andy Jefferson - fix for count(this) where we have a composite PK
    ...
**********************************************************************/
package org.jpox.store.mapped.expression;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import org.jpox.exceptions.JPOXUserException;
import org.jpox.store.mapped.mapping.IntegerMapping;
import org.jpox.store.mapped.mapping.JavaTypeMapping;
import org.jpox.store.mapped.mapping.ShortMapping;

/**
* Representation of aggregate functions in JDOQL
* @version $Revision: 1.16 $
*/
public class AggregateExpression extends NumericExpression
{
    /** Whether we should use DISTINCT on the aggregate field column. */
    boolean distinct = false;

    /**
     * Constructor
     * @param qs The query statement
     */
    public AggregateExpression(QueryExpression qs)
    {
        super(qs);
    }

    protected AggregateExpression(JavaTypeMapping mapping,  String functionName, List args, boolean distinct)
    {
        super(functionName, args);

        // Remove ScalarExpression generated SQL since it cant handle what we want
        st.clearStatement();
        st.append(functionName).append('(');
        if (distinct)
        {
            st.append("DISTINCT ");
        }

        ListIterator i = args.listIterator();
        ScalarExpression arg = (ScalarExpression)i.next();
        te = arg.getLogicSetExpression(); //just delegate table expr to one arg.
        st.append(arg);

        while (i.hasNext())
        {
            arg = (ScalarExpression)i.next();
            st.append(',').append(arg);
        }

        st.append(')');
        this.expressionList.addExpression(this);
        this.mapping = mapping;
    }

    /**
     * Method to enable use of DISTINCT on the aggregate field column
     */
    public void setDistinct()
    {
        distinct = true;
    }

    /**
     * Returns the max value of the argument.
     * @param expr the expression
     * @return the result in a ScalarExpression instance
     */
    public ScalarExpression maxMethod(ScalarExpression expr)
    {
        if (distinct)
        {
            throw new JPOXUserException(LOCALISER.msg("037012", "MAX"));
        }
        return getFunctionExpression("MAX", expr, expr.getMapping());
    }

    /**
     * Returns the max value of the argument.
     * @param expr the expression
     * @return the result in a ScalarExpression instance
     */
    public ScalarExpression minMethod(ScalarExpression expr)
    {
        if (distinct)
        {
            throw new JPOXUserException(LOCALISER.msg("037012", "MIN"));
        }
        return getFunctionExpression("MIN", expr, expr.getMapping());
    }

    /**
     * Returns the sum value of the argument.
     * @param expr the expression
     * @return the result in a ScalarExpression instance
     */
    public ScalarExpression sumMethod(ScalarExpression expr)
    {
        if (!(expr instanceof NumericExpression))
        {
            // JDO2 spec [14.6.9] : SUM is invalid on non-numeric types
            throw new JPOXUserException(LOCALISER.msg("037011", "SUM"));
        }
        JavaTypeMapping sumMapping = expr.getMapping();
        if (sumMapping instanceof IntegerMapping || sumMapping instanceof ShortMapping)
        {
            // Integral types return Long
            sumMapping = qs.getStoreManager().getDatastoreAdapter().getMapping(Long.class,
                qs.getStoreManager(), qs.getClassLoaderResolver());
        }
        return getFunctionExpression("SUM", expr, sumMapping);
    }

    /**
     * Returns the average value of the argument.
     * @param expr the expression
     * @return the result in a ScalarExpression instance
     */
    public ScalarExpression avgMethod(ScalarExpression expr)
    {
        return getFunctionExpression("AVG", expr, expr.getMapping());
    }

    /**
     * Returns the count value of the argument.
     * @param expr the expression
     * @return the result in a ScalarExpression instance
     */
    public ScalarExpression countMethod(ScalarExpression expr)
    {
        if (expr instanceof ObjectExpression && expr.getMapping().getNumberOfDatastoreFields() > 1)
        {
            // Use first column only with COUNT - COUNT(a,b) is invalid for RDBMS
            ((ObjectExpression)expr).useFirstDatastoreFieldOnly();
        }
        return getFunctionExpression("COUNT", expr,
            qs.getStoreManager().getDatastoreAdapter().getMapping(Long.class, qs.getStoreManager(), qs.getClassLoaderResolver()));
    }

    /**
     * Creates a function expression. e.g. MAX(expr)
     * @param functionName the name of the function
     * @param expr the expression
     * @param mapping the mapping to be used for converting from db to java and vice-versa
     * @return the function expression. a NullLiteral is returned if the argument expr is null
     */
    private ScalarExpression getFunctionExpression(String functionName, ScalarExpression expr, JavaTypeMapping mapping)
    {
        if (expr == null)
        {
            return new NullLiteral(qs);
        }
        else
        {
            ArrayList args = new ArrayList();
            args.add(expr);

            ScalarExpression numExpr = new AggregateExpression(mapping, functionName, args, distinct);
            return numExpr;
        }
    }
}
TOP

Related Classes of org.jpox.store.mapped.expression.AggregateExpression

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.