Package org.jpox.store.rdbms.request

Source Code of org.jpox.store.rdbms.request.FetchRequest

/**********************************************************************
Copyright (c) 2002 Mike Martin (TJDO) 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:
2003 Erik Bengtson - throws a JPOXObjectNotFoundException
2003 Erik Bengtson - removed unused variable and import
2003 Andy Jefferson - coding standards
2003 Andy Jefferson - conversion to use Logger
2003 Erik Bengtson - added optimistic
2004 Erik Bengtson - added consumer
2004 Andy Jefferson - added discriminator
2005 Andy Jefferson - added handling of 1-1 bidir FKs
2007 Andy Jefferson - rewritten to select across all inheritance tree tables in one
    ...
**********************************************************************/
package org.jpox.store.rdbms.request;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.jpox.ClassLoaderResolver;
import org.jpox.ManagedConnection;
import org.jpox.ObjectManager;
import org.jpox.StateManager;
import org.jpox.Transaction;
import org.jpox.exceptions.JPOXDataStoreException;
import org.jpox.exceptions.JPOXObjectNotFoundException;
import org.jpox.identity.OID;
import org.jpox.metadata.AbstractClassMetaData;
import org.jpox.metadata.AbstractMemberMetaData;
import org.jpox.metadata.DiscriminatorStrategy;
import org.jpox.metadata.MetaDataManager;
import org.jpox.metadata.Relation;
import org.jpox.metadata.VersionMetaData;
import org.jpox.store.mapped.DatastoreClass;
import org.jpox.store.mapped.DatastoreContainerObject;
import org.jpox.store.mapped.DatastoreField;
import org.jpox.store.mapped.FetchStatement;
import org.jpox.store.mapped.MappedStoreManager;
import org.jpox.store.mapped.SecondaryDatastoreClass;
import org.jpox.store.mapped.StatementExpressionIndex;
import org.jpox.store.mapped.mapping.InterfaceMapping;
import org.jpox.store.mapped.mapping.JavaTypeMapping;
import org.jpox.store.mapped.mapping.MappingCallbacks;
import org.jpox.store.mapped.mapping.MappingConsumer;
import org.jpox.store.mapped.mapping.PersistenceCapableMapping;
import org.jpox.store.rdbms.RDBMSFetchStatement;
import org.jpox.store.rdbms.RDBMSManager;
import org.jpox.store.rdbms.SQLController;
import org.jpox.store.rdbms.fieldmanager.ParameterSetter;
import org.jpox.store.rdbms.fieldmanager.ResultSetGetter;
import org.jpox.store.rdbms.table.AbstractClassTable;
import org.jpox.store.rdbms.table.CollectionTable;
import org.jpox.util.JPOXLogger;
import org.jpox.util.StringUtils;

/**
* Class to retrieve a series of fields for an object of a class from the datastore.
* All fields are retrieved in a single SELECT, selecting a candidate table (the most derived table
* for which a field is required), and INNER JOINs to all superclass tables that are also required.
* <p>
* Any surrogate version stored in this table will be fetched *if* the object being updated doesnt
* already have a value for it. If the caller wants the surrogate version to be updated then
* they should nullify the "transactional" version before calling.
* </p>
*
* @version $Revision: 1.85 $
**/
public class FetchRequest extends Request
{
    /** Callbacks for postFetch() operations, to be called after the fetch itself (relation fields). */
    private final MappingCallbacks[] callbacks;

    private FetchMappingConsumer consumer;

    private MappingStatementIndex mappingStatementIndex;

    private FetchStatement fetchStatement;

    /** Convenience string listing the fields to be fetched by this request. */
    private final String fieldsToFetch;

    /** Number of fields (columns) to fetch, excluding any version column */
    private final int numberOfFieldsToFetch;

    /** cache the statement when generated **/
    private String[] stmt = new String[2];

    /** Whether we are fetching a surrogate version in this fetch. */
    private boolean fetchingSurrogateVersion = false;

