Package org.datanucleus.store.rdbms.scostore

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

/**********************************************************************
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 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.mapping.EmbeddedKeyPCMapping;
import org.datanucleus.store.mapped.mapping.EmbeddedValuePCMapping;
import org.datanucleus.store.mapped.mapping.JavaTypeMapping;
import org.datanucleus.store.mapped.mapping.MappingHelper;
import org.datanucleus.store.mapped.scostore.AbstractMapStore;
import org.datanucleus.store.mapped.scostore.AbstractMapStoreSpecialization;
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.store.rdbms.table.JoinTable;
import org.datanucleus.util.Localiser;

/**
* RDBMS-specific implementation of an {@link AbstractMapStoreSpecialization}.
*/
class RDBMSAbstractMapStoreSpecialization extends RDBMSElementContainerStoreSpecialization implements AbstractMapStoreSpecialization
{
    private String containsValueStmt;

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

    /**
     * Method to initialise the statements being used.
     * Subclasses should override the getXXXStmt() if they want to use an
     * alternative statement.
     * @param mapStore The map store
     **/
    public void initialise(AbstractMapStore mapStore)
    {
        containsValueStmt = getContainsValueStmt(mapStore.getOwnerMapping(), mapStore.getValueMapping(),
            mapStore.getMapTable());
    }

    /**
     * Generate statement to check if a value is contained in the Map.
     * <PRE>
     * SELECT OWNERCOL
     * FROM MAPTABLE
     * WHERE OWNERCOL=? AND VALUECOL = ?
     * </PRE>
     * @param ownerMapping the owner mapping
     * @param valueMapping the value mapping
     * @param mapTable the map table
     * @return Statement to check if a value is contained in the Map.
     */
    private String getContainsValueStmt(JavaTypeMapping ownerMapping, JavaTypeMapping valueMapping,
            DatastoreContainerObject mapTable)
    {
        StringBuffer stmt = new StringBuffer();
        stmt.append("SELECT ");
        for (int i=0; i<ownerMapping.getNumberOfDatastoreMappings(); i++)
        {
            if (i > 0)
            {
                stmt.append(",");
            }
            stmt.append(ownerMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
        }
        stmt.append(" FROM ");
        stmt.append(mapTable.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<valueMapping.getNumberOfDatastoreMappings(); i++)
        {
            stmt.append(" AND ");
            stmt.append(valueMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
            stmt.append(" = ");
            stmt.append(((RDBMSMapping)valueMapping.getDatastoreMapping(i)).getUpdateInputParameter());
        }
        return stmt.toString();
    }

    public boolean updateEmbeddedValue(ObjectProvider sm, Object value, int fieldNumber, Object newValue,
            JavaTypeMapping fieldMapping, AbstractMapStore mapStore)
    {
        boolean modified;
        String stmt =
            getUpdateEmbeddedValueStmt(fieldMapping, mapStore.getOwnerMapping(), mapStore.getValueMapping(), mapStore.getMapTable());
        try
        {
            ExecutionContext ec = sm.getExecutionContext();
            ManagedConnection mconn = storeMgr.getConnection(ec);
            SQLController sqlControl = storeMgr.getSQLController();

            try
            {
                PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, stmt, false);
                try
                {
                    int jdbcPosition = 1;
                    fieldMapping.setObject(ec, ps, MappingHelper.getMappingIndices(jdbcPosition, fieldMapping),
                        newValue);
                    jdbcPosition += fieldMapping.getNumberOfDatastoreMappings();
                    jdbcPosition = BackingStoreHelper.populateOwnerInStatement(sm, ec, ps, jdbcPosition, mapStore);
                    jdbcPosition = BackingStoreHelper.populateEmbeddedValueFieldsInStatement(
                        sm, value, ps, jdbcPosition, (JoinTable)mapStore.getMapTable(), mapStore);
                    sqlControl.executeStatementUpdate(mconn, stmt, ps, true);
                    modified = true;
                }
                finally
                {
                    sqlControl.closeStatement(mconn, ps);
                }
            }
            finally
            {
                mconn.release();
            }
        }
        catch (SQLException e)
        {
            e.printStackTrace();
            throw new NucleusDataStoreException(localiser.msg("056011", stmt), e);
        }
        return modified;
    }

    /**
     * Generate statement for update the field of an embedded key.
     * <PRE>
     * UPDATE MAPTABLE
     * SET EMBEDDEDKEYCOL1 = ?
     * WHERE OWNERCOL=?
     * AND EMBEDDEDKEYCOL1 = ?
     * AND EMBEDDEDKEYCOL2 = ? ...
     * </PRE>
     * @param fieldMapping The mapping for the field to be updated
     * @param ownerMapping The owner mapping
     * @param keyMapping The key mapping
     * @param mapTable The map table
     * @return Statement for updating an embedded key in the Set
     */
    protected String getUpdateEmbeddedKeyStmt(JavaTypeMapping fieldMapping, JavaTypeMapping ownerMapping,
            JavaTypeMapping keyMapping, DatastoreContainerObject mapTable)
    {
        StringBuffer stmt = new StringBuffer();
        stmt.append("UPDATE ");
        stmt.append(mapTable.toString());
        stmt.append(" SET ");
        for (int i=0; i<fieldMapping.getNumberOfDatastoreMappings(); i++)
        {
            if (i > 0)
            {
                stmt.append(",");
            }
            stmt.append(fieldMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
            stmt.append(" = ");
            stmt.append(((RDBMSMapping)fieldMapping.getDatastoreMapping(i)).getUpdateInputParameter());
        }

        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());
        }

        EmbeddedKeyPCMapping embeddedMapping = (EmbeddedKeyPCMapping)keyMapping;
        for (int i=0;i<embeddedMapping.getNumberOfJavaTypeMappings();i++)
        {
            JavaTypeMapping m = embeddedMapping.getJavaTypeMapping(i);
            if (m != null)
            {
                for (int j=0;j<m.getNumberOfDatastoreMappings();j++)
                {
                    stmt.append(" AND ");
                    stmt.append(m.getDatastoreMapping(j).getDatastoreField().getIdentifier().toString());
                    stmt.append(" = ");
                    stmt.append(((RDBMSMapping)m.getDatastoreMapping(j)).getUpdateInputParameter());
                }
            }
        }
        return stmt.toString();
    }

