Package org.datanucleus.store.rdbms.scostore

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

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

import org.datanucleus.ClassLoaderResolver;
import org.datanucleus.exceptions.NucleusDataStoreException;
import org.datanucleus.metadata.AbstractMemberMetaData;
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.mapping.JavaTypeMapping;
import org.datanucleus.store.mapped.mapping.MappingHelper;
import org.datanucleus.store.mapped.scostore.ElementContainerStore;
import org.datanucleus.store.mapped.scostore.FKListStore;
import org.datanucleus.store.mapped.scostore.FKListStoreSpecialization;
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 FKListStoreSpecialization}.
*/
public class RDBMSFKListStoreSpecialization extends RDBMSAbstractListStoreSpecialization implements FKListStoreSpecialization
{
    private String unsetStmt;

    private String removeAtNullifyStmt;

    private String clearNullifyStmt;

    /** Statement for updating a foreign key in a 1-N unidirectional */
    private String updateFkStmt;

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

    /**
     * Generates the statement for setting an item to be at a position.
     * <PRE>
     * UPDATE LISTTABLE SET OWNERCOL=?, INDEXCOL = ? [,DISTINGUISHER=?]
     * WHERE ELEMENTCOL = ?
     * </PRE>
     * @return The Statement for setting an item
     */
    protected String getSetStmt(ElementContainerStore ecs)
    {
        if (setStmt == 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("UPDATE ");
            stmt.append(containerTable.toString()); // TODO Allow for multiple element tables
            stmt.append(" SET ");
            for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(",");
                }
                stmt.append(ownerMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) ownerMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }

            if (orderMapping != null)
            {
                for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(",");
                    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(",");
                    stmt.append(relationDiscriminatorMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                    stmt.append(" = ");
                    stmt.append(((RDBMSMapping) relationDiscriminatorMapping.getDatastoreMapping(i)).getUpdateInputParameter());
                }
            }

            stmt.append(" WHERE ");

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

