Package org.datanucleus.store.rdbms.scostore

Source Code of org.datanucleus.store.rdbms.scostore.RDBMSAbstractListStoreSpecialization

/**********************************************************************
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.rdbms.scostore;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;

import org.datanucleus.ClassLoaderResolver;
import org.datanucleus.exceptions.NucleusDataStoreException;
import org.datanucleus.store.ExecutionContext;
import org.datanucleus.store.ObjectProvider;
import org.datanucleus.store.connection.ManagedConnection;
import org.datanucleus.store.mapped.DatastoreContainerObject;
import org.datanucleus.store.mapped.exceptions.MappedDatastoreException;
import org.datanucleus.store.mapped.mapping.JavaTypeMapping;
import org.datanucleus.store.mapped.scostore.AbstractListStoreSpecialization;
import org.datanucleus.store.mapped.scostore.ElementContainerStore;
import org.datanucleus.store.rdbms.JDBCUtils;
import org.datanucleus.store.rdbms.RDBMSStoreManager;
import org.datanucleus.store.rdbms.SQLController;
import org.datanucleus.store.rdbms.mapping.RDBMSMapping;
import org.datanucleus.util.Localiser;

/**
* RDBMS-specific implementation of an {@link AbstractListStoreSpecialization}.
*/
abstract class RDBMSAbstractListStoreSpecialization extends RDBMSAbstractCollectionStoreSpecialization
        implements AbstractListStoreSpecialization
{
    protected String removeAtStmt;
    protected String setStmt;
    protected String shiftStmt;
    protected String indexOfStmt;
    protected String lastIndexOfStmt;

    RDBMSAbstractListStoreSpecialization(Localiser localiser, ClassLoaderResolver clr, RDBMSStoreManager storeMgr)
    {
        super(localiser, clr, storeMgr);
    }

    /**
     * Generate statement for getting the index of an item.
     * <PRE>
     * SELECT INDEXCOL FROM LISTTABLE
     * WHERE OWNERCOL=?
     * AND ELEMENTCOL=?
     * [AND EMBEDDEDFIELD1=? AND EMBEDDEDFIELD2=? AND ...]
     * [AND DISTINGUISHER=?]
     * ORDER BY INDEXCOL
     * </PRE>
     * @return The Statement for getting the index of an item
     */
    protected String getIndexOfStmt(ElementContainerStore ecs)
    {
        if (indexOfStmt == null)
        {
            JavaTypeMapping ownerMapping = ecs.getOwnerMapping();
            JavaTypeMapping orderMapping = ecs.getOrderMapping();
            DatastoreContainerObject containerTable = ecs.getContainerTable();
            JavaTypeMapping elementMapping = ecs.getElementMapping();
            JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();

            StringBuffer stmt = new StringBuffer();
            stmt.append("SELECT ");
            for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(",");
                }
                stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
            }
            stmt.append(" FROM ");
            stmt.append(containerTable.toString());
            stmt.append(" WHERE ");
            for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(" AND ");
                }
                stmt.append(ownerMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) ownerMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }

            for (int i = 0; i < elementMapping.getNumberOfDatastoreMappings(); i++)
            {
                stmt.append(" AND ");
                stmt.append(elementMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) elementMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }
            if (relationDiscriminatorMapping != null)
            {
                for (int i = 0; i < relationDiscriminatorMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(" AND ");
                    stmt.append(relationDiscriminatorMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                    stmt.append(" = ");
                    stmt.append(((RDBMSMapping) relationDiscriminatorMapping.getDatastoreMapping(i)).getUpdateInputParameter());
                }
            }

            stmt.append(" ORDER BY ");
            for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(",");
                }
                stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
            }
            indexOfStmt = stmt.toString();
        }
        return indexOfStmt;
    }

    /**
     * Generates the statement for getting the index of the last item.
     *
     * <PRE>
     * SELECT INDEXCOL FROM LISTTABLE
     * WHERE OWNERCOL=?
     * AND ELEMENTCOL=?
     * [AND EMBEDDEDFIELD1=? AND EMBEDDEDFIELD2=? AND ...]
     * [AND DISTINGUISHER=?]
     * ORDER BY INDEXCOL DESC
     * </PRE>
     * @return The Statement for getting the last item
     */
    protected String getLastIndexOfStmt(ElementContainerStore ecs)
    {
        if (lastIndexOfStmt == null)
        {
            JavaTypeMapping ownerMapping = ecs.getOwnerMapping();
            JavaTypeMapping orderMapping = ecs.getOrderMapping();
            DatastoreContainerObject containerTable = ecs.getContainerTable();
            JavaTypeMapping elementMapping = ecs.getElementMapping();
            JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();

            StringBuffer stmt = new StringBuffer();
            stmt.append("SELECT ");
            for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(",");
                }
                stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
            }
            stmt.append(" FROM ");
            stmt.append(containerTable.toString());
            stmt.append(" WHERE ");

            for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(" AND ");
                }
                stmt.append(ownerMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) ownerMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }

            for (int i = 0; i < elementMapping.getNumberOfDatastoreMappings(); i++)
            {
                stmt.append(" AND ");
                stmt.append(elementMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) elementMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }
            if (relationDiscriminatorMapping != null)
            {
                for (int i = 0; i < relationDiscriminatorMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(" AND ");
                    stmt.append(relationDiscriminatorMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                    stmt.append(" = ");
                    stmt.append(((RDBMSMapping) relationDiscriminatorMapping.getDatastoreMapping(i)).getUpdateInputParameter());
                }
            }

            stmt.append(" ORDER BY ");
            for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(",");
                }
                stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" DESC ");
            }
            lastIndexOfStmt = stmt.toString();
        }
        return lastIndexOfStmt;
    }

    /**
     * Generates the statement for removing an item.
     *
     * <PRE>
     * DELETE FROM LISTTABLE
     * WHERE OWNERCOL = ?
     * AND INDEXCOL = ?
     * [AND DISTINGUISHER=?]
     * </PRE>
     * @return The Statement for removing an item from a position
     */
    protected String getRemoveAtStmt(ElementContainerStore ecs)
    {
        if (removeAtStmt == null)
        {
            JavaTypeMapping ownerMapping = ecs.getOwnerMapping();
            JavaTypeMapping orderMapping = ecs.getOrderMapping();
            DatastoreContainerObject containerTable = ecs.getContainerTable();
            JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();

            StringBuffer stmt = new StringBuffer();
            stmt.append("DELETE FROM ");
            stmt.append(containerTable.toString());
            stmt.append(" WHERE ");

            for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(" AND ");
                }
                stmt.append(ownerMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) ownerMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }

            for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
            {
                stmt.append(" AND ");
                stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) orderMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }
            if (relationDiscriminatorMapping != null)
            {
                for (int i = 0; i < relationDiscriminatorMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(" AND ");
                    stmt.append(relationDiscriminatorMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                    stmt.append(" = ");
                    stmt.append(((RDBMSMapping) relationDiscriminatorMapping.getDatastoreMapping(i)).getUpdateInputParameter());
                }
            }
            removeAtStmt = stmt.toString();
        }
        return removeAtStmt;
    }

    /**
     * Generates the statement for shifting items.
     *
     * <PRE>
     * UPDATE LISTTABLE SET INDEXCOL = ?
     * WHERE OWNERCOL = ?
     * AND INDEXCOL = ?
     * [AND DISTINGUISHER=?]
     * </PRE>
     * @return The Statement for shifting elements
     */
    protected String getShiftStmt(ElementContainerStore ecs)
    {
        if (shiftStmt == null)
        {
            JavaTypeMapping ownerMapping = ecs.getOwnerMapping();
            JavaTypeMapping orderMapping = ecs.getOrderMapping();
            DatastoreContainerObject containerTable = ecs.getContainerTable();
            JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();

            StringBuffer stmt = new StringBuffer();
            stmt.append("UPDATE ");
            stmt.append(containerTable.toString());
            stmt.append(" SET ");

            for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(",");
                }
                stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) orderMapping.getDatastoreMapping(i)).getUpdateInputParameter());
                stmt.append(" + ");
                stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
            }

            stmt.append(" WHERE ");
            for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(" AND ");
                }
                stmt.append(ownerMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) ownerMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }

            for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
            {
                stmt.append(" AND ");
                stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) orderMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }
            if (relationDiscriminatorMapping != null)
            {
                for (int i = 0; i < relationDiscriminatorMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(" AND ");
                    stmt.append(relationDiscriminatorMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                    stmt.append(" = ");
                    stmt.append(((RDBMSMapping) relationDiscriminatorMapping.getDatastoreMapping(i)).getUpdateInputParameter());
                }
            }
            shiftStmt = stmt.toString();
        }
        return shiftStmt;
    }

    /**
     * Generates the statement for getting the indices of a collection of element. Order into descending index order
     * (highest first) so they will NOT be in the same order as they appear in the input collection "elements".
     *
     * <PRE>
     * SELECT INDEXCOL FROM LISTTABLE
     * WHERE (OWNERCOL=? AND ELEMENT_COL=? [AND DISTINGUISHER=?]) OR
     *       (OWNERCOL=? AND ELEMENT_COL=? [AND DISTINGUISHER=?]) OR
     *       (OWNERCOL=? AND ELEMENT_COL=? [AND DISTINGUISHER=?])
     * ORDER BY INDEXCOL DESC
     * </PRE>
     * @param elements The elements to retrieve the indices for.
     * @return The Statement for getting the indices of the collection.
     */
    protected String getIndicesOfStmt(Collection elements, ElementContainerStore ecs)
    {
        JavaTypeMapping ownerMapping = ecs.getOwnerMapping();
        JavaTypeMapping orderMapping = ecs.getOrderMapping();
        DatastoreContainerObject containerTable = ecs.getContainerTable();
        JavaTypeMapping elementMapping = ecs.getElementMapping();
        JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();

        StringBuffer stmt = new StringBuffer();
        stmt.append("SELECT ");
        for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
        {
            if (i > 0)
            {
                stmt.append(",");
            }
            stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
        }
        stmt.append(" FROM ");
        stmt.append(containerTable.toString());
        stmt.append(" WHERE ");
        Iterator iter = elements.iterator();
        boolean first_element = true;
        while (iter.hasNext())
        {
            iter.next(); // Move to next element

            if (!first_element)
            {
                stmt.append(" OR (");
            }
            else
            {
                stmt.append("(");
            }

            for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(" AND ");
                }
                stmt.append(ownerMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) ownerMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }

            for (int i = 0; i < elementMapping.getNumberOfDatastoreMappings(); i++)
            {
                stmt.append(" AND ");
                stmt.append(elementMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) elementMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }
            if (relationDiscriminatorMapping != null)
            {
                for (int i = 0; i < relationDiscriminatorMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(" AND ");
                    stmt.append(relationDiscriminatorMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                    stmt.append(" = ");
                    stmt.append(((RDBMSMapping) relationDiscriminatorMapping.getDatastoreMapping(i)).getUpdateInputParameter());
                }
            }

            stmt.append(")");
            first_element = false;
        }

        stmt.append(" ORDER BY ");
        for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
        {
            if (i > 0)
            {
                stmt.append(",");
            }
            stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
            stmt.append(" DESC");
        }

        return stmt.toString();
    }

    /**
     * Method to prepare the indicesOf statement for use. Populates the various parameters. This is required because the
     * query is built dynamically depending on the number of elements to retrieve the indices for.
     * @param sm State Manager of the container.
     * @param ps The Prepared Statement
     * @param elements Collection of elements
     **/
    protected void prepareIndicesOfStmt(ObjectProvider sm, PreparedStatement ps, Collection elements,
            ElementContainerStore ecs)
    {
        if (elements == null || elements.size() == 0)
        {
            return;
        }

        ExecutionContext ec = sm.getExecutionContext();
        Iterator iter = elements.iterator();
        int jdbcPosition = 1;
        while (iter.hasNext())
        {
            Object element = iter.next();

            jdbcPosition = BackingStoreHelper.populateOwnerInStatement(sm, ec, ps, jdbcPosition, ecs);
            jdbcPosition = BackingStoreHelper.populateElementInStatement(ec, ps, element, jdbcPosition, ecs.getElementMapping());
            if (ecs.getRelationDiscriminatorMapping() != null)
            {
                jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, ecs);
            }
        }
    }

    /**
     * Internal method to find the index of an element.
     * @param sm The state manager.
     * @param element The element
     * @param stmt The statement to find the element.
     * @return The index of the element in the List.
     **/
    protected int internalIndexOf(ObjectProvider sm, Object element, String stmt, ElementContainerStore ecs)
    {
        try
        {
            ExecutionContext ec = sm.getExecutionContext();
            ManagedConnection mconn = ecs.getStoreManager().getConnection(ec);
            SQLController sqlControl = storeMgr.getSQLController();
            try
            {
                PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, stmt, false);
                try
                {
                    int jdbcPosition = 1;
                    jdbcPosition = BackingStoreHelper.populateOwnerInStatement(sm, ec, ps, jdbcPosition, ecs);
                    jdbcPosition = BackingStoreHelper.populateElementInStatement(ec, ps, element, jdbcPosition, ecs.getElementMapping());
                    if (ecs.getRelationDiscriminatorMapping() != null)
                    {
                        jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, ecs);
                    }

                    ResultSet rs = sqlControl.executeStatementQuery(mconn, stmt, ps);
                    try
                    {
                        boolean found = rs.next();
                        if (!found)
                        {
                            JDBCUtils.logWarnings(rs);
                            return -1;
                        }
                        int index = rs.getInt(1);
                        JDBCUtils.logWarnings(rs);
                        return index;
                    }
                    finally
                    {
                        rs.close();
                    }
                }
                finally
                {
                    sqlControl.closeStatement(mconn, ps);
                }
            }
            finally
            {
                mconn.release();
            }
        }
        catch (SQLException e)
        {
            throw new NucleusDataStoreException(localiser.msg("056017", stmt), e);
        }
    }

    public int indexOf(ObjectProvider sm, Object element, ElementContainerStore ecs)
    {
        return internalIndexOf(sm, element, getIndexOfStmt(ecs), ecs);
    }

    public int lastIndexOf(ObjectProvider sm, Object element, ElementContainerStore ecs)
    {
        return internalIndexOf(sm, element, getLastIndexOfStmt(ecs), ecs);
    }

    public int[] getIndicesOf(ObjectProvider sm, Collection elements, ElementContainerStore ecs)
    {
        String stmt = getIndicesOfStmt(elements, ecs);
        int[] indices = new int[elements.size()];
        try
        {
            ExecutionContext ec = sm.getExecutionContext();
            ManagedConnection mconn = ecs.getStoreManager().getConnection(ec);
            SQLController sqlControl = storeMgr.getSQLController();
            try
            {
                PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, stmt, false);
                try
                {
                    prepareIndicesOfStmt(sm, ps, elements, ecs);

                    ResultSet rs = sqlControl.executeStatementQuery(mconn, stmt, ps);
                    try
                    {
                        int i = 0;
                        while (rs.next())
                        {
                            indices[i++] = rs.getInt(1);
                        }

                        if (i < elements.size())
                        {
                            throw new NucleusDataStoreException(localiser.msg("056023", stmt));
                        }
                        JDBCUtils.logWarnings(rs);
                    }
                    finally
                    {
                        rs.close();
                    }
                }
                finally
                {
                    sqlControl.closeStatement(mconn, ps);
                }
            }
            finally
            {
                mconn.release();
            }
        }
        catch (SQLException e)
        {
            throw new NucleusDataStoreException(localiser.msg("056017", stmt), e);
        }

        return indices;
    }

    /**
     * Internal method to remove an object at a location in the List.
     * @param sm The state manager.
     * @param index The location
     * @param stmt The statement to remove the element from the List
     * @param size Current list size (if known). -1 if not known
     */
    protected void internalRemoveAt(ObjectProvider sm, int index, String stmt, int size,
            ElementContainerStore ecs)
    {
        int currentListSize = 0;
        if (size < 0)
        {
            // Get the current size from the datastore
            currentListSize = ecs.size(sm);
        }
        else
        {
            currentListSize = size;
        }

        ExecutionContext ec = sm.getExecutionContext();
        try
        {
            ManagedConnection mconn = ecs.getStoreManager().getConnection(ec);
            SQLController sqlControl = storeMgr.getSQLController();
            try
            {
                PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, stmt, false);
                try
                {
                    int jdbcPosition = 1;
                    jdbcPosition = BackingStoreHelper.populateOwnerInStatement(sm, ec, ps, jdbcPosition, ecs);
                    jdbcPosition = BackingStoreHelper.populateOrderInStatement(ec, ps, index, jdbcPosition, ecs.getOrderMapping());
                    if (ecs.getRelationDiscriminatorMapping() != null)
                    {
                        jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, ecs);
                    }

                    int[] rowsDeleted = sqlControl.executeStatementUpdate(mconn, stmt, ps, true);
                    if (rowsDeleted[0] == 0)
                    {
                        // ?? throw exception??
                    }
                }
                finally
                {
                    sqlControl.closeStatement(mconn, ps);
                }

                // shift down
                if (index != currentListSize - 1)
                {
                    for (int i = index + 1; i < currentListSize; i++)
                    {
                        // Shift this index down 1
                        internalShift(sm, mconn, false, i, -1, true, ecs);
                    }
                }
            }
            finally
            {
                mconn.release();
            }
        }
        catch (SQLException e)
        {
            throw new NucleusDataStoreException(localiser.msg("056012", stmt), e);
        }
        catch (MappedDatastoreException e)
        {
            throw new NucleusDataStoreException(localiser.msg("056012", stmt), e);
        }
    }

    /**
     * Method to process a "shift" statement, updating the index in the list of the specified index.
     * @param ownerSM StateManager of the owner
     * @param conn The connection
     * @param batched Whether the statement is batched
     * @param oldIndex The old index
     * @param amount Amount to shift by (negative means shift down)
     * @param executeNow Whether to execute the statement now (or wait for batching)
     * @return Return code(s) from any executed statements
     * @throws MappedDatastoreException Thrown if an error occurs
     */
    public int[] internalShift(ObjectProvider ownerSM, ManagedConnection conn, boolean batched, int oldIndex,
            int amount, boolean executeNow, ElementContainerStore ecs) throws MappedDatastoreException
    {
        JavaTypeMapping orderMapping = ecs.getOrderMapping();
        JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();

        ExecutionContext ec = ownerSM.getExecutionContext();
        SQLController sqlControl = storeMgr.getSQLController();
        String shiftStmt = getShiftStmt(ecs);
        try
        {
            PreparedStatement ps = sqlControl.getStatementForUpdate(conn, shiftStmt, false);
            try
            {
                int jdbcPosition = 1;
                jdbcPosition = BackingStoreHelper.populateOrderInStatement(ec, ps, amount, jdbcPosition, orderMapping);
                jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerSM, ec, ps, jdbcPosition, ecs);
                jdbcPosition = BackingStoreHelper.populateOrderInStatement(ec, ps, oldIndex, jdbcPosition, orderMapping);
                if (relationDiscriminatorMapping != null)
                {
                    jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, ecs);
                }

                // Execute the statement
                return sqlControl.executeStatementUpdate(conn, shiftStmt, ps, executeNow);
            }
            finally
            {
                sqlControl.closeStatement(conn, ps);
            }
        }
        catch (SQLException sqle)
        {
            String stmt = getShiftStmt(ecs);
            throw new MappedDatastoreException(stmt, sqle);
        }
    }
}
TOP

Related Classes of org.datanucleus.store.rdbms.scostore.RDBMSAbstractListStoreSpecialization

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.