    /** Name of the version field (if any). Only applies if the class has a version field (not surrogate). */
    private String versionFieldName = null;

    /** Version MetaData for the class defining the version. */
    private VersionMetaData versionMetaData = null;

    /**
     * Constructor, taking the table. Uses the structure of the datastore table to build a basic query.
     * @param classTable The Class Table representing the datastore table to retrieve
     * @param fieldMetaData MetaData of the fields to retrieve
     * @param cls Class of objects being fetched
     * @param clr ClassLoader resolver
     */
    public FetchRequest(DatastoreClass classTable, AbstractMemberMetaData[] fieldMetaData, Class cls,
        ClassLoaderResolver clr)
    {
        super(classTable);
        AbstractClassMetaData cmd = classTable.getStoreManager().getOMFContext().getMetaDataManager().getMetaDataForClass(cls, clr);

        // Work out the real candidate table.
        // Instead of just taking the most derived table as the candidate we find the table closest to
        // the root table necessary to retrieve the requested fields
        boolean found = false;
        DatastoreClass candidateTable = classTable;
        while (candidateTable != null)
        {
            for (int i=0;i<fieldMetaData.length;i++)
            {
                JavaTypeMapping m = candidateTable.getFieldMappingInDatastoreClass(fieldMetaData[i]);
                if (m != null)
                {
                    found = true;
                    break;
                }
            }
            if (found)
            {
                break;
            }
            candidateTable = candidateTable.getSuperDatastoreClass();
        }
        if (candidateTable == null)
        {
            candidateTable = classTable;
        }
        this.table = candidateTable;
        this.key = ((AbstractClassTable)table).getPrimaryKey();

        mappingStatementIndex = new MappingStatementIndex();
        fetchStatement = new RDBMSFetchStatement(table);

        // Extract the fields to be retrieved
        consumer = new FetchMappingConsumer(fetchStatement, cmd, clr);

        // Include any datastore id mapping for the candidate table
        table.provideDatastoreIdMappings(consumer);

        // Add fields/discriminator in this table and any supertables
        DatastoreClass currentTable = table;
        while (currentTable != null)
        {
            // Add the required fields (and any discriminator) present in this table
            currentTable.provideMappingsForFields(consumer, fieldMetaData, true);
            currentTable.provideDiscriminatorMappings(consumer);
            VersionMetaData currentVermd = currentTable.getVersionMetaData();
            if (currentVermd != null)
            {
                if (currentVermd.getFieldName() == null)
                {
                    // Surrogate version is stored in this table, so fetch it
                    currentTable.provideVersionMappings(consumer);
                    fetchingSurrogateVersion = true;
                    versionMetaData = currentVermd;
                }
                else
                {
                    // Version field
                    versionFieldName = currentVermd.getFieldName();
                    versionMetaData = currentVermd;
                    AbstractMemberMetaData[] mmds = new AbstractMemberMetaData[1];
                    mmds[0] = cmd.getMetaDataForMember(currentVermd.getFieldName());
                    currentTable.provideMappingsForFields(consumer, mmds, true);
                }
            }

            currentTable = currentTable.getSuperDatastoreClass();
        }

        callbacks = (MappingCallbacks[]) consumer.getMappingCallbacks().toArray(
            new MappingCallbacks[consumer.getMappingCallbacks().size()]);

        // Generate string of fields being fetched
        StringBuffer str = new StringBuffer();
        int[] fieldNumbersToFetch = consumer.getNumbersOfFieldsToBeFetched();
        numberOfFieldsToFetch = (fieldNumbersToFetch != null ? fieldNumbersToFetch.length : 0);
        if (fieldNumbersToFetch != null && fieldNumbersToFetch.length > 0)
        {
            for (int i=0;i<fieldNumbersToFetch.length;i++)
            {
                AbstractMemberMetaData fmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumbersToFetch[i]);
                if (i > 0)
                {
                    str.append(",");
                }
                str.append(fmd.getName());
            }
        }
        if (fetchingSurrogateVersion)
        {
            // Add on surrogate version column
            if (str.length() > 0)
            {
                str.append(",");
            }
            str.append("[VERSION]");
        }
        if (str.length() > 0)
        {
            fieldsToFetch = str.toString();
        }
        else
        {
            fieldsToFetch = null;
        }