    /**
     * Generate statement for update the field of an embedded value.
     * <PRE>
     * UPDATE MAPTABLE
     * SET EMBEDDEDVALUECOL1 = ?
     * WHERE OWNERCOL=?
     * AND EMBEDDEDVALUECOL1 = ?
     * AND EMBEDDEDVALUECOL2 = ? ...
     * </PRE>
     * @param fieldMapping The mapping for the field to be updated
     * @param ownerMapping The owner mapping
     * @param mapTable The map table
     * @return Statement for updating an embedded value in the Set
     */
    protected String getUpdateEmbeddedValueStmt(JavaTypeMapping fieldMapping, JavaTypeMapping ownerMapping,
           JavaTypeMapping valueMapping, DatastoreContainerObject mapTable)
    {
        StringBuffer stmt = new StringBuffer();
        stmt.append("UPDATE ");
        stmt.append(mapTable.toString());
        stmt.append(" SET ");
        for (int i=0; i<fieldMapping.getNumberOfDatastoreMappings(); i++)
        {
            if (i > 0)
            {
                stmt.append(",");
            }
            stmt.append(fieldMapping.getDatastoreMapping(i).getDatastoreField().getIdentifier().toString());
            stmt.append(" = ");
            stmt.append(((RDBMSMapping)fieldMapping.getDatastoreMapping(i)).getUpdateInputParameter());
        }

        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());
        }

        EmbeddedValuePCMapping embeddedMapping = (EmbeddedValuePCMapping)valueMapping;
        for (int i=0;i<embeddedMapping.getNumberOfJavaTypeMappings();i++)
        {
            JavaTypeMapping m = embeddedMapping.getJavaTypeMapping(i);
            if (m != null)
            {
                for (int j=0;j<m.getNumberOfDatastoreMappings();j++)
                {
                    stmt.append(" AND ");
                    stmt.append(m.getDatastoreMapping(j).getDatastoreField().getIdentifier().toString());
                    stmt.append(" = ");
                    stmt.append(((RDBMSMapping)m.getDatastoreMapping(j)).getUpdateInputParameter());
                }
            }
        }
        return stmt.toString();
    }

    public boolean updatedEmbeddedKey(ObjectProvider sm, Object key, int fieldNumber, Object newValue, JavaTypeMapping fieldMapping, AbstractMapStore mapStore)
    {
        boolean modified;
        String stmt = getUpdateEmbeddedKeyStmt(fieldMapping, mapStore.getOwnerMapping(), mapStore.getKeyMapping(), mapStore.getMapTable());
        try
        {
            ExecutionContext ec = sm.getExecutionContext();
            ManagedConnection mconn = storeMgr.getConnection(ec);
            SQLController sqlControl = storeMgr.getSQLController();

            try
            {
                PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, stmt, false);
                try
                {
                    int jdbcPosition = 1;
                    fieldMapping.setObject(ec, ps, MappingHelper.getMappingIndices(jdbcPosition, fieldMapping), key);
                    jdbcPosition += fieldMapping.getNumberOfDatastoreMappings();
                    jdbcPosition = BackingStoreHelper.populateOwnerInStatement(sm, ec, ps, jdbcPosition, mapStore);
                    jdbcPosition = BackingStoreHelper.populateEmbeddedKeyFieldsInStatement(sm, key, ps, jdbcPosition,
                        (JoinTable)mapStore.getMapTable(), mapStore);

                    sqlControl.executeStatementUpdate(mconn, stmt, ps, true);
                    modified = true;
                }
                finally
                {
                    sqlControl.closeStatement(mconn, ps);
                }
            }
            finally
            {
                mconn.release();
            }
        }
        catch (SQLException e)
        {
            e.printStackTrace();
            throw new NucleusDataStoreException(localiser.msg("056010", stmt), e);
        }
        return modified;
    }

    public boolean containsValue(ObjectProvider sm, Object value, AbstractMapStore abstractMapStore)
    {
        boolean exists = false;
        try
        {
            ExecutionContext ec = sm.getExecutionContext();
            ManagedConnection mconn = storeMgr.getConnection(ec);
            SQLController sqlControl = storeMgr.getSQLController();
            try
            {
                PreparedStatement ps = sqlControl.getStatementForQuery(mconn, containsValueStmt);
                try
                {
                    int jdbcPosition = 1;
                    jdbcPosition = BackingStoreHelper.populateOwnerInStatement(sm, ec, ps, jdbcPosition, abstractMapStore);
                    BackingStoreHelper.populateValueInStatement(ec, ps, value, jdbcPosition, abstractMapStore.getValueMapping());

                    ResultSet rs = sqlControl.executeStatementQuery(mconn, containsValueStmt, ps);
                    try
                    {
                        if (rs.next())
                        {
                            exists = true;
                        }

                        JDBCUtils.logWarnings(rs);
                    }
                    finally
                    {
                        rs.close();
                    }
                }
                finally
                {
                    sqlControl.closeStatement(mconn, ps);
                }
            }
            finally
            {
                mconn.release();
            }
        }
        catch (SQLException e)
        {
            throw new NucleusDataStoreException(localiser.msg("056019",containsValueStmt),e);
        }

        return exists;
    }
}
TOP

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

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.