Package org.jpox.store.rdbms.request

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

/**********************************************************************
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:
    ...
**********************************************************************/
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.List;

import org.jpox.ManagedConnection;
import org.jpox.ObjectManager;
import org.jpox.StateManager;
import org.jpox.exceptions.JPOXDataStoreException;
import org.jpox.exceptions.JPOXObjectNotFoundException;
import org.jpox.identity.OID;
import org.jpox.metadata.AbstractMemberMetaData;
import org.jpox.store.mapped.DatastoreClass;
import org.jpox.store.mapped.DatastoreField;
import org.jpox.store.mapped.FetchStatement;
import org.jpox.store.mapped.StatementExpressionIndex;
import org.jpox.store.mapped.mapping.JavaTypeMapping;
import org.jpox.store.mapped.mapping.MappingConsumer;
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.util.JPOXLogger;
import org.jpox.util.StringUtils;

/**
* Class to locate a record in the data store.
* Extends basic request class implementing the execute method to do a JDBC select operation.
*
* @version $Revision: 1.35 $
**/
public class LocateRequest extends Request
{
    /** Index of the statements. */
    private final MappingStatementIndex mappingStatementIndex;

    /** SQL statement for the locate. */
    private final String locateStmt;

    /** Numbers of Primary key fields. */
    private final int[] pkFieldNumbers;

    /**
     * Constructor, taking the table. Uses the structure of the datastore
     * table to build a basic query.
     * @param table The Class Table representing the datastore table to retrieve
     **/
    public LocateRequest(DatastoreClass table)
    {
        super(table);

        mappingStatementIndex = new MappingStatementIndex();
        FetchStatement fetchStmt = new RDBMSFetchStatement(table);
        FetchMappingConsumer consumer = new FetchMappingConsumer(fetchStmt);
        fetchStmt.select("1");
        table.provideDatastoreIdMappings(consumer);
        table.providePrimaryKeyMappings(consumer);

        locateStmt = fetchStmt.toString();
        pkFieldNumbers = consumer.getPrimaryKeyFieldNumbers();
    }

    /**
     * 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 (locateStmt != null)
        {
            ObjectManager om = sm.getObjectManager();
            RDBMSManager storeMgr = (RDBMSManager)om.getStoreManager();
            try
            {
                ManagedConnection mconn = storeMgr.getConnection(om);
                SQLController sqlControl = storeMgr.getSQLController();

                try
                {
                    PreparedStatement ps = sqlControl.getStatementForQuery(mconn, locateStmt);

                    try
                    {
                        if (sm.getInternalObjectId() instanceof OID)
                        {
                            // datastore identity
                            table.getDataStoreObjectIdMapping().setObject(om, ps,
                                mappingStatementIndex.getDatastoreId().getParameterIndex(),
                                sm.getInternalObjectId());
                        }
                        else
                        {
                            // application identity - provide primary key fields
                            sm.provideFields(pkFieldNumbers, new ParameterSetter(sm, ps,
                                mappingStatementIndex.getFields(), false));
                        }

                        ResultSet rs = sqlControl.executeStatementQuery(mconn, locateStmt, ps);
                        try
                        {
                            if (!rs.next())
                            {
                                JPOXLogger.DATASTORE_RETRIEVE.info(LOCALISER.msg("050018",
                                    sm.getInternalObjectId()));
                                throw new JPOXObjectNotFoundException("No such database row", sm.getInternalObjectId());
                            }
                        }
                        finally
                        {
                            rs.close();
                        }
                    }
                    finally
                    {
                        sqlControl.closeStatement(mconn, ps);
                    }
                }
                finally
                {
                    mconn.release();
                }
            }
            catch (SQLException e)
            {
                String msg = LOCALISER.msg("052220",
                    StringUtils.toJVMIDString(sm.getObject()), locateStmt, 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()]));
            }
        }
    }

    private class FetchMappingConsumer implements MappingConsumer
    {
        private int paramIndex = 1;

        final FetchStatement fetchStmt;

        /** PK fields numbers. */
        List pkFields = new ArrayList();

        boolean initialized = false;
       
        /**
         * @param fetchStmt
         */
        public FetchMappingConsumer(final FetchStatement fetchStmt)
        {
            super();
            this.fetchStmt = fetchStmt;
        }
       
        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 (m.includeInFetchStatement())
            {
                mappingStatementIndex.getFields()[fmd.getAbsoluteFieldNumber()] = new StatementExpressionIndex();
                mappingStatementIndex.getFields()[fmd.getAbsoluteFieldNumber()].setMapping(m);

                /*
                 * 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
                 */
                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()) + " = ?");
                       
                        pkFields.add(new Integer(fmd.getAbsoluteFieldNumber()));
                       
                        parametersIndex[j] = paramIndex++;
                    }
                    mappingStatementIndex.getFields()[fmd.getAbsoluteFieldNumber()].setParameterIndex(parametersIndex);
                }
            }
         
        }
       
        /**
         * Consumes a mapping not associated to a field (surrogate columns etc).
         * @param m Mapping
         * @param mappingType the Mapping type
         */
        public void consumeMapping(JavaTypeMapping m, int mappingType)
        {
          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
        }

        /**
         * 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[] getPrimaryKeyFieldNumbers()
        {
            int[] fieldNumbers = new int[pkFields.size()];
            for (int i = 0; i < pkFields.size(); i++)
            {
                fieldNumbers[i] = ((Integer) pkFields.get(i)).intValue();
            }
            return fieldNumbers;
        }      
    }
}
TOP

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

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.