Search in sources :

Example 1 with Table

use of org.datanucleus.store.rdbms.table.Table in project datanucleus-rdbms by datanucleus.

the class IndexFunction method getExpression.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
     */
public SQLExpression getExpression(SQLStatement stmt, SQLExpression ignore, List args) {
    if (ignore == null) {
        if (args == null || args.size() != 2) {
            throw new NucleusException("INDEX can only be used with 2 arguments - the element expression, and the collection expression");
        }
        SQLExpression elemSqlExpr = (SQLExpression) args.get(0);
        SQLExpression collSqlExpr = (SQLExpression) args.get(1);
        AbstractMemberMetaData mmd = collSqlExpr.getJavaTypeMapping().getMemberMetaData();
        if (!mmd.hasCollection()) {
            throw new NucleusException("INDEX expression for field " + mmd.getFullFieldName() + " does not represent a collection!");
        } else if (!mmd.getOrderMetaData().isIndexedList()) {
            throw new NucleusException("INDEX expression for field " + mmd.getFullFieldName() + " does not represent an indexed list!");
        }
        JavaTypeMapping orderMapping = null;
        SQLTable orderTable = null;
        Table joinTbl = stmt.getRDBMSManager().getTable(mmd);
        if (joinTbl != null) {
            // 1-N via join table
            CollectionTable collTable = (CollectionTable) joinTbl;
            orderTable = stmt.getTableForDatastoreContainer(collTable);
            // TODO If the join table is not yet referenced, or referenced multiple times then fix this
            orderMapping = collTable.getOrderMapping();
        } else {
            // 1-N via FK
            orderTable = elemSqlExpr.getSQLTable();
            orderMapping = ((ClassTable) elemSqlExpr.getSQLTable().getTable()).getExternalMapping(mmd, MappingType.EXTERNAL_INDEX);
        }
        return new NumericExpression(stmt, orderTable, orderMapping);
    }
    throw new NucleusException(Localiser.msg("060002", "INDEX", ignore));
}
Also used : CollectionTable(org.datanucleus.store.rdbms.table.CollectionTable) Table(org.datanucleus.store.rdbms.table.Table) ClassTable(org.datanucleus.store.rdbms.table.ClassTable) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) CollectionTable(org.datanucleus.store.rdbms.table.CollectionTable) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 2 with Table

use of org.datanucleus.store.rdbms.table.Table in project datanucleus-rdbms by datanucleus.

the class OracleBlobColumnMapping method setPostProcessing.

@SuppressWarnings("deprecation")
@Override
public void setPostProcessing(DNStateManager sm, Object value) {
    // Oracle requires that a BLOB is initialised with EMPTY_BLOB() and then you retrieve the column and update its BLOB value. Performs a statement
    // SELECT {blobColumn} FROM TABLE WHERE ID=? FOR UPDATE
    // and then updates the Blob value returned.
    ExecutionContext ec = sm.getExecutionContext();
    byte[] bytes = (byte[]) value;
    Table table = column.getTable();
    RDBMSStoreManager storeMgr = table.getStoreManager();
    if (table instanceof DatastoreClass) {
        // BLOB within a primary table
        DatastoreClass classTable = (DatastoreClass) table;
        // Generate "SELECT {blobColumn} FROM TABLE WHERE ID=? FOR UPDATE" statement
        SelectStatement sqlStmt = new SelectStatement(storeMgr, table, null, null);
        sqlStmt.setClassLoaderResolver(ec.getClassLoaderResolver());
        sqlStmt.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, true);
        SQLTable blobSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), mapping);
        sqlStmt.select(blobSqlTbl, column, null);
        StatementClassMapping mappingDefinition = new StatementClassMapping();
        AbstractClassMetaData cmd = sm.getClassMetaData();
        SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
        int inputParamNum = 1;
        if (cmd.getIdentityType() == IdentityType.DATASTORE) {
            // Datastore identity value for input
            JavaTypeMapping datastoreIdMapping = classTable.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
            SQLExpression expr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), datastoreIdMapping);
            SQLExpression val = exprFactory.newLiteralParameter(sqlStmt, datastoreIdMapping, null, "ID");
            sqlStmt.whereAnd(expr.eq(val), true);
            StatementMappingIndex datastoreIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
            if (datastoreIdx == null) {
                datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
                mappingDefinition.addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
            }
            datastoreIdx.addParameterOccurrence(new int[] { inputParamNum });
        } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
            // Application identity value(s) for input
            int[] pkNums = cmd.getPKMemberPositions();
            for (int i = 0; i < pkNums.length; i++) {
                AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[i]);
                JavaTypeMapping pkMapping = classTable.getMemberMapping(mmd);
                SQLExpression expr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), pkMapping);
                SQLExpression val = exprFactory.newLiteralParameter(sqlStmt, pkMapping, null, "PK" + i);
                sqlStmt.whereAnd(expr.eq(val), true);
                StatementMappingIndex pkIdx = mappingDefinition.getMappingForMemberPosition(pkNums[i]);
                if (pkIdx == null) {
                    pkIdx = new StatementMappingIndex(pkMapping);
                    mappingDefinition.addMappingForMember(pkNums[i], pkIdx);
                }
                int[] inputParams = new int[pkMapping.getNumberOfColumnMappings()];
                for (int j = 0; j < pkMapping.getNumberOfColumnMappings(); j++) {
                    inputParams[j] = inputParamNum++;
                }
                pkIdx.addParameterOccurrence(inputParams);
            }
        }
        String textStmt = sqlStmt.getSQLText().toSQL();
        if (sm.isEmbedded()) {
            // This mapping is embedded, so navigate back to the real owner since that is the "id" in the table
            DNStateManager embeddedOwner = ec.getOwnerForEmbeddedStateManager(sm);
            if (embeddedOwner != null) {
                // TODO Should check if the owner is stored in this table
                sm = embeddedOwner;
            }
        }
        try {
            ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
            SQLController sqlControl = storeMgr.getSQLController();
            try {
                PreparedStatement ps = sqlControl.getStatementForQuery(mconn, textStmt);
                try {
                    // Provide the primary key field(s) to the JDBC statement
                    if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                        StatementMappingIndex datastoreIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
                        for (int i = 0; i < datastoreIdx.getNumberOfParameterOccurrences(); i++) {
                            classTable.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, datastoreIdx.getParameterPositionsForOccurrence(i), sm.getInternalObjectId());
                        }
                    } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                        sm.provideFields(cmd.getPKMemberPositions(), new ParameterSetter(sm, ps, mappingDefinition));
                    }
                    ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, textStmt, ps);
                    try {
                        if (!rs.next()) {
                            throw new NucleusObjectNotFoundException(Localiser.msg("050018", IdentityUtils.getPersistableIdentityForId(sm.getInternalObjectId())));
                        }
                        DatastoreAdapter dba = storeMgr.getDatastoreAdapter();
                        int jdbcMajorVersion = dba.getDriverMajorVersion();
                        if (dba.getDatastoreDriverName().equalsIgnoreCase(OracleAdapter.OJDBC_DRIVER_NAME) && jdbcMajorVersion < 10) {
                            oracle.sql.BLOB blob = null;
                            if (jdbcMajorVersion <= 8) {
                                // Oracle JDBC <= v8
                                // We are effectively doing the following line but don't want to impose having Oracle <= v10 in the CLASSPATH, just any Oracle driver
                                // blob = ((oracle.jdbc.driver.OracleResultSet)rs).getBLOB(1);
                                Method getBlobMethod = ClassUtils.getMethodForClass(rs.getClass(), "getBLOB", new Class[] { int.class });
                                try {
                                    blob = (BLOB) getBlobMethod.invoke(rs, new Object[] { 1 });
                                } catch (Throwable thr) {
                                    throw new NucleusDataStoreException("Error in getting BLOB", thr);
                                }
                            } else {
                                // Oracle JDBC v9
                                blob = (BLOB) rs.getBlob(1);
                            }
                            if (blob != null) {
                                // Deprecated but what can you do
                                blob.putBytes(1, bytes);
                            }
                        } else {
                            // Oracle JDBC v10+ supposedly use the JDBC standard class for Blobs
                            java.sql.Blob blob = rs.getBlob(1);
                            if (blob != null) {
                                blob.setBytes(1, bytes);
                            }
                        }
                    } finally {
                        rs.close();
                    }
                } finally {
                    sqlControl.closeStatement(mconn, ps);
                }
            } finally {
                mconn.release();
            }
        } catch (SQLException e) {
            throw new NucleusDataStoreException("Update of BLOB value failed: " + textStmt, e);
        }
    } else {
        // TODO Support join table
        throw new NucleusDataStoreException("We do not support INSERT/UPDATE BLOB post processing of non-primary table " + table);
    }
}
Also used : SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLException(java.sql.SQLException) StatementMappingIndex(org.datanucleus.store.rdbms.query.StatementMappingIndex) ParameterSetter(org.datanucleus.store.rdbms.fieldmanager.ParameterSetter) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) SQLController(org.datanucleus.store.rdbms.SQLController) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) BLOB(oracle.sql.BLOB) ResultSet(java.sql.ResultSet) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) Table(org.datanucleus.store.rdbms.table.Table) PreparedStatement(java.sql.PreparedStatement) Method(java.lang.reflect.Method) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) StatementClassMapping(org.datanucleus.store.rdbms.query.StatementClassMapping) ExecutionContext(org.datanucleus.ExecutionContext) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) DNStateManager(org.datanucleus.state.DNStateManager) Blob(java.sql.Blob) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 3 with Table

use of org.datanucleus.store.rdbms.table.Table in project datanucleus-rdbms by datanucleus.

the class RDBMSStoreManager method getBackingStoreForField.

/**
 * Accessor for the backing store for the specified member.
 * Note : if we have an embedded object that is embedded into some other type and the object has a member that requires a join table (backing store), this method
 * will not cater for the different places that can be embedded.
 * @param clr The ClassLoaderResolver
 * @param mmd metadata for the member to be persisted by this Store
 * @param type instantiated type or prefered type
 * @return The backing store
 */
public Store getBackingStoreForField(ClassLoaderResolver clr, AbstractMemberMetaData mmd, Class type) {
    if (mmd == null || mmd.isSerialized()) {
        return null;
    }
    Store store = backingStoreByMemberName.get(mmd.getFullFieldName());
    if (store != null) {
        return store;
    }
    synchronized (backingStoreByMemberName) {
        // Just in case we synced just after someone added since our previous lookup above
        store = backingStoreByMemberName.get(mmd.getFullFieldName());
        if (store != null) {
            return store;
        }
        Class expectedMappingType = null;
        if (mmd.getMap() != null) {
            expectedMappingType = MapMapping.class;
        } else if (mmd.getArray() != null) {
            expectedMappingType = ArrayMapping.class;
        } else if (mmd.getCollection() != null) {
            expectedMappingType = CollectionMapping.class;
        } else {
            expectedMappingType = PersistableMapping.class;
        }
        // Validate the mapping type matches the table
        try {
            DatastoreClass ownerTable = getDatastoreClass(mmd.getClassName(), clr);
            if (ownerTable == null) {
                // Class doesn't manage its own table (uses subclass-table, or superclass-table?)
                AbstractClassMetaData fieldTypeCmd = getMetaDataManager().getMetaDataForClass(mmd.getClassName(), clr);
                AbstractClassMetaData[] tableOwnerCmds = getClassesManagingTableForClass(fieldTypeCmd, clr);
                if (tableOwnerCmds != null && tableOwnerCmds.length == 1) {
                    ownerTable = getDatastoreClass(tableOwnerCmds[0].getFullClassName(), clr);
                }
            }
            if (ownerTable != null) {
                JavaTypeMapping m = ownerTable.getMemberMapping(mmd);
                if (!expectedMappingType.isAssignableFrom(m.getClass())) {
                    String requiredType = type != null ? type.getName() : mmd.getTypeName();
                    NucleusLogger.PERSISTENCE.warn("Member " + mmd.getFullFieldName() + " in table=" + ownerTable + " has mapping=" + m + " but expected mapping type=" + expectedMappingType);
                    throw new IncompatibleFieldTypeException(mmd.getFullFieldName(), requiredType, m.getType());
                }
            }
        } catch (NoTableManagedException ntme) {
        // Embedded, so just pass through
        }
        if (mmd.getMap() != null) {
            Table datastoreTable = getTable(mmd);
            if (datastoreTable == null) {
                store = new FKMapStore(mmd, this, clr);
            } else {
                store = new JoinMapStore((MapTable) datastoreTable, clr);
            }
        } else if (mmd.getArray() != null) {
            Table datastoreTable = getTable(mmd);
            if (datastoreTable != null) {
                store = new JoinArrayStore(mmd, (ArrayTable) datastoreTable, clr);
            } else {
                store = new FKArrayStore(mmd, this, clr);
            }
        } else if (mmd.getCollection() != null) {
            Table datastoreTable = getTable(mmd);
            if (type == null) {
                // No type to base it on so create it based on the field declared type
                if (datastoreTable == null) {
                    // We need a "FK" relation
                    if (Set.class.isAssignableFrom(mmd.getType())) {
                        store = new FKSetStore(mmd, this, clr);
                    } else if (List.class.isAssignableFrom(mmd.getType()) || Queue.class.isAssignableFrom(mmd.getType())) {
                        store = new FKListStore(mmd, this, clr);
                    } else if (mmd.getOrderMetaData() != null) {
                        // User has requested ordering
                        store = new FKListStore(mmd, this, clr);
                    } else {
                        store = new FKSetStore(mmd, this, clr);
                    }
                } else {
                    // We need a "JoinTable" relation.
                    if (Set.class.isAssignableFrom(mmd.getType())) {
                        store = new JoinSetStore(mmd, (CollectionTable) datastoreTable, clr);
                    } else if (List.class.isAssignableFrom(mmd.getType()) || Queue.class.isAssignableFrom(mmd.getType())) {
                        store = new JoinListStore(mmd, (CollectionTable) datastoreTable, clr);
                    } else if (mmd.getOrderMetaData() != null) {
                        // User has requested ordering
                        store = new JoinListStore(mmd, (CollectionTable) datastoreTable, clr);
                    } else {
                        store = new JoinSetStore(mmd, (CollectionTable) datastoreTable, clr);
                    }
                }
            } else {
                // Instantiated type specified, so use it to pick the associated backing store
                if (datastoreTable == null) {
                    if (SCOUtils.isListBased(type)) {
                        // List required
                        store = new FKListStore(mmd, this, clr);
                    } else {
                        // Set required
                        store = new FKSetStore(mmd, this, clr);
                    }
                } else {
                    if (SCOUtils.isListBased(type)) {
                        // List required
                        store = new JoinListStore(mmd, (CollectionTable) datastoreTable, clr);
                    } else {
                        // Set required
                        store = new JoinSetStore(mmd, (CollectionTable) datastoreTable, clr);
                    }
                }
            }
        } else {
            store = new JoinPersistableRelationStore(mmd, (PersistableJoinTable) getTable(mmd), clr);
        }
        backingStoreByMemberName.put(mmd.getFullFieldName(), store);
        return store;
    }
}
Also used : Table(org.datanucleus.store.rdbms.table.Table) ProbeTable(org.datanucleus.store.rdbms.table.ProbeTable) JoinTable(org.datanucleus.store.rdbms.table.JoinTable) ClassTable(org.datanucleus.store.rdbms.table.ClassTable) MapTable(org.datanucleus.store.rdbms.table.MapTable) PersistableJoinTable(org.datanucleus.store.rdbms.table.PersistableJoinTable) ArrayTable(org.datanucleus.store.rdbms.table.ArrayTable) CollectionTable(org.datanucleus.store.rdbms.table.CollectionTable) SequenceTable(org.datanucleus.store.rdbms.valuegenerator.SequenceTable) JoinArrayStore(org.datanucleus.store.rdbms.scostore.JoinArrayStore) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) JoinMapStore(org.datanucleus.store.rdbms.scostore.JoinMapStore) JoinSetStore(org.datanucleus.store.rdbms.scostore.JoinSetStore) JoinListStore(org.datanucleus.store.rdbms.scostore.JoinListStore) Store(org.datanucleus.store.types.scostore.Store) JoinArrayStore(org.datanucleus.store.rdbms.scostore.JoinArrayStore) JoinPersistableRelationStore(org.datanucleus.store.rdbms.scostore.JoinPersistableRelationStore) FKSetStore(org.datanucleus.store.rdbms.scostore.FKSetStore) FKListStore(org.datanucleus.store.rdbms.scostore.FKListStore) FKMapStore(org.datanucleus.store.rdbms.scostore.FKMapStore) FKArrayStore(org.datanucleus.store.rdbms.scostore.FKArrayStore) JoinMapStore(org.datanucleus.store.rdbms.scostore.JoinMapStore) IncompatibleFieldTypeException(org.datanucleus.store.types.IncompatibleFieldTypeException) MacroString(org.datanucleus.util.MacroString) JoinListStore(org.datanucleus.store.rdbms.scostore.JoinListStore) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) MapTable(org.datanucleus.store.rdbms.table.MapTable) ArrayMapping(org.datanucleus.store.rdbms.mapping.java.ArrayMapping) JoinSetStore(org.datanucleus.store.rdbms.scostore.JoinSetStore) CollectionTable(org.datanucleus.store.rdbms.table.CollectionTable) FKMapStore(org.datanucleus.store.rdbms.scostore.FKMapStore) FKSetStore(org.datanucleus.store.rdbms.scostore.FKSetStore) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) FKArrayStore(org.datanucleus.store.rdbms.scostore.FKArrayStore) PersistableJoinTable(org.datanucleus.store.rdbms.table.PersistableJoinTable) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NoTableManagedException(org.datanucleus.store.rdbms.exceptions.NoTableManagedException) FKListStore(org.datanucleus.store.rdbms.scostore.FKListStore) JoinPersistableRelationStore(org.datanucleus.store.rdbms.scostore.JoinPersistableRelationStore)

Example 4 with Table

use of org.datanucleus.store.rdbms.table.Table in project datanucleus-rdbms by datanucleus.

the class MapGetMethod method getAsSubquery.

/**
 * Implementation of Map.get() using a subquery on the table representing the map,
 * adding a condition on the key and returning the value.
 * @param stmt SQLStatement
 * @param mapExpr The map expression
 * @param keyValExpr The key value expression
 * @return The value expression
 */
protected SQLExpression getAsSubquery(SQLStatement stmt, MapExpression mapExpr, SQLExpression keyValExpr) {
    ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
    AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
    MapMetaData mapmd = mmd.getMap();
    RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
    JavaTypeMapping ownerMapping = null;
    JavaTypeMapping keyMapping = null;
    JavaTypeMapping valMapping = null;
    Table mapTbl = null;
    if (mapmd.getMapType() == MapType.MAP_TYPE_JOIN) {
        // JoinTable
        mapTbl = storeMgr.getTable(mmd);
        ownerMapping = ((MapTable) mapTbl).getOwnerMapping();
        keyMapping = ((MapTable) mapTbl).getKeyMapping();
        valMapping = ((MapTable) mapTbl).getValueMapping();
    } else if (mapmd.getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
        // ForeignKey from value table to key
        AbstractClassMetaData valCmd = mapmd.getValueClassMetaData(clr);
        mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getValueType(), clr);
        if (mmd.getMappedBy() != null) {
            ownerMapping = mapTbl.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        String keyFieldName = mmd.getKeyMetaData().getMappedBy();
        AbstractMemberMetaData valKeyMmd = valCmd.getMetaDataForMember(keyFieldName);
        keyMapping = mapTbl.getMemberMapping(valKeyMmd);
        valMapping = mapTbl.getIdMapping();
    } else if (mapmd.getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
        // ForeignKey from key table to value
        AbstractClassMetaData keyCmd = mapmd.getKeyClassMetaData(clr);
        mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getKeyType(), clr);
        if (mmd.getMappedBy() != null) {
            ownerMapping = mapTbl.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        keyMapping = mapTbl.getIdMapping();
        String valFieldName = mmd.getValueMetaData().getMappedBy();
        AbstractMemberMetaData keyValMmd = keyCmd.getMetaDataForMember(valFieldName);
        valMapping = mapTbl.getMemberMapping(keyValMmd);
    } else {
        throw new NucleusException("Invalid map for " + mapExpr + " in get() call");
    }
    SelectStatement subStmt = new SelectStatement(stmt, storeMgr, mapTbl, null, null);
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    subStmt.setClassLoaderResolver(clr);
    SQLExpression valExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valMapping);
    subStmt.select(valExpr, null);
    // Link to primary statement
    SQLExpression elementOwnerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
    SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping());
    subStmt.whereAnd(elementOwnerExpr.eq(ownerIdExpr), true);
    // Condition on key
    SQLExpression keyExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), keyMapping);
    subStmt.whereAnd(keyExpr.eq(keyValExpr), true);
    SubqueryExpression subExpr = new SubqueryExpression(stmt, subStmt);
    subExpr.setJavaTypeMapping(valMapping);
    return subExpr;
}
Also used : MapTable(org.datanucleus.store.rdbms.table.MapTable) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) Table(org.datanucleus.store.rdbms.table.Table) 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) MapMetaData(org.datanucleus.metadata.MapMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) SubqueryExpression(org.datanucleus.store.rdbms.sql.expression.SubqueryExpression) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 5 with Table

use of org.datanucleus.store.rdbms.table.Table in project datanucleus-rdbms by datanucleus.

the class MapValueMethod method getAsSubquery.

/**
 * Implementation of VALUE(map) using a subquery on the table representing the map, returning the value.
 * @param stmt SQLStatement
 * @param mapExpr The map expression
 * @return The value expression
 */
protected SQLExpression getAsSubquery(SQLStatement stmt, MapExpression mapExpr) {
    AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
    MapMetaData mapmd = mmd.getMap();
    RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
    ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
    JavaTypeMapping ownerMapping = null;
    JavaTypeMapping valMapping = null;
    Table mapTbl = null;
    if (mapmd.getMapType() == MapType.MAP_TYPE_JOIN) {
        // JoinTable
        mapTbl = storeMgr.getTable(mmd);
        ownerMapping = ((MapTable) mapTbl).getOwnerMapping();
        valMapping = ((MapTable) mapTbl).getValueMapping();
    } else if (mapmd.getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
        // ForeignKey from value table to key
        AbstractClassMetaData valCmd = mapmd.getValueClassMetaData(clr);
        mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getValueType(), clr);
        if (mmd.getMappedBy() != null) {
            ownerMapping = mapTbl.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        valMapping = mapTbl.getIdMapping();
    } else if (mapmd.getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
        // ForeignKey from key table to value
        AbstractClassMetaData keyCmd = mapmd.getKeyClassMetaData(clr);
        mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getKeyType(), clr);
        if (mmd.getMappedBy() != null) {
            ownerMapping = mapTbl.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
        } else {
            ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
        }
        String valFieldName = mmd.getValueMetaData().getMappedBy();
        AbstractMemberMetaData keyValMmd = keyCmd.getMetaDataForMember(valFieldName);
        valMapping = mapTbl.getMemberMapping(keyValMmd);
    } else {
        throw new NucleusException("Invalid map for " + mapExpr + " in get() call");
    }
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    SelectStatement subStmt = new SelectStatement(stmt, storeMgr, mapTbl, null, null);
    subStmt.setClassLoaderResolver(clr);
    SQLExpression valExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valMapping);
    subStmt.select(valExpr, null);
    // Link to primary statement
    SQLExpression elementOwnerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
    SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping());
    subStmt.whereAnd(elementOwnerExpr.eq(ownerIdExpr), true);
    SubqueryExpression subExpr = new SubqueryExpression(stmt, subStmt);
    subExpr.setJavaTypeMapping(valMapping);
    return subExpr;
}
Also used : Table(org.datanucleus.store.rdbms.table.Table) MapTable(org.datanucleus.store.rdbms.table.MapTable) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) 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) MapMetaData(org.datanucleus.metadata.MapMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) SubqueryExpression(org.datanucleus.store.rdbms.sql.expression.SubqueryExpression) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

Table (org.datanucleus.store.rdbms.table.Table)26 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)20 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)17 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)15 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)12 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)12 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)11 NucleusException (org.datanucleus.exceptions.NucleusException)10 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)10 JoinTable (org.datanucleus.store.rdbms.table.JoinTable)10 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)9 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)9 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)8 MapTable (org.datanucleus.store.rdbms.table.MapTable)8 CollectionTable (org.datanucleus.store.rdbms.table.CollectionTable)7 ClassTable (org.datanucleus.store.rdbms.table.ClassTable)6 ArrayTable (org.datanucleus.store.rdbms.table.ArrayTable)4 ElementContainerTable (org.datanucleus.store.rdbms.table.ElementContainerTable)4 PersistableJoinTable (org.datanucleus.store.rdbms.table.PersistableJoinTable)4 Collection (java.util.Collection)3