        // Add the WHERE clause of the fetch (PK mappings)
        if (str.length() > 0)
        {
            this.table.providePrimaryKeyMappings(consumer);
        }
        else
        {
            fetchStatement = null;
        }
    }

    /**
     * Method performing the retrieval of the record from the datastore.
     * Takes the constructed retrieval query and populates with the specific record information.
     *
     * @param sm The state manager for the record to be retrieved
     */
    public void execute(StateManager sm)
    {
        if (fieldsToFetch != null && JPOXLogger.PERSISTENCE.isDebugEnabled())
        {
            // Debug information about what we are retrieving
            JPOXLogger.PERSISTENCE.debug(LOCALISER.msg("052218", StringUtils.toJVMIDString(sm.getObject()),
                fieldsToFetch, table));
        }

        if (isFetchingVersionOnly() && isVersionLoaded(sm))
        {
            // Dont fetch if we have only the version to fetch and it is already loaded
            // Debug comment until we're sure this is a valid thing to do
            JPOXLogger.PERSISTENCE.debug("FetchRequest " + fetchStatement +
                " is to only fetch the version yet it is loaded so omitting the fetch ");
        }
        else if (fetchStatement != null)
        {
            ObjectManager om = sm.getObjectManager();
            RDBMSManager storeMgr = (RDBMSManager)om.getStoreManager();
            Transaction tx = om.getTransaction();
            boolean useUpdateLock = ((Boolean)tx.getOptions().get("transaction.serializeReadObjects")).booleanValue();
            if (stmt[useUpdateLock ? 1 : 0] == null)
            {
                stmt[useUpdateLock ? 1 : 0] = fetchStatement.toString(useUpdateLock);
            }

            try
            {
                ManagedConnection mconn = storeMgr.getConnection(om);
                SQLController sqlControl = storeMgr.getSQLController();

                try
                {
                    PreparedStatement ps = sqlControl.getStatementForQuery(mconn, stmt[useUpdateLock ? 1 : 0]);

                    try
                    {
                        // Provide the primary key field(s)
                        if (sm.getInternalObjectId() instanceof OID)
                        {
                            table.getDataStoreObjectIdMapping().setObject(om, ps,
                                mappingStatementIndex.getDatastoreId().getParameterIndex(), sm.getInternalObjectId());
                        }
                        else
                        {
                            sm.provideFields(consumer.getPrimaryKeyFieldsToBeProvided(),
                                new ParameterSetter(sm, ps, mappingStatementIndex.getFields(), false));
                        }

                        ResultSet rs = sqlControl.executeStatementQuery(mconn, stmt[useUpdateLock ? 1 : 0], ps);
                        try
                        {
                            if (!rs.next())
                            {
                                JPOXLogger.DATASTORE_RETRIEVE.warn(LOCALISER.msg("050018",
                                    sm.getInternalObjectId()));
                                throw new JPOXObjectNotFoundException("No such database row", sm.getInternalObjectId());
                            }
                            sm.replaceFields(consumer.getNumbersOfFieldsToBeFetched(),
                                new ResultSetGetter(sm, rs, mappingStatementIndex.getFields()));

                            if (sm.getTransactionalVersion(sm.getObject()) == null)
                            {
                                // Object has no version set so update it from this fetch
                                Object datastoreVersion = null;
                                if (fetchingSurrogateVersion)
                                {
                                    // Surrogate version column - get from the result set using the version mapping
                                    datastoreVersion = table.getVersionMapping(true).getObject(om, rs, 
                                        mappingStatementIndex.getVersion().getExpressionIndex());
                                }
                                else if (versionFieldName != null)
                                {
                                    // Version field - already populated in the field in the object
                                    AbstractClassMetaData cmd = (AbstractClassMetaData)versionMetaData.getParent();
                                    datastoreVersion = sm.provideField(cmd.getAbsolutePositionOfMember(versionFieldName));
                                }
                                sm.setVersion(datastoreVersion);
                            }
                        }
                        finally
                        {
                            rs.close();
                        }
                    }
                    finally
                    {
                        sqlControl.closeStatement(mconn, ps);
                    }
                }
                finally
                {
                    mconn.release();
                }
            }
            catch (SQLException e)
            {
                String msg = LOCALISER.msg("052219",
                    StringUtils.toJVMIDString(sm.getObject()), stmt[useUpdateLock?1:0], e.getMessage());
                JPOXLogger.DATASTORE_RETRIEVE.warn(msg);
                List exceptions = new ArrayList();
                exceptions.add(e);
                while((e = e.getNextException())!=null)
                {
                    exceptions.add(e);
                }
                throw new JPOXDataStoreException(msg, (Throwable[])exceptions.toArray(new Throwable[exceptions.size()]));
            }
        }

        // Execute any mapping actions now that we have fetched the element
        for (int i = 0; i < callbacks.length; ++i)
        {
            callbacks[i].postFetch(sm);
        }
    }

    /**
     * Convenience method to return if the version field of the managed object is loaded.
     * @param sm StateManager of the object
     * @return Whether the version is loaded
     */
    private boolean isVersionLoaded(StateManager sm)
    {
        return sm.getObject() != null && sm.getObjectManager().getApiAdapter().getVersion(sm) != null;
    }

    /**
     * Convenience method to return if just the version field is being fetched.
     * @return Whether we are just fetching the version field
     */
    private boolean isFetchingVersionOnly()
    {
        return ((fetchingSurrogateVersion || versionFieldName != null) && numberOfFieldsToFetch == 0);
    }

    /**
     * Mapping Consumer used for generating the SELECT statement for an object in a table.
     * This statement will be of the form
     * <PRE>
     * SELECT col1, col2, col3, col4 FROM TABLE WHERE ID = ?
     * </PRE>
     *
     * @version $Revision: 1.85 $
     */
    private class FetchMappingConsumer implements MappingConsumer
    {
        /** Current parameter index. */
        private int paramIndex = 1;

        /** The statement to retrieve the object. This is provided by the caller and updated here. */
        final FetchStatement fetchStmt;

        /** fields to be fetched. */
        List fetchFields = new ArrayList();

        /** pk fields to be provided */
        List pkbp = new ArrayList();

        List mappingCallbacks = new ArrayList();

        /** Flag for initialisation state of the consumer. */
        boolean initialized = false;

        /** ClassLoaderResolver **/
        final ClassLoaderResolver clr;

        /** Store Manager for this datastore. */
        final MappedStoreManager storeMgr;

        final AbstractClassMetaData cmd;

        /**
         * @param fetchStmt The Fetch Statement
         * @param clr The ClassLoaderResolver
         */
        public FetchMappingConsumer(final FetchStatement fetchStmt, AbstractClassMetaData cmd, ClassLoaderResolver clr)
        {
            super();
            this.fetchStmt = fetchStmt;
            this.cmd = cmd;
            this.clr = clr;
            this.storeMgr = table.getStoreManager();
        }

        public void preConsumeMapping(int highestFieldNumber)
        {
            if (!initialized)
            {
                mappingStatementIndex.setPrimaryKeys(new StatementExpressionIndex[highestFieldNumber]);
                mappingStatementIndex.setFields(new StatementExpressionIndex[highestFieldNumber]);
                initialized = true;
            }
        }

        public void consumeMapping(JavaTypeMapping m, AbstractMemberMetaData fmd)
        {
            if (!fmd.getAbstractClassMetaData().isSameOrAncestorOf(cmd))
            {
                return;
            }
            if (m.includeInFetchStatement())
            {
                mappingStatementIndex.getFields()[fmd.getAbsoluteFieldNumber()] = new StatementExpressionIndex();
                mappingStatementIndex.getFields()[fmd.getAbsoluteFieldNumber()].setMapping(m);

                // create the expressions index (columns index)
                int expressionsIndex[] = null;
                if (m.getNumberOfDatastoreFields() == 0 &&
                    (m instanceof PersistenceCapableMapping || m instanceof InterfaceMapping))
                {
                    int relationType = fmd.getRelationType(clr);
                    if (relationType == Relation.ONE_TO_ONE_BI)
                    {
                        MetaDataManager mmgr = storeMgr.getOMFContext().getMetaDataManager();
                        if (fmd.getMappedBy() != null)
                        {
                            // 1-1 bidirectional (non-owner) field (without datastore column(s))
                            Class fieldType = fmd.getType();
                            DatastoreClass relatedTable;
                            String[] clsNames = null;
                            if (fieldType.isInterface())
                            {
                                if (fmd.getFieldTypes() != null && fmd.getFieldTypes().length == 1)
                                {
                                    // Use field-type since only one class specified
                                    Class fldTypeCls = clr.classForName(fmd.getFieldTypes()[0]);
                                    if (fldTypeCls.isInterface())
                                    {
                                        // User has specified an interface, so find its implementations
                                        clsNames = mmgr.getClassesImplementingInterface(fmd.getFieldTypes()[0], clr);
                                    }
                                    else
                                    {
                                        // Use user-provided field-type
                                        clsNames = new String[] {fmd.getFieldTypes()[0]};
                                    }
                                }
                                if (clsNames == null)
                                {
                                    clsNames = mmgr.getClassesImplementingInterface(fieldType.getName(), clr);
                                }
                            }
                            else
                            {
                                clsNames = new String[] { fieldType.getName() };
                            }
                            //only allowed to have association to one table. implementations can be many, but must store to the same table
                            relatedTable = storeMgr.getDatastoreClass(clsNames[0], clr);
                           
                            JavaTypeMapping referenceMapping = relatedTable.getFieldMapping(fmd.getMappedBy());
                            JavaTypeMapping selectMapping = relatedTable.getIDMapping();
                            JavaTypeMapping refDiscrimMapping = relatedTable.getDiscriminatorMapping(false);
                            Object[] discrimValues = null;
                            JavaTypeMapping refTypeMapping = null;

                            expressionsIndex = new int[referenceMapping.getNumberOfDatastoreFields()];
                            if (refDiscrimMapping != null)
                            {
                                // Related table has a discriminator
                                DiscriminatorStrategy strategy = relatedTable.getDiscriminatorMetaData().getStrategy();
                                if (strategy == DiscriminatorStrategy.CLASS_NAME)
                                {
                                    HashSet allclasses = new HashSet();
                                    if (clsNames != null)
                                    {
                                        for (int i=0;i<clsNames.length;i++)
                                        {
                                            allclasses.add(clsNames[i]);
                                        }
                                    }
                                    for( int i=0; i<clsNames.length; i++)
                                    {
                                        HashSet subclasses = storeMgr.getSubClassesForClass(clsNames[i], true, clr);
                                        if (subclasses != null && subclasses.size() > 0)
                                        {
                                            allclasses.addAll(subclasses);
                                        }
                                    }
                                    discrimValues = allclasses.toArray();
                                }
                                else if (strategy == DiscriminatorStrategy.VALUE_MAP)
                                {
                                    HashSet subclasses = storeMgr.getSubClassesForClass(fmd.getTypeName(), true, clr);
                                    if (subclasses != null && subclasses.size() > 0)
                                    {
                                        int valNo = 0;
                                        discrimValues = new Object[subclasses.size()+1];
                                        discrimValues[valNo++] = fmd.getAbstractClassMetaData().getInheritanceMetaData().getDiscriminatorMetaData().getValue();
                                        Iterator subclassesIter = subclasses.iterator();
                                        while (subclassesIter.hasNext())
                                        {
                                            String subclass = (String)subclassesIter.next();
                                            AbstractClassMetaData subclassCmd = mmgr.getMetaDataForClass(subclass, clr);
                                            discrimValues[valNo++] = subclassCmd.getInheritanceMetaData().getDiscriminatorMetaData().getValue();
                                        }
                                    }
                                    else
                                    {
                                        discrimValues = new Object[1];
                                        discrimValues[0] = mmgr.getMetaDataForClass(fmd.getType(), clr).getInheritanceMetaData().getDiscriminatorMetaData().getValue();
                                    }
                                }
                            }
                            else if (relatedTable != referenceMapping.getDataStoreMapping(0).getDatastoreField().getDatastoreContainerObject())
                            {
                                // The reference mapping is stored in a base class and the field actually stores a subclass
                                // so we need to provide the reference type mapping too
                                refTypeMapping = relatedTable.getIDMapping();
                            }

                            if (refTypeMapping == null)
                            {
                                expressionsIndex = fetchStmt.selectOuterJoin(referenceMapping, selectMapping,
                                    refDiscrimMapping, discrimValues, false);
                            }
                            else
                            {
                                expressionsIndex = fetchStmt.selectOuterJoin(referenceMapping, selectMapping,
                                    refTypeMapping);
                            }
                        }
                    }
                    else if (relationType == Relation.MANY_TO_ONE_BI)
                    {
                        AbstractMemberMetaData[] relatedMmds = fmd.getRelatedMemberMetaData(clr);
                        if (fmd.getJoinMetaData() != null || relatedMmds[0].getJoinMetaData() != null)
                        {
                            // N-1 (Join Table) bidirectional field in element class without datastore column(s)
                            DatastoreContainerObject joinTable =
                                storeMgr.getDatastoreContainerObject(relatedMmds[0]);
                            if (joinTable != null)
                            {
                                JavaTypeMapping referenceMapping = null;
                                JavaTypeMapping selectMapping = null;
                                if (java.util.Collection.class.isAssignableFrom(relatedMmds[0].getType()))
                                {
                                    CollectionTable collTable = (CollectionTable)joinTable;
                                    referenceMapping = collTable.getElementMapping();
                                    selectMapping = collTable.getOwnerMapping();
                                }

                                // TODO Do we need to allow for a discriminator in the owner class here ?
                                // TODO Do we need to allow for subclass table here (like in 1-1 case) ?
                                expressionsIndex = fetchStmt.selectOuterJoin(referenceMapping, selectMapping,
                                    null, null, false);
                            }
                        }
                    }
                }
                else
                {
                    DatastoreContainerObject mappingTable = m.getDatastoreContainer();
                    if (fmd.getTable() != null && mappingTable instanceof SecondaryDatastoreClass)
                    {
                        // Secondary table field
                        SecondaryDatastoreClass secTable = (SecondaryDatastoreClass)mappingTable;
                        if (secTable.getJoinMetaData().isOuter())
                        {
                            // Outer join
                            expressionsIndex = fetchStmt.selectOuterJoin(secTable.getIDMapping(), m, null, null, true);
                        }
                        else
                        {
                            // Inner join, so just select the fields and FetchStatement does the rest
                            expressionsIndex = new int[m.getNumberOfDatastoreFields()];
                            for (int i = 0; i < expressionsIndex.length; i++)
                            {
                                expressionsIndex[i] = fetchStmt.select(m.getDataStoreMapping(i).getDatastoreField());
                            }
                        }
                    }
                    else
                    {
                        // Primary table field, with datastore columnhs in the table
                        expressionsIndex = new int[m.getNumberOfDatastoreFields()];
                        for (int i = 0; i < expressionsIndex.length; i++)
                        {
                            expressionsIndex[i] = fetchStmt.select(m.getDataStoreMapping(i).getDatastoreField());
                        }
                    }
                }
                mappingStatementIndex.getFields()[fmd.getAbsoluteFieldNumber()].setExpressionIndex(expressionsIndex);

                /*
                 * check if the our column is primary key. if the
                 * first column for the mapping is primary key,
                 * all columns for the same mapping must be primary key
                 */
                Integer abs_field_num = new Integer(fmd.getAbsoluteFieldNumber());
                if (fmd.isPrimaryKey())
                {
                    int parametersIndex[] = new int[m.getNumberOfDatastoreFields()];
                    for (int j = 0; j < parametersIndex.length; j++)
                    {
                        fetchStmt.andCondition(fetchStmt.referenceDatastoreField(m.getDataStoreMapping(j).getDatastoreField()) + "=?");
                        if (!pkbp.contains(abs_field_num))
                        {
                            pkbp.add(abs_field_num);
                        }
                        parametersIndex[j] = paramIndex++;
                    }
                    mappingStatementIndex.getFields()[fmd.getAbsoluteFieldNumber()].setParameterIndex(parametersIndex);
                }
                else
                {
                    if (!fetchFields.contains(abs_field_num))
                    {
                        fetchFields.add(abs_field_num);
                    }
                }
            }

            if (m instanceof MappingCallbacks)
            {
                mappingCallbacks.add(m);
            }
        }

        /**
         * Consumes a mapping not associated to a field (surrogate columns - version, datastore-identity).
         * @param m The mapping
         * @param mappingType the Mapping type
         */
        public void consumeMapping(JavaTypeMapping m, int mappingType)
        {
            if (mappingType == MappingConsumer.MAPPING_TYPE_VERSION)
            {
                mappingStatementIndex.getVersion().setMapping(m);
                int expressionsIndex[] = new int[m.getNumberOfDatastoreFields()];
                for (int j = 0; j < expressionsIndex.length; j++)
                {
                    expressionsIndex[j] = fetchStmt.select(m.getDataStoreMapping(j).getDatastoreField());
                }
                mappingStatementIndex.getVersion().setExpressionIndex(expressionsIndex);
            }
            else if (mappingType == MappingConsumer.MAPPING_TYPE_DATASTORE_ID)
            {
                fetchStmt.andCondition(fetchStmt.referenceDatastoreField((DatastoreField) key.getColumns().get(0)) + "=?");
                mappingStatementIndex.getDatastoreId().setParameterIndex(new int[]{paramIndex});
                paramIndex++;
            }
        }

        /**
         * Consumer a datastore field without mapping.
         * @param fld The datastore field
         */
        public void consumeUnmappedDatastoreField(DatastoreField fld)
        {
            // Do nothing since we dont handle unmapped columns
        }

        /**
         * @return Returns the mappingCallbacks.
         */
        public List getMappingCallbacks()
        {
            return mappingCallbacks;
        }

        /**
         * Obtain the field numbers which values are to be replaced (the fields that are SELECTed).
         * @return the array of field numbers
         */
        public int[] getNumbersOfFieldsToBeFetched()
        {
            int[] fieldsToBeFetched = new int[fetchFields.size()];
            for (int i = 0; i < fetchFields.size(); ++i)
            {
                fieldsToBeFetched[i] = ((Integer) fetchFields.get(i)).intValue();
            }
            return fieldsToBeFetched;
        }

        /**
         * Obtain the primary key field numbers which values are to be provided by the StateManager
         * @return the array of primary key field numbers
         */          
        public int[] getPrimaryKeyFieldsToBeProvided()
        {
            int[] pkfieldsToBeProvided = new int[pkbp.size()];
            for (int i = 0; i < pkbp.size(); i++)
            {
                pkfieldsToBeProvided[i] = ((Integer) pkbp.get(i)).intValue();
            }
            return pkfieldsToBeProvided;
        }
    }
}
TOP

Related Classes of org.jpox.store.rdbms.request.FetchRequest

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.
=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-20639858-1', 'auto'); ga('send', 'pageview');