All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.datanucleus.store.db4o.query.NativeQuery Maven / Gradle / Ivy

/**********************************************************************
Copyright (c) 2008 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.db4o.query;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.datanucleus.exceptions.NucleusUserException;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.store.ExecutionContext;
import org.datanucleus.store.connection.ManagedConnection;
import org.datanucleus.store.db4o.DB4OStoreManager;
import org.datanucleus.store.db4o.DB4OUtils;
import org.datanucleus.store.query.AbstractJavaQuery;
import org.datanucleus.util.Localiser;
import org.datanucleus.util.NucleusLogger;

import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;
import com.db4o.query.QueryComparator;

/**
 * Representation of a DB4O "Native" query for use in JPOX.
 * Created by passing in the predicate object.
 * A DB4O native query is not compiled as such, with all work being performed at execution.
 * Any "comparator" for the native query can be specified via the query extension "db4o.native.comparator".
 */
public class NativeQuery extends AbstractJavaQuery
{
    /** Localiser for messages. */
    protected static final Localiser LOCALISER_DB4O = Localiser.getInstance(
        "org.datanucleus.store.db4o.Localisation", DB4OStoreManager.class.getClassLoader());

    /** The Predicate for the native query. */
    protected Predicate predicate = null;

    /**
     * Constructs a new query instance that uses the given persistence manager.
     * @param ec execution context
     */
    public NativeQuery(ExecutionContext ec)
    {
        this(ec, null);
    }

    /**
     * Constructor for a query using DB4O "native" query language.
     * The second parameter must implement "com.db4o.query.Predicate".
     * @param ec execution context
     * @param predicate The native query predicate
     * @throws NucleusUserException When the second parameter isnt an implementation of a Predicate
     */
    public NativeQuery(ExecutionContext ec, Object predicate)
    {
        super(ec);

        if (!(predicate instanceof Predicate))
        {
            throw new NucleusUserException(LOCALISER_DB4O.msg("DB4O.Native.NeedsPredicate"));
        }

        this.predicate = (Predicate)predicate;
        setCandidateClassName(this.predicate.extentType().getName());
    }

    /**
     * Method to compile the query.
     * We have nothing to compile with db4o native queries since all is done at execution.
     * @param forExecute Whether to compile ready for execution
     */
    protected void compileInternal(boolean forExecute, Map parameterValues)
    {
    }

    /**
     * Method to return if the query is compiled.
     * @return Whether it is compiled
     */
    protected boolean isCompiled()
    {
        return true;
    }

    /**
     * Method to execute the query.
     * @param parameters Map of parameter values keyed by the name
     * @return The query result
     */
    protected Object performExecute(Map parameters)
    {
        ManagedConnection mconn = ec.getStoreManager().getConnection(ec);
        ObjectContainer cont = (ObjectContainer) mconn.getConnection();
        try
        {
            // Execute the query
            long startTime = System.currentTimeMillis();
            if (NucleusLogger.QUERY.isDebugEnabled())
            {
                NucleusLogger.QUERY.debug(LOCALISER.msg("021046", "Native", getSingleStringQuery()));
            }

            // Try to find any comparator info
            ObjectSet resultSet = null;
            Object comparator = getExtension("db4o.native.comparator");
            if (comparator != null)
            {
                if (comparator instanceof QueryComparator)
                {
                    resultSet = cont.query(predicate, (QueryComparator)comparator);
                }
                else if (comparator instanceof Comparator)
                {
                    resultSet = cont.query(predicate, (Comparator)comparator);
                }
                else
                {
                    throw new NucleusUserException("Native query comparator " + comparator.getClass().getName() +
                        " can only be an instance of QueryComparator or Comparator");
                }
            }
            else
            {
                // No comparator
                resultSet = cont.query(predicate);
            }

            if (NucleusLogger.QUERY.isDebugEnabled())
            {
                NucleusLogger.QUERY.debug(LOCALISER.msg("021074", "Native", "" + (System.currentTimeMillis() - startTime)));
            }

            // Assign StateManagers to any returned persistable objects
            ArrayList results = new ArrayList(resultSet);
            AbstractClassMetaData cmd = null;
            Iterator iter = results.iterator();
            while (iter.hasNext())
            {
                Object obj = iter.next();
                if (ec.getApiAdapter().isPersistable(obj))
                {
                    if (cmd == null)
                    {
                        cmd = ec.getMetaDataManager().getMetaDataForClass(getCandidateClassName(), 
                            ec.getClassLoaderResolver());
                    }
                    DB4OUtils.prepareDB4OObjectForUse(obj, ec, cont, cmd, (DB4OStoreManager)ec.getStoreManager());
                }
            }

            return results;
        }
        finally
        {
            mconn.release();
        }
    }

    /**
     * Convenience method to return whether the query should return a single row.
     * @return Whether a single row should result
     */
    protected boolean shouldReturnSingleRow()
    {
        // We always return the List of objects returned by the query since no other way of knowing if unique
        return false;
    }

    /**
     * Method to return the query as a single string.
     * @return The single string
     */
    public String getSingleStringQuery()
    {
        return "DB4O Native Query <" + candidateClassName + ">";
    }

    /**
     * Method to return the names of the extensions supported by this query.
     * To be overridden by subclasses where they support additional extensions.
     * @return The supported extension names
     */
    public Set getSupportedExtensions()
    {
        Set supported = super.getSupportedExtensions();
        supported.add("db4o.native.comparator");
        return supported;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy