Package org.datanucleus.store.mapped.scostore

Source Code of org.datanucleus.store.mapped.scostore.AbstractCollectionStore

/**********************************************************************
Copyright (c) 2005 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.mapped.scostore;

import java.util.Collection;

import org.datanucleus.ClassLoaderResolver;
import org.datanucleus.StateManager;
import org.datanucleus.store.StoreManager;
import org.datanucleus.store.mapped.DatastoreIdentifier;
import org.datanucleus.store.mapped.expression.CollectionStoreQueryable;
import org.datanucleus.store.mapped.expression.LogicSetExpression;
import org.datanucleus.store.mapped.expression.QueryExpression;
import org.datanucleus.store.mapped.expression.ScalarExpression;
import org.datanucleus.store.mapped.expression.StringLiteral;
import org.datanucleus.store.mapped.mapping.EmbeddedElementPCMapping;
import org.datanucleus.store.mapped.mapping.JavaTypeMapping;
import org.datanucleus.store.scostore.CollectionStore;

/**
* Abstract representation of a store of a Collection.
* Contains all common parts of storing Sets and Lists.
*/
public abstract class AbstractCollectionStore extends ElementContainerStore
    implements CollectionStore, CollectionStoreQueryable
{
    /**
     * Constructor.
     * @param storeMgr Manager for the store
     * @param clr ClassLoader resolver
     */
    protected AbstractCollectionStore(StoreManager storeMgr, ClassLoaderResolver clr,
            AbstractCollectionStoreSpecialization abstractCollectionStoreSpecialization)
    {
        super(storeMgr, clr, abstractCollectionStoreSpecialization);
    }

    /**
     * Method to update a field of an embedded element.
     * @param sm State Manager of the owner
     * @param element The element to update
     * @param fieldNumber The number of the field to update
     * @param value The value
     * @return true if the datastore was updated
     */
    public boolean updateEmbeddedElement(StateManager sm, Object element, int fieldNumber, Object value)
    {
        boolean modified = false;
        if (elementMapping != null && elementMapping instanceof EmbeddedElementPCMapping)
        {
            String fieldName = emd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber).getName();
            if (fieldName == null)
            {
                // We have no mapping for this field so presumably is the owner field or a PK field
                return false;
            }
            JavaTypeMapping fieldMapping = ((EmbeddedElementPCMapping)elementMapping).getJavaTypeMapping(fieldName);
            if (fieldMapping == null)
            {
                // We have no mapping for this field so presumably is the owner field or a PK field
                return false;
            }
            modified = getSpecialization().updateEmbeddedElement(sm, element,
                fieldNumber, value, fieldMapping, this);
        }

        return modified;
    }

    private AbstractCollectionStoreSpecialization getSpecialization()
    {
        return (AbstractCollectionStoreSpecialization) specialization;
    }

  /**
     * Method to update the collection to be the supplied collection of elements.
     * @param sm StateManager of the object
     * @param coll The collection to use
     */
    public void update(StateManager sm, Collection coll)
    {
        // Crude update - remove existing and add new!
        clear(sm);
        addAll(sm, coll, 0);
    }

    /**
     * Method to verify if the association owner vs elements contains
     * a specific element in the association
     * @param sm The StateManager
     * @param element The element
     * @return Whether it contains the element
     */
    public boolean contains(StateManager sm, Object element)
    {
        if (!validateElementForReading(sm, element))
        {
            return false;
        }
        return getSpecialization().contains(sm, element, this);
    }

    // ----------------------------- TODO Remove these when we replace JDOQL -----------------------------------

    /**
     * Query utility to generate an exists() statement for an element.
     * The generated query will be of the form
     * <PRE>
     * SELECT 1 FROM JOINTABLE THIS_JOIN WHERE THIS_JOIN.OWNER_ID_OID = THIS.OWNER_ID
     * </PRE>
     * @param qs The parent query statement that will use this as a subquery
     * @param mapping mapping for the owner
     * @param ownerTe Expression for the table that the subquery should join to
     * @param collectionTableAlias alias for the main table of the subquery
     * @return The query statement
     */
    public QueryExpression getExistsSubquery(QueryExpression qs, JavaTypeMapping mapping,
            LogicSetExpression ownerTe, DatastoreIdentifier collectionTableAlias)
    {
        QueryExpression stmt = dba.newQueryStatement(containerTable, collectionTableAlias,
            qs.getClassLoaderResolver());
        stmt.setParent(qs);

        // Join for the owner
        ScalarExpression ownerExpr = mapping.newScalarExpression(stmt, ownerTe);
        ScalarExpression ownerInCollectionExpr = ownerMapping.newScalarExpression(stmt,
            stmt.getTableExpression(collectionTableAlias));
        stmt.andCondition(ownerExpr.eq(ownerInCollectionExpr));

        // Select id mapping of element
        stmt.select(collectionTableAlias, elementMapping);

        return stmt;
    }

    /**
     * Query utility to generate a subquery for the size() of the collection.
     * The generated query will be of the form
     * <PRE>
     * SELECT COUNT(*) FROM JOINTABLE THIS_JOIN WHERE THIS_JOIN.OWNER_ID_OID = THIS.OWNER_ID
     * </PRE>
     * @param qs The parent query statement that will use this as a subquery
     * @param mapping mapping of the field
     * @param ownerTe Expression for the owner table that the subquery should join to
     * @param collectionTableAlias alias for the main table of the subquery
     * @return The query statement
     */
    public QueryExpression getSizeSubquery(QueryExpression qs, JavaTypeMapping mapping,
            LogicSetExpression ownerTe, DatastoreIdentifier collectionTableAlias)
    {
        QueryExpression stmt = dba.newQueryStatement(containerTable, collectionTableAlias,
            qs.getClassLoaderResolver());
        stmt.setParent(qs);

        // Join for the owner
        ScalarExpression ownerExpr = mapping.newScalarExpression(stmt, ownerTe);
        ScalarExpression ownerInCollectionExpr = ownerMapping.newScalarExpression(stmt,
            stmt.getTableExpression(collectionTableAlias));
        stmt.andCondition(ownerExpr.eq(ownerInCollectionExpr));

        // Select COUNT(*)
        JavaTypeMapping m = storeMgr.getMappingManager().getMapping(String.class);
        StringLiteral lit = (StringLiteral)m.newLiteral(stmt, "COUNT(*)");
        lit.generateStatementWithoutQuotes();
        stmt.selectScalarExpression(lit);

        // TODO This needs to restrict the discriminator also where it is present (see sizeStmt)

        return stmt;
    }
}
TOP

Related Classes of org.datanucleus.store.mapped.scostore.AbstractCollectionStore

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.