Search in sources :

Example 11 with StatementParameterMapping

use of org.datanucleus.store.rdbms.query.StatementParameterMapping in project datanucleus-rdbms by datanucleus.

the class JoinMapStore method getSQLStatementForGet.

/**
 * Method to return an SQLStatement for retrieving the value for a key.
 * Selects the join table and optionally joins to the value table if it has its own table.
 * @param ownerOP ObjectProvider for the owning object
 * @return The SQLStatement
 */
protected SelectStatement getSQLStatementForGet(ObjectProvider ownerOP) {
    SelectStatement sqlStmt = null;
    ExecutionContext ec = ownerOP.getExecutionContext();
    final ClassLoaderResolver clr = ownerOP.getExecutionContext().getClassLoaderResolver();
    Class valueCls = clr.classForName(this.valueType);
    if (valuesAreEmbedded || valuesAreSerialised) {
        // Value is stored in join table
        sqlStmt = new SelectStatement(storeMgr, mapTable, null, null);
        sqlStmt.setClassLoaderResolver(clr);
        sqlStmt.select(sqlStmt.getPrimaryTable(), valueMapping, null);
    } else {
        // Value is stored in own table
        getMappingDef = new StatementClassMapping();
        if (!valueCmd.getFullClassName().equals(valueCls.getName())) {
            valueCls = clr.classForName(valueCmd.getFullClassName());
        }
        UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null, mapTable, null, valueMapping);
        stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
        getMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
        sqlStmt = stmtGen.getStatement(ec);
        // Select the value field(s)
        SQLTable valueSqlTbl = sqlStmt.getTable(valueTable, sqlStmt.getPrimaryTable().getGroupName());
        if (valueSqlTbl == null) {
            // Root value candidate has no table, so try to find a value candidate with a table that exists in this statement
            Collection<String> valueSubclassNames = storeMgr.getSubClassesForClass(valueType, true, clr);
            if (valueSubclassNames != null && !valueSubclassNames.isEmpty()) {
                for (String valueSubclassName : valueSubclassNames) {
                    DatastoreClass valueTbl = storeMgr.getDatastoreClass(valueSubclassName, clr);
                    if (valueTbl != null) {
                        valueSqlTbl = sqlStmt.getTable(valueTbl, sqlStmt.getPrimaryTable().getGroupName());
                        if (valueSqlTbl != null) {
                            break;
                        }
                    }
                }
            }
        }
        SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, getMappingDef, ec.getFetchPlan(), valueSqlTbl, valueCmd, ec.getFetchPlan().getMaxFetchDepth());
    }
    // Apply condition on owner field to filter by owner
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), ownerMapping);
    SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
    SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
    sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
    // Apply condition on key
    if (keyMapping instanceof SerialisedMapping) {
        // if the keyMapping contains a BLOB column (or any other column not supported by the database
        // as primary key), uses like instead of the operator OP_EQ (=)
        // in future do not check if the keyMapping is of ObjectMapping, but use the database
        // adapter to check the data types not supported as primary key
        // if object mapping (BLOB) use like
        SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
        SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
        sqlStmt.whereAnd(new org.datanucleus.store.rdbms.sql.expression.BooleanExpression(keyExpr, Expression.OP_LIKE, keyVal), true);
    } else {
        SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
        SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
        sqlStmt.whereAnd(keyExpr.eq(keyVal), true);
    }
    // Input parameter(s) - owner, key
    int inputParamNum = 1;
    StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
    StatementMappingIndex keyIdx = new StatementMappingIndex(keyMapping);
    if (sqlStmt.getNumberOfUnions() > 0) {
        // Add parameter occurrence for each union of statement
        for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
            int[] ownerPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < ownerPositions.length; k++) {
                ownerPositions[k] = inputParamNum++;
            }
            ownerIdx.addParameterOccurrence(ownerPositions);
            int[] keyPositions = new int[keyMapping.getNumberOfDatastoreMappings()];
            for (int k = 0; k < keyPositions.length; k++) {
                keyPositions[k] = inputParamNum++;
            }
            keyIdx.addParameterOccurrence(keyPositions);
        }
    } else {
        int[] ownerPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < ownerPositions.length; k++) {
            ownerPositions[k] = inputParamNum++;
        }
        ownerIdx.addParameterOccurrence(ownerPositions);
        int[] keyPositions = new int[keyMapping.getNumberOfDatastoreMappings()];
        for (int k = 0; k < keyPositions.length; k++) {
            keyPositions[k] = inputParamNum++;
        }
        keyIdx.addParameterOccurrence(keyPositions);
    }
    getMappingParams = new StatementParameterMapping();
    getMappingParams.addMappingForParameter("owner", ownerIdx);
    getMappingParams.addMappingForParameter("key", keyIdx);
    return sqlStmt;
}
Also used : StatementParameterMapping(org.datanucleus.store.rdbms.query.StatementParameterMapping) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) UnionStatementGenerator(org.datanucleus.store.rdbms.sql.UnionStatementGenerator) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) ExecutionContext(org.datanucleus.ExecutionContext) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) SerialisedMapping(org.datanucleus.store.rdbms.mapping.java.SerialisedMapping) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Example 12 with StatementParameterMapping

use of org.datanucleus.store.rdbms.query.StatementParameterMapping in project datanucleus-rdbms by datanucleus.

the class JoinMapStore method getSQLStatementForGet.

/**
 * Method to return an SQLStatement for retrieving the value for a key.
 * Selects the join table and optionally joins to the value table if it has its own table.
 * @param ownerSM StateManager for the owning object
 * @return The SQLStatement
 */
protected SelectStatement getSQLStatementForGet(DNStateManager ownerSM) {
    SelectStatement sqlStmt = null;
    ExecutionContext ec = ownerSM.getExecutionContext();
    final ClassLoaderResolver clr = ownerSM.getExecutionContext().getClassLoaderResolver();
    Class<?> valueCls = clr.classForName(this.valueType);
    if (valuesAreEmbedded || valuesAreSerialised) {
        // Value is stored in join table
        sqlStmt = new SelectStatement(storeMgr, mapTable, null, null);
        sqlStmt.setClassLoaderResolver(clr);
        sqlStmt.select(sqlStmt.getPrimaryTable(), valueMapping, null);
    } else {
        // Value is stored in own table
        getMappingDef = new StatementClassMapping();
        if (!valueCmd.getFullClassName().equals(valueCls.getName())) {
            valueCls = clr.classForName(valueCmd.getFullClassName());
        }
        UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null, mapTable, null, valueMapping);
        stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
        getMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
        sqlStmt = stmtGen.getStatement(ec);
        // Select the value field(s)
        SQLTable valueSqlTbl = sqlStmt.getTable(valueTable, sqlStmt.getPrimaryTable().getGroupName());
        if (valueSqlTbl == null) {
            // Root value candidate has no table, so try to find a value candidate with a table that exists in this statement
            Collection<String> valueSubclassNames = storeMgr.getSubClassesForClass(valueType, true, clr);
            if (valueSubclassNames != null && !valueSubclassNames.isEmpty()) {
                for (String valueSubclassName : valueSubclassNames) {
                    DatastoreClass valueTbl = storeMgr.getDatastoreClass(valueSubclassName, clr);
                    if (valueTbl != null) {
                        valueSqlTbl = sqlStmt.getTable(valueTbl, sqlStmt.getPrimaryTable().getGroupName());
                        if (valueSqlTbl != null) {
                            break;
                        }
                    }
                }
            }
        }
        SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, getMappingDef, ec.getFetchPlan(), valueSqlTbl, valueCmd, ec.getFetchPlan().getMaxFetchDepth());
    }
    // Apply condition on owner field to filter by owner
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), ownerMapping);
    SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
    SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
    sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
    // Apply condition on key
    if (keyMapping instanceof SerialisedMapping) {
        // if the keyMapping contains a BLOB column (or any other column not supported by the database as primary key), uses like instead of the operator OP_EQ (=)
        // in future do not check if the keyMapping is of ObjectMapping, but use the database adapter to check the data types not supported as primary key
        // if object mapping (BLOB) use like
        SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
        SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
        sqlStmt.whereAnd(new org.datanucleus.store.rdbms.sql.expression.BooleanExpression(keyExpr, Expression.OP_LIKE, keyVal), true);
    } else {
        SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
        SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
        sqlStmt.whereAnd(keyExpr.eq(keyVal), true);
    }
    // Input parameter(s) - owner, key
    int inputParamNum = 1;
    StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
    StatementMappingIndex keyIdx = new StatementMappingIndex(keyMapping);
    int numberOfUnions = sqlStmt.getNumberOfUnions();
    // Add parameter occurrence for each union of statement
    for (int j = 0; j < numberOfUnions + 1; j++) {
        int[] ownerPositions = new int[ownerMapping.getNumberOfColumnMappings()];
        for (int k = 0; k < ownerPositions.length; k++) {
            ownerPositions[k] = inputParamNum++;
        }
        ownerIdx.addParameterOccurrence(ownerPositions);
        int[] keyPositions = new int[keyMapping.getNumberOfColumnMappings()];
        for (int k = 0; k < keyPositions.length; k++) {
            keyPositions[k] = inputParamNum++;
        }
        keyIdx.addParameterOccurrence(keyPositions);
    }
    getMappingParams = new StatementParameterMapping();
    getMappingParams.addMappingForParameter("owner", ownerIdx);
    getMappingParams.addMappingForParameter("key", keyIdx);
    return sqlStmt;
}
Also used : StatementParameterMapping(org.datanucleus.store.rdbms.query.StatementParameterMapping) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) UnionStatementGenerator(org.datanucleus.store.rdbms.sql.UnionStatementGenerator) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) ExecutionContext(org.datanucleus.ExecutionContext) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) SerialisedMapping(org.datanucleus.store.rdbms.mapping.java.SerialisedMapping) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Example 13 with StatementParameterMapping

use of org.datanucleus.store.rdbms.query.StatementParameterMapping in project datanucleus-rdbms by datanucleus.

the class MapEntrySetStore method iterator.

/**
 * Method returning an iterator across the entries in the map for this owner object.
 * @param ownerSM StateManager of the owning object
 * @return The iterator for the entries (<pre>map.entrySet().iterator()</pre>).
 */
public Iterator<Map.Entry<K, V>> iterator(DNStateManager ownerSM) {
    ExecutionContext ec = ownerSM.getExecutionContext();
    Boolean serializeRead = ec.getTransaction().getSerializeRead();
    String stmtSql = serializeRead ? iteratorSelectStmtLockedSql : iteratorSelectStmtSql;
    if (stmtSql == null) {
        synchronized (// Make sure this completes in case another thread needs the same info
        this) {
            // Generate the statement
            SelectStatement selectStmt = getSQLStatementForIterator(ownerSM, ec.getFetchPlan(), true);
            // Input parameter(s) - the owner
            int inputParamNum = 1;
            StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
            if (selectStmt.getNumberOfUnions() > 0) {
                // Add parameter occurrence for each union of statement
                for (int j = 0; j < selectStmt.getNumberOfUnions() + 1; j++) {
                    int[] paramPositions = new int[ownerMapping.getNumberOfColumnMappings()];
                    for (int k = 0; k < ownerMapping.getNumberOfColumnMappings(); k++) {
                        paramPositions[k] = inputParamNum++;
                    }
                    ownerIdx.addParameterOccurrence(paramPositions);
                }
            } else {
                int[] paramPositions = new int[ownerMapping.getNumberOfColumnMappings()];
                for (int k = 0; k < ownerMapping.getNumberOfColumnMappings(); k++) {
                    paramPositions[k] = inputParamNum++;
                }
                ownerIdx.addParameterOccurrence(paramPositions);
            }
            iteratorMappingParams = new StatementParameterMapping();
            iteratorMappingParams.addMappingForParameter("owner", ownerIdx);
            // Save the two possible select statements (normal, locked)
            iteratorSelectStmtSql = selectStmt.getSQLText().toSQL();
            selectStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
            iteratorSelectStmtLockedSql = selectStmt.getSQLText().toSQL();
        }
        stmtSql = serializeRead ? iteratorSelectStmtLockedSql : iteratorSelectStmtSql;
    }
    try {
        ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
        SQLController sqlControl = storeMgr.getSQLController();
        try {
            // Create the statement and set the owner
            PreparedStatement ps = sqlControl.getStatementForQuery(mconn, stmtSql);
            StatementMappingIndex ownerIdx = iteratorMappingParams.getMappingForParameter("owner");
            int numParams = ownerIdx.getNumberOfParameterOccurrences();
            for (int paramInstance = 0; paramInstance < numParams; paramInstance++) {
                ownerIdx.getMapping().setObject(ec, ps, ownerIdx.getParameterPositionsForOccurrence(paramInstance), ownerSM.getObject());
            }
            try {
                ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, stmtSql, ps);
                try {
                    return new SetIterator(ownerSM, this, ownerMemberMetaData, rs, iteratorKeyResultCols, iteratorValueResultCols) {

                        protected boolean next(Object rs) {
                            try {
                                return ((ResultSet) rs).next();
                            } catch (SQLException e) {
                                throw new NucleusDataStoreException("SQLException", e);
                            }
                        }
                    };
                } finally {
                    rs.close();
                }
            } finally {
                sqlControl.closeStatement(mconn, ps);
            }
        } finally {
            mconn.release();
        }
    } catch (SQLException e) {
        throw new NucleusDataStoreException(Localiser.msg("056012", stmtSql), e);
    }
}
Also used : StatementParameterMapping(org.datanucleus.store.rdbms.query.StatementParameterMapping) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) SQLController(org.datanucleus.store.rdbms.SQLController) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) ExecutionContext(org.datanucleus.ExecutionContext) ResultSet(java.sql.ResultSet) ManagedConnection(org.datanucleus.store.connection.ManagedConnection)

Example 14 with StatementParameterMapping

use of org.datanucleus.store.rdbms.query.StatementParameterMapping in project datanucleus-rdbms by datanucleus.

the class MapValueCollectionStore method getSQLStatementForIterator.

/**
 * Method to generate an SQLStatement for iterating through values of the map.
 * Populates the iteratorMappingDef and iteratorMappingParams.
 * Creates a statement that selects the value table(s), and adds any necessary join to the containerTable
 * if that is not the value table. If the value is embedded then selects the table it is embedded in.
 * Adds a restriction on the ownerMapping of the containerTable so we can restrict to the owner object.
 * @param ownerSM StateManager for the owner object
 * @return The SQLStatement
 */
protected SelectStatement getSQLStatementForIterator(DNStateManager ownerSM) {
    SelectStatement sqlStmt = null;
    ExecutionContext ec = ownerSM.getExecutionContext();
    final ClassLoaderResolver clr = ec.getClassLoaderResolver();
    final Class valueCls = clr.classForName(elementType);
    SQLTable containerSqlTbl = null;
    MapType mapType = getOwnerMemberMetaData().getMap().getMapType();
    FetchPlan fp = ec.getFetchPlan();
    if (elementCmd != null && elementCmd.getDiscriminatorStrategyForTable() != null && elementCmd.getDiscriminatorStrategyForTable() != DiscriminatorStrategy.NONE) {
        // Map<?, PC> where value has discriminator
        if (ClassUtils.isReferenceType(valueCls)) {
            // Take the metadata for the first implementation of the reference type
            String[] clsNames = storeMgr.getNucleusContext().getMetaDataManager().getClassesImplementingInterface(elementType, clr);
            Class[] cls = new Class[clsNames.length];
            for (int j = 0; j < clsNames.length; j++) {
                cls[j] = clr.classForName(clsNames[j]);
            }
            SelectStatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, cls, true, null, null);
            sqlStmt = stmtGen.getStatement(ec);
        } else {
            SelectStatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, valueCls, true, null, null);
            sqlStmt = stmtGen.getStatement(ec);
        }
        iterateUsingDiscriminator = true;
        if (mapType == MapType.MAP_TYPE_VALUE_IN_KEY) {
            // Join to key table and select value fields
            JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
            containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
            iteratorMappingDef = new StatementClassMapping();
            SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
        } else if (mapType == MapType.MAP_TYPE_KEY_IN_VALUE) {
            // Select value fields
            containerSqlTbl = sqlStmt.getPrimaryTable();
            iteratorMappingDef = new StatementClassMapping();
            SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
        } else {
            // Join to join table and select value fields
            JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
            containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
            iteratorMappingDef = new StatementClassMapping();
            SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
        }
    } else {
        if (mapType == MapType.MAP_TYPE_VALUE_IN_KEY) {
            if (elementCmd != null) {
                // TODO Allow for null value [change to select the key table and left outer join to the key]
                // Select of value table, joining to key table
                iteratorMappingDef = new StatementClassMapping();
                UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null);
                stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
                iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
                sqlStmt = stmtGen.getStatement(ec);
                JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
                containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
                SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
            } else {
                // Select of value in key table
                sqlStmt = new SelectStatement(storeMgr, containerTable, null, null);
                sqlStmt.setClassLoaderResolver(clr);
                containerSqlTbl = sqlStmt.getPrimaryTable();
                SQLTable elemSqlTblForValue = containerSqlTbl;
                if (elementMapping.getTable() != containerSqlTbl.getTable()) {
                    elemSqlTblForValue = sqlStmt.getTableForDatastoreContainer(elementMapping.getTable());
                    if (elemSqlTblForValue == null) {
                        // Add join to key table holding value
                        elemSqlTblForValue = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), sqlStmt.getPrimaryTable().getTable().getIdMapping(), elementMapping.getTable(), null, elementMapping.getTable().getIdMapping(), null, null, true);
                    }
                }
                sqlStmt.select(elemSqlTblForValue, elementMapping, null);
            }
        } else if (mapType == MapType.MAP_TYPE_KEY_IN_VALUE) {
            // Select of value in value table (allow union of possible value types)
            iteratorMappingDef = new StatementClassMapping();
            UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null);
            stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
            iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
            sqlStmt = stmtGen.getStatement(ec);
            containerSqlTbl = sqlStmt.getPrimaryTable();
            SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
        } else {
            if (elementCmd != null) {
                // TODO Allow for null value [change to select the join table and left outer join to the key]
                // Select of value table, joining to key table
                iteratorMappingDef = new StatementClassMapping();
                UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null);
                stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
                iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
                sqlStmt = stmtGen.getStatement(ec);
                JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
                containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
                SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
            } else {
                // Select of value in join table
                sqlStmt = new SelectStatement(storeMgr, containerTable, null, null);
                containerSqlTbl = sqlStmt.getPrimaryTable();
                sqlStmt.select(sqlStmt.getPrimaryTable(), elementMapping, null);
            }
        }
    }
    // Apply condition on owner field to filter by owner
    SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
    SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, containerSqlTbl, ownerMapping);
    SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
    SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
    sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
    // Input parameter(s) - the owner
    int inputParamNum = 1;
    StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
    if (sqlStmt.getNumberOfUnions() > 0) {
        // Add parameter occurrence for each union of statement
        for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
            int[] paramPositions = new int[ownerMapping.getNumberOfColumnMappings()];
            for (int k = 0; k < ownerMapping.getNumberOfColumnMappings(); k++) {
                paramPositions[k] = inputParamNum++;
            }
            ownerIdx.addParameterOccurrence(paramPositions);
        }
    } else {
        int[] paramPositions = new int[ownerMapping.getNumberOfColumnMappings()];
        for (int k = 0; k < ownerMapping.getNumberOfColumnMappings(); k++) {
            paramPositions[k] = inputParamNum++;
        }
        ownerIdx.addParameterOccurrence(paramPositions);
    }
    iteratorMappingParams = new StatementParameterMapping();
    iteratorMappingParams.addMappingForParameter("owner", ownerIdx);
    return sqlStmt;
}
Also used : StatementParameterMapping(org.datanucleus.store.rdbms.query.StatementParameterMapping) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) FetchPlan(org.datanucleus.FetchPlan) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) MapType(org.datanucleus.metadata.MapMetaData.MapType) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) UnionStatementGenerator(org.datanucleus.store.rdbms.sql.UnionStatementGenerator) SelectStatementGenerator(org.datanucleus.store.rdbms.sql.SelectStatementGenerator) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) ExecutionContext(org.datanucleus.ExecutionContext) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) DiscriminatorStatementGenerator(org.datanucleus.store.rdbms.sql.DiscriminatorStatementGenerator) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Aggregations

StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)14 StatementParameterMapping (org.datanucleus.store.rdbms.query.StatementParameterMapping)14 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)14 ExecutionContext (org.datanucleus.ExecutionContext)13 StatementClassMapping (org.datanucleus.store.rdbms.query.StatementClassMapping)12 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)9 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)9 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)9 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)8 UnionStatementGenerator (org.datanucleus.store.rdbms.sql.UnionStatementGenerator)8 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)7 DiscriminatorStatementGenerator (org.datanucleus.store.rdbms.sql.DiscriminatorStatementGenerator)6 PreparedStatement (java.sql.PreparedStatement)5 ResultSet (java.sql.ResultSet)5 SQLException (java.sql.SQLException)5 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)5 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)5 SQLController (org.datanucleus.store.rdbms.SQLController)5 FetchPlan (org.datanucleus.FetchPlan)4 MapType (org.datanucleus.metadata.MapMetaData.MapType)4