Package org.datanucleus.store.query

Source Code of org.datanucleus.store.query.AbstractJPQLQuery

/**********************************************************************
Copyright (c) 2007 Andy Jefferson 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:
    ...
**********************************************************************/
package org.datanucleus.store.query;

import java.util.Iterator;
import java.util.Map;

import org.datanucleus.ObjectManager;
import org.datanucleus.exceptions.NucleusUserException;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.query.JPQLSingleStringParser;
import org.datanucleus.query.QueryUtils;
import org.datanucleus.query.compiler.JPQLCompiler;
import org.datanucleus.query.compiler.JavaQueryCompiler;
import org.datanucleus.query.compiler.QueryCompilation;
import org.datanucleus.util.NucleusLogger;

/**
* Abstract representation of a JPQL query used by DataNucleus.
* The query can be specified via method calls, or via a single-string form.
* @see Query
*/
public abstract class AbstractJPQLQuery extends AbstractJavaQuery
{
    /**
     * Constructor.
     * @param om ObjectManager
     */
    public AbstractJPQLQuery(ObjectManager om)
    {
        super(om);
    }

    /**
     * Constructs a new query instance having the same criteria as the given query.
     * @param om The ObjectManager
     * @param q The query from which to copy criteria.
     */
    public AbstractJPQLQuery(ObjectManager om, AbstractJPQLQuery q)
    {
        super(om);

        if (q == null)
        {
            candidateClass = null;
            candidateClassName = null;
            filter = null;
            imports = null;
            explicitVariables = null;
            explicitParameters = null;
            grouping = null;
            ordering = null;
            result = null;
            resultClass = null;
            resultClassName = null;
            resultDistinct = false;
            range = null;
            fromInclNo = 0;
            toExclNo = Long.MAX_VALUE;
        }
        else
        {
            candidateClass = q.candidateClass;
            candidateClassName = q.candidateClassName;
            filter = q.filter;
            imports = q.imports;
            explicitVariables = q.explicitVariables;
            explicitParameters = q.explicitParameters;
            grouping = q.grouping;
            ordering = q.ordering;
            result = q.result;
            resultClass = q.resultClass;
            resultClassName = q.resultClassName;
            resultDistinct = q.resultDistinct;
            range = q.range;
            fromInclNo = q.fromInclNo;
            toExclNo = q.toExclNo;

            // JDO 1.0.1, Sect 12.6.3 : IgnoreCache is preserved when using other query baseline
            ignoreCache = q.ignoreCache;
        }
    }

    /**
     * Constructor for a JPQL query where the query is specified using the "Single-String" format.
     * @param om The ObjectManager
     * @param query The query string
     */
    public AbstractJPQLQuery(ObjectManager om, String query)
    {
        super(om);

        new JPQLSingleStringParser(this, query).parse();
    }

    /**
     * Set the result for the results.
     * @param result Optional keyword "distinct" followed by comma-separated list of
     *     result expressions or a result class
     */
    public void setResult(String result)
    {
        discardCompiled();
        assertIsModifiable();
        if (result == null)
        {
            this.result = null;
            this.resultDistinct = false;
            return;
        }

        String str = result.trim();
        if (str.toUpperCase().startsWith("DISTINCT "))
        {
            this.resultDistinct = true;
            this.result = str.substring(8).trim();
        }
        else
        {
            this.resultDistinct = false;
            this.result = str;
        }
    }

    /**
     * Method to take the defined parameters for the query and form a single string.
     * This is used to print out the query for logging.
     * @return The single string
     */
    public String getSingleStringQuery()
    {
        if (singleString != null)
        {
            return singleString;
        }

        StringBuffer str = new StringBuffer();
        if (type == BULK_UPDATE)
        {
            str.append("UPDATE " + update + " ");
        }
        else if (type == BULK_DELETE)
        {
            str.append("DELETE ");
        }
        else
        {
            str.append("SELECT ");
        }

        if (result != null)
        {
            if (resultDistinct)
            {
                str.append("DISTINCT ");
            }
            str.append(result + " ");
        }
        if (from != null)
        {
            str.append("FROM " + from + " ");
        }
        if (filter != null)
        {
            str.append("WHERE " + filter + " ");
        }
        if (grouping != null)
        {
            str.append("GROUP BY " + grouping + " ");
        }
        if (having != null)
        {
            str.append("HAVING " + having + " ");
        }
        if (ordering != null)
        {
            str.append("ORDER BY " + ordering + " ");
        }

        singleString = str.toString().trim();
        return singleString;
    }

    /**
     * Method to compile the JPQL query.
     * This implementation assumes that we are using the "generic" JPQL compiler in
     * <i>org.datanucleus.query.compiler</i>. If not then override this method.
     * Will populate the "compilation" class variable.
     * @param forExecute Whether compiling for execution NOT USED HERE. TODO Remove this when possible
     * @param parameterValues Map of param values keyed by param name.
     */
    protected void compileInternal(boolean forExecute, Map parameterValues)
    {
        if (compilation != null)
        {
            return;
        }

        QueryManager queryMgr = om.getOMFContext().getQueryManager();
        boolean caching = getBooleanExtensionProperty("datanucleus.query.cached", true);
        if (caching)
        {
            QueryCompilation cachedCompilation = queryMgr.getQueryCompilationForQuery("JPQL", toString());
            if (cachedCompilation != null)
            {
                if (NucleusLogger.QUERY.isDebugEnabled())
                {
                    NucleusLogger.QUERY.debug(LOCALISER.msg("021079", toString(), "JPQL"));
                }
                compilation = cachedCompilation;
                if (compilation.getExprResult() == null)
                {
                    // If the result was "Object(e)" or "e" then this is meaningless so remove
                    result = null;
                }
                checkParameterTypesAgainstCompilation(parameterValues);
                return;
            }
        }

        long startTime = 0;
        if (NucleusLogger.QUERY.isDebugEnabled())
        {
            startTime = System.currentTimeMillis();
            NucleusLogger.QUERY.debug(LOCALISER.msg("021044", "JPQL", getSingleStringQuery()));
        }
        JavaQueryCompiler compiler = new JPQLCompiler(om.getMetaDataManager(), om.getClassLoaderResolver(),
            from, candidateClass, candidateCollection,
            this.filter, getParsedImports(), this.ordering, this.result, this.grouping, this.having,
            explicitParameters, update);
        compilation = compiler.compile(parameterValues, subqueries);
        if (QueryUtils.queryReturnsSingleRow(this))
        {
            compilation.setReturnsSingleRow();
        }
        if (compilation.getExprResult() == null)
        {
            // If the result was "Object(e)" or "e" then this is meaningless so remove
            result = null;
        }
        if (NucleusLogger.QUERY.isDebugEnabled())
        {
            NucleusLogger.QUERY.debug(LOCALISER.msg("021045", "JPQL",
                "" + (System.currentTimeMillis() - startTime)));
        }

        if (subqueries != null)
        {
            // Compile any subqueries
            Iterator iter = subqueries.entrySet().iterator();
            while (iter.hasNext())
            {
                Map.Entry entry = (Map.Entry)iter.next();
                SubqueryDefinition subqueryDefinition = (SubqueryDefinition)entry.getValue();
                Query subquery = subqueryDefinition.getQuery();
                if (NucleusLogger.QUERY.isDebugEnabled())
                {
                    startTime = System.currentTimeMillis();
                    NucleusLogger.QUERY.debug(LOCALISER.msg("021044", "JPQL",
                        ((AbstractJPQLQuery)subquery).getSingleStringQuery()));
                }
                compiler = new JPQLCompiler(om.getMetaDataManager(), om.getClassLoaderResolver(),
                    subquery.from, subquery.candidateClass, null,
                    subquery.filter, getParsedImports(), subquery.ordering, subquery.result,
                    subquery.grouping, subquery.having, null, null);
                QueryCompilation subqueryCompilation = compiler.compile(parameterValues, null);
                compilation.addSubqueryCompilation((String)entry.getKey(), subqueryCompilation);
                if (NucleusLogger.QUERY.isDebugEnabled())
                {
                    NucleusLogger.QUERY.debug(LOCALISER.msg("021045", "JPQL",
                        "" + (System.currentTimeMillis() - startTime)));
                }
            }
        }

        if (implicitParameters != null)
        {
            // Make sure any implicit parameters have their values in the compilation
            Iterator paramKeyIter = implicitParameters.keySet().iterator();
            while (paramKeyIter.hasNext())
            {
                Object paramKey = paramKeyIter.next();
                String paramName = "" + paramKey;
                applyImplicitParameterValueToCompilation(paramName, implicitParameters.get(paramName));
            }
        }
        checkParameterTypesAgainstCompilation(parameterValues);

        if (caching)
        {
            // Cache for future reference
            queryMgr.addQueryCompilation("JPQL", toString(), compilation);
        }
    }

    /**
     * Utility to resolve the declaration to a particular class.
     * Takes the passed in name, together with the defined import declarations and returns the
     * class represented by the declaration.
     * @param classDecl The declaration
     * @return The class it resolves to (if any)
     * @throws NucleusUserException Thrown if the class cannot be resolved.
     */
    public Class resolveClassDeclaration(String classDecl)
    {
        // Try to find an entity name before relaying to the superclass method
        AbstractClassMetaData acmd = this.getStoreManager().getOMFContext().getMetaDataManager().getMetaDataForEntityName(classDecl);
        if (acmd != null)
        {
            classDecl = acmd.getFullClassName();
        }

        return super.resolveClassDeclaration(classDecl);
    }
}
TOP

Related Classes of org.datanucleus.store.query.AbstractJPQLQuery

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.