        return setStmt;
    }

    /**
     * Generates the statement for unsetting an item from a list position.
     * <PRE>
     * UPDATE LISTTABLE SET OWNERCOL=NULL, INDEXCOL=-1 [, DISTINGUISHER = NULL]
     * WHERE OWNERCOL = ? AND INDEXCOL = ? [AND DISTINGUISHER = ?]
     * </PRE>
     * @return The Statement for unsetting an item
     */
    protected String getUnsetStmt(ElementContainerStore ecs)
    {
        if (unsetStmt == null)
        {
            JavaTypeMapping ownerMapping = ecs.getOwnerMapping();
            JavaTypeMapping orderMapping = ecs.getOrderMapping();
            DatastoreContainerObject containerTable = ecs.getContainerTable();
            JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();

            StringBuffer stmt = new StringBuffer();
            stmt.append("UPDATE ");
            // TODO Allow for multiple element tables
            stmt.append(containerTable.toString());
            stmt.append(" SET ");
            for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(",");
                }
                stmt.append(ownerMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = NULL");
            }

            if (orderMapping != null)
            {
                for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(",");
                    stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                    stmt.append("=-1");
                }
            }
            if (relationDiscriminatorMapping != null)
            {
                for (int i = 0; i < relationDiscriminatorMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(",");
                    stmt.append(relationDiscriminatorMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                    stmt.append(" = NULL");
                }
            }

            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());
            }
            if (orderMapping != null)
            {
                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());
                }
            }
            unsetStmt = stmt.toString();
        }
        return unsetStmt;
    }

    public Object set(ObjectProvider sm, int index, Object element, boolean allowDependentField,
            ElementContainerStore ecs, Object obj)
    {
        String setStmt = getSetStmt(ecs);
        String unsetStmt = getUnsetStmt(ecs);

        JavaTypeMapping orderMapping = ecs.getOrderMapping();
        JavaTypeMapping elementMapping = ecs.getElementMapping();
        JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();

        try
        {
            ExecutionContext ec = sm.getExecutionContext();
            ManagedConnection mconn = ecs.getStoreManager().getConnection(ec);
            SQLController sqlControl = storeMgr.getSQLController();
            try
            {
                // Unset the existing object from this position
                PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, unsetStmt, false);
                try
                {
                    int jdbcPosition = 1;
                    jdbcPosition = BackingStoreHelper.populateOwnerInStatement(sm, ec, ps, jdbcPosition, ecs);
                    if (orderMapping != null)
                    {
                        jdbcPosition = BackingStoreHelper.populateOrderInStatement(ec, ps, index, jdbcPosition, orderMapping);
                    }
                    if (relationDiscriminatorMapping != null)
                    {
                        jdbcPosition =
                            BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, ecs);
                    }

                    sqlControl.executeStatementUpdate(mconn, unsetStmt, ps, true);
                }
                finally
                {
                    sqlControl.closeStatement(mconn, ps);
                }

                // Set the new object at this position
                PreparedStatement ps2 = sqlControl.getStatementForUpdate(mconn, setStmt, false);
                try
                {
                    int jdbcPosition = 1;
                    jdbcPosition = BackingStoreHelper.populateOwnerInStatement(sm, ec, ps2, jdbcPosition, ecs);
                    if (orderMapping != null)
                    {
                        jdbcPosition = BackingStoreHelper.populateOrderInStatement(ec, ps2, index, jdbcPosition, orderMapping);
                    }
                    if (relationDiscriminatorMapping != null)
                    {
                        jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps2, jdbcPosition, ecs);
                    }
                    jdbcPosition = BackingStoreHelper.populateElementInStatement(ec, ps2, element, jdbcPosition, elementMapping);

                    sqlControl.executeStatementUpdate(mconn, setStmt, ps2, true);
                }
                finally
                {
                    ps2.close();
                }
            }
            finally
            {
                mconn.release();
            }
        }
        catch (SQLException e)
        {
            throw new NucleusDataStoreException(localiser.msg("056015", setStmt), e);
        }

        boolean dependent = ecs.getOwnerMemberMetaData().getCollection().isDependentElement();
        if (ecs.getOwnerMemberMetaData().isCascadeRemoveOrphans())
        {
            dependent = true;
        }
        if (dependent && allowDependentField)
        {
            if (obj != null)
            {
                // Delete the element if it is dependent and doesnt have a duplicate entry in the list
                sm.getExecutionContext().deleteObjectInternal(obj);
            }
        }

        return obj;
    }

    /**
     * Generate statement for updating the owner, index columns in an inverse 1-N.
     * Will result in the statement
     * <PRE>
     * UPDATE ELEMENTTABLE SET FK_COL_1 = ?, FK_COL_2 = ?, FK_IDX = ? [,DISTINGUISHER=?]
     * WHERE ELEMENT_ID = ?
     * </PRE>
     * when we have a single element table, and
     * <PRE>
     * UPDATE ? SET FK_COL_1=?, FK_COL_2=?, FK_IDX=? [,DISTINGUISHER=?]
     * WHERE ELEMENT_ID=?
     * </PRE>
     * when we have multiple element tables possible
     * @return Statement for updating the owner/index of an element in an inverse 1-N
     */
    private String getUpdateFkStmt(ElementContainerStore ecs)
    {
        if (updateFkStmt == null)
        {
            JavaTypeMapping ownerMapping = ecs.getOwnerMapping();
            JavaTypeMapping orderMapping = ecs.getOrderMapping();
            DatastoreContainerObject containerTable = ecs.getContainerTable();
            JavaTypeMapping elementMapping = ecs.getElementMapping();
            ElementContainerStore.ElementInfo[] elementInfo = ecs.getElementInfo();
            JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();

            StringBuffer stmt = new StringBuffer();
            stmt.append("UPDATE ");
            if (elementInfo.length > 1)
            {
                stmt.append("?");
            }
            else
            {
                // Could use elementInfo[0].getDatastoreClass but need to allow for relation in superclass table
                stmt.append(containerTable.toString());
            }
            stmt.append(" SET ");
            for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(",");
                }
                stmt.append(ownerMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                stmt.append(" = ");
                stmt.append(((RDBMSMapping) ownerMapping.getDatastoreMapping(i)).getUpdateInputParameter());
            }
            if (orderMapping != null)
            {
                for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(",");
                    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(",");
                    stmt.append(relationDiscriminatorMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                    stmt.append(" = ");
                    stmt.append(((RDBMSMapping) relationDiscriminatorMapping.getDatastoreMapping(i)).getUpdateInputParameter());
                }
            }

            stmt.append(" WHERE ");

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

        return updateFkStmt;
    }

    public boolean updateElementFk(ObjectProvider sm, Object element, Object owner, int index, ExecutionContext ec,
            ElementContainerStore ecs)
    {
        JavaTypeMapping ownerMapping = ecs.getOwnerMapping();
        JavaTypeMapping orderMapping = ecs.getOrderMapping();
        JavaTypeMapping elementMapping = ecs.getElementMapping();
        ElementContainerStore.ElementInfo[] elementInfo = ecs.getElementInfo();
        JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();
        AbstractMemberMetaData ownerMemberMetaData = ecs.getOwnerMemberMetaData();

        String updateFkStmt = getUpdateFkStmt(ecs);
        boolean retval;
        try
        {
            ManagedConnection mconn = storeMgr.getConnection(ec);
            SQLController sqlControl = storeMgr.getSQLController();
            try
            {
                PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, updateFkStmt, false);
                try
                {
                    int jdbcPosition = 1;
                    if (elementInfo.length > 1)
                    {
                        storeMgr.getDatastoreClass(element.getClass().getName(), clr);
                    }
                    if (owner == null)
                    {
                        if (ownerMemberMetaData != null)
                        {
                            ownerMapping.setObject(ec, ps, MappingHelper.getMappingIndices(jdbcPosition, ownerMapping), null, sm,
                                ownerMemberMetaData.getAbsoluteFieldNumber());
                        }
                        else
                        {
                            ownerMapping.setObject(ec, ps, MappingHelper.getMappingIndices(jdbcPosition, ownerMapping), null);
                        }
                        jdbcPosition += ownerMapping.getNumberOfDatastoreMappings();
                    }
                    else
                    {
                        jdbcPosition = BackingStoreHelper.populateOwnerInStatement(sm, ec, ps, jdbcPosition, ecs);
                    }
                    if (orderMapping != null)
                    {
                        jdbcPosition = BackingStoreHelper.populateOrderInStatement(ec, ps, index, jdbcPosition, orderMapping);
                    }
                    if (relationDiscriminatorMapping != null)
                    {
                        jdbcPosition = BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, ecs);
                    }
                    jdbcPosition = BackingStoreHelper.populateElementInStatement(ec, ps, element, jdbcPosition, elementMapping);

                    sqlControl.executeStatementUpdate(mconn, updateFkStmt, ps, true);
                    retval = true;
                }
                finally
                {
                    sqlControl.closeStatement(mconn, ps);
                }
            }
            finally
            {
                mconn.release();
            }
        }
        catch (SQLException e)
        {
            throw new NucleusDataStoreException(localiser.msg("056027", updateFkStmt), e);
        }

        return retval;
    }

    /**
     * Generates the statement for removing an item by nulling it out.
     * When there is only a single element table the statement will be
     * <PRE>
     * UPDATE LISTTABLE SET OWNERCOL=NULL, INDEXCOL=-1
     * WHERE OWNERCOL = ?
     * AND INDEXCOL = ?
     * [AND DISTINGUISHER = ?]
     * </PRE>
     * and when there are multiple element tables the statement will be
     * <PRE>
     * UPDATE ? SET OWNERCOL=NULL, INDEXCOL=-1
     * WHERE OWNERCOL=?
     * AND INDEXCOL=?
     * [AND DISTINGUISHER = ?]
     * </PRE>
     * @return The Statement for removing an item from a position
     */
    protected String getRemoveAtNullifyStmt(ElementContainerStore ecs)
    {
        if (removeAtNullifyStmt == null)
        {
            JavaTypeMapping ownerMapping = ecs.getOwnerMapping();
            JavaTypeMapping orderMapping = ecs.getOrderMapping();
            DatastoreContainerObject containerTable = ecs.getContainerTable();
            ElementContainerStore.ElementInfo[] elementInfo = ecs.getElementInfo();
            JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();

            StringBuffer stmt = new StringBuffer();
            stmt.append("UPDATE ");
            if (elementInfo.length > 1)
            {
                stmt.append("?");
            }
            else
            {
                // Could use elementInfo[0].getDatastoreClass but need to allow for relation in superclass table
                stmt.append(containerTable.toString());
            }
            stmt.append(" SET ");
            for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(", ");
                }
                stmt.append(ownerMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString() + "=NULL");
            }
            if (orderMapping != null)
            {
                for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(", ");
                    stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString() + "=-1");
                }
            }

            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());
            }
            if (orderMapping != null)
            {
                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());
                }
            }
            removeAtNullifyStmt = stmt.toString();
        }
        return removeAtNullifyStmt;
    }

    /**
     * Generates the statement for clearing items by nulling the owner link out. The statement will be
     * <PRE>
     * UPDATE LISTTABLE SET OWNERCOL=NULL, INDEXCOL=-1 [,DISTINGUISHER=NULL]
     * WHERE OWNERCOL=? [AND DISTINGUISHER=?]
     * </PRE>
     * when there is only one element table, and will be
     * <PRE>
     * UPDATE ? SET OWNERCOL=NULL, INDEXCOL=-1 [,DISTINGUISHER=NULL]
     * WHERE OWNERCOL=? [AND DISTINGUISHER=?]
     * </PRE>
     * when there is more than 1 element table.
     * @return The Statement for clearing items for the owner.
     */
    protected String getClearNullifyStmt(ElementContainerStore ecs)
    {
        if (clearNullifyStmt == null)
        {
            JavaTypeMapping ownerMapping = ecs.getOwnerMapping();
            JavaTypeMapping orderMapping = ecs.getOrderMapping();
            DatastoreContainerObject containerTable = ecs.getContainerTable();
            ElementContainerStore.ElementInfo[] elementInfo = ecs.getElementInfo();
            JavaTypeMapping relationDiscriminatorMapping = ecs.getRelationDiscriminatorMapping();

            StringBuffer stmt = new StringBuffer();
            stmt.append("UPDATE ");
            if (elementInfo.length > 1)
            {
                stmt.append("?");
            }
            else
            {
                // Could use elementInfo[0].getDatastoreClass but need to allow for relation in superclass table
                stmt.append(containerTable.toString());
            }
            stmt.append(" SET ");
            for (int i = 0; i < ownerMapping.getNumberOfDatastoreMappings(); i++)
            {
                if (i > 0)
                {
                    stmt.append(", ");
                }
                stmt.append(ownerMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString() + "=NULL");
            }
            if (orderMapping != null)
            {
                for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(", ");
                    stmt.append(orderMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString() + "=-1");
                }
            }
            if (relationDiscriminatorMapping != null)
            {
                for (int i = 0; i < relationDiscriminatorMapping.getNumberOfDatastoreMappings(); i++)
                {
                    stmt.append(", ");
                    stmt.append(
                        relationDiscriminatorMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
                    stmt.append("=NULL");
                }
            }

            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());
            }
            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());
                }
            }
            clearNullifyStmt = stmt.toString();
        }
        return clearNullifyStmt;
    }

    public void clearWithoutDelete(ExecutionContext ec, ObjectProvider ownerSM, ElementContainerStore ecs)
    {
        // TODO If the relation is bidirectional we need to clear the owner in the element
        String clearNullifyStmt = getClearNullifyStmt(ecs);
        try
        {
            ManagedConnection mconn = ecs.getStoreManager().getConnection(ec);
            SQLController sqlControl = storeMgr.getSQLController();
            try
            {
                PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, clearNullifyStmt, false);
                try
                {
                    int jdbcPosition = 1;
                    jdbcPosition = BackingStoreHelper.populateOwnerInStatement(ownerSM, ec, ps, jdbcPosition, ecs);
                    if (ecs.getRelationDiscriminatorMapping() != null)
                    {
                        BackingStoreHelper.populateRelationDiscriminatorInStatement(ec, ps, jdbcPosition, ecs);
                    }
                    sqlControl.executeStatementUpdate(mconn, clearNullifyStmt, ps, true);
                }
                finally
                {
                    sqlControl.closeStatement(mconn, ps);
                }
            }
            finally
            {
                mconn.release();
            }
        }
        catch (SQLException e)
        {
            throw new NucleusDataStoreException(localiser.msg("056013", clearNullifyStmt), e);
        }
    }

    public void removeAt(ObjectProvider sm, int index, int size, boolean nullify, FKListStore fkListStore)
    {
        String stmt;
        if (nullify)
        {
            // TODO When using this statement we need to plug in the element table name, and do it for
            // all possible element tables
            stmt = getRemoveAtNullifyStmt(fkListStore);
        }
        else
        {
            stmt = getRemoveAtStmt(fkListStore);
        }
        internalRemoveAt(sm, index, stmt, size, fkListStore);
    }
}
TOP

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

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.