use of org.datanucleus.store.rdbms.table.MapTable 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;
}
use of org.datanucleus.store.rdbms.table.MapTable in project datanucleus-rdbms by datanucleus.
the class MapGetMethod method getAsInnerJoin.
/**
* Implementation of Map.get() using an inner join to 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 getAsInnerJoin(SQLStatement stmt, MapExpression mapExpr, SQLExpression keyValExpr) {
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
JavaTypeMapping m = mapExpr.getJavaTypeMapping();
AbstractMemberMetaData mmd = m.getMemberMetaData();
if (mmd != null) {
MapMetaData mapmd = mmd.getMap();
if (mapmd.getMapType() == MapType.MAP_TYPE_JOIN) {
MapTable joinTbl = (MapTable) stmt.getRDBMSManager().getTable(mmd);
// Add join to join table
SQLTable joinSqlTbl = stmt.join(JoinType.INNER_JOIN, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), joinTbl, null, joinTbl.getOwnerMapping(), null, null);
// Add condition on key
SQLExpression keyExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getKeyMapping());
stmt.whereAnd(keyExpr.eq(keyValExpr), true);
// Return value expression
if (mapmd.getValueClassMetaData(clr) != null) {
// Persistable value so join to its table
DatastoreClass valTable = stmt.getRDBMSManager().getDatastoreClass(mapmd.getValueType(), clr);
SQLTable valueSqlTbl = stmt.join(JoinType.INNER_JOIN, joinSqlTbl, joinTbl.getValueMapping(), valTable, null, valTable.getIdMapping(), null, null);
return exprFactory.newExpression(stmt, valueSqlTbl, valTable.getIdMapping());
}
// Return mapping for the value in the join table
SQLExpression valueExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getValueMapping());
return valueExpr;
} else if (mapmd.getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
// Key stored in value table, so join to value table
DatastoreClass valTable = stmt.getRDBMSManager().getDatastoreClass(mapmd.getValueType(), clr);
AbstractClassMetaData valCmd = mapmd.getValueClassMetaData(clr);
JavaTypeMapping mapTblOwnerMapping;
if (mmd.getMappedBy() != null) {
mapTblOwnerMapping = valTable.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
mapTblOwnerMapping = valTable.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
SQLTable valSqlTbl = stmt.join(JoinType.INNER_JOIN, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), valTable, null, mapTblOwnerMapping, null, null);
// Add condition on key
JavaTypeMapping keyMapping = valTable.getMemberMapping(valCmd.getMetaDataForMember(mmd.getKeyMetaData().getMappedBy()));
SQLExpression keyExpr = exprFactory.newExpression(stmt, valSqlTbl, keyMapping);
stmt.whereAnd(keyExpr.eq(keyValExpr), true);
// Return value expression
SQLExpression valueExpr = exprFactory.newExpression(stmt, valSqlTbl, valTable.getIdMapping());
return valueExpr;
} else if (mapmd.getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
// Value stored in key table, so join to key table
DatastoreClass keyTable = stmt.getRDBMSManager().getDatastoreClass(mapmd.getKeyType(), clr);
AbstractClassMetaData keyCmd = mapmd.getKeyClassMetaData(clr);
JavaTypeMapping mapTblOwnerMapping;
if (mmd.getMappedBy() != null) {
mapTblOwnerMapping = keyTable.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
mapTblOwnerMapping = keyTable.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
SQLTable keySqlTbl = stmt.join(JoinType.INNER_JOIN, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping(), keyTable, null, mapTblOwnerMapping, null, null);
// Add condition on key
SQLExpression keyExpr = exprFactory.newExpression(stmt, keySqlTbl, keyTable.getIdMapping());
stmt.whereAnd(keyExpr.eq(keyValExpr), true);
// Return value expression
JavaTypeMapping valueMapping = keyTable.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getValueMetaData().getMappedBy()));
SQLExpression valueExpr = exprFactory.newExpression(stmt, keySqlTbl, valueMapping);
return valueExpr;
}
}
throw new NucleusException("Map.get() for the filter is not supported for " + mapExpr + " with an argument of " + keyValExpr + ". Why not contribute support for it?");
}
use of org.datanucleus.store.rdbms.table.MapTable in project datanucleus-rdbms by datanucleus.
the class MapValueMethod method getAsJoin.
/**
* Implementation of VALUE(map) using a join to the table representing the map, and returning the value.
* @param stmt SQLStatement
* @param mapExpr The map expression
* @return The value expression
*/
protected SQLExpression getAsJoin(SQLStatement stmt, MapExpression mapExpr) {
JavaTypeMapping m = mapExpr.getJavaTypeMapping();
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
AbstractMemberMetaData mmd = m.getMemberMetaData();
// Use the statement of the table for this Map expression, since it could be in an outer query
stmt = mapExpr.getSQLTable().getSQLStatement();
if (mmd != null) {
MapMetaData mapmd = mmd.getMap();
SQLTable mapSqlTbl = mapExpr.getSQLTable();
// Set alias of "map" table from MapExpression in case it was defined in FROM clause
String mapJoinAlias = mapExpr.getAliasForMapTable();
if (mapJoinAlias == null) {
mapJoinAlias = (mapExpr.getSQLTable().getAlias().toString() + "_" + mmd.getName()).toUpperCase();
}
if (mapmd.getMapType() == MapType.MAP_TYPE_JOIN) {
// Add join to join table
MapTable joinTbl = (MapTable) storeMgr.getTable(mmd);
SQLTable joinSqlTbl = stmt.getTable(mapJoinAlias);
if (joinSqlTbl == null) {
joinSqlTbl = stmt.join(JoinType.INNER_JOIN, mapSqlTbl, mapSqlTbl.getTable().getIdMapping(), joinTbl, mapJoinAlias, joinTbl.getOwnerMapping(), null, null);
}
// Return value expression
if (mapmd.getValueClassMetaData(clr) != null && !mapmd.isEmbeddedValue()) {
// Persistable value so join to its table (default to "{mapJoinAlias}_VALUE")
DatastoreClass valTable = storeMgr.getDatastoreClass(mapmd.getValueType(), clr);
SQLTable valueSqlTbl = stmt.getTable(mapJoinAlias + "_VALUE");
if (valueSqlTbl == null) {
valueSqlTbl = stmt.join(JoinType.INNER_JOIN, joinSqlTbl, joinTbl.getValueMapping(), valTable, mapJoinAlias + "_VALUE", valTable.getIdMapping(), null, null);
}
return exprFactory.newExpression(stmt, valueSqlTbl, valTable.getIdMapping());
}
return exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getValueMapping());
} else if (mapmd.getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
// Key stored in value table, so join to value table
DatastoreClass valTable = storeMgr.getDatastoreClass(mapmd.getValueType(), clr);
AbstractClassMetaData valCmd = mmd.getMap().getValueClassMetaData(clr);
JavaTypeMapping mapTblOwnerMapping;
if (mmd.getMappedBy() != null) {
mapTblOwnerMapping = valTable.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
mapTblOwnerMapping = valTable.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
SQLTable valSqlTbl = stmt.join(JoinType.INNER_JOIN, mapSqlTbl, mapSqlTbl.getTable().getIdMapping(), valTable, mapJoinAlias, mapTblOwnerMapping, null, null);
// Return value expression
return exprFactory.newExpression(stmt, valSqlTbl, valTable.getIdMapping());
} else if (mapmd.getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
// Value stored in key table, so join to key table
DatastoreClass keyTable = storeMgr.getDatastoreClass(mapmd.getKeyType(), clr);
AbstractClassMetaData keyCmd = mmd.getMap().getKeyClassMetaData(clr);
JavaTypeMapping mapTblOwnerMapping;
if (mmd.getMappedBy() != null) {
mapTblOwnerMapping = keyTable.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
mapTblOwnerMapping = keyTable.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
SQLTable keySqlTbl = stmt.join(JoinType.INNER_JOIN, mapSqlTbl, mapSqlTbl.getTable().getIdMapping(), keyTable, mapJoinAlias, mapTblOwnerMapping, null, null);
// Return value expression
AbstractMemberMetaData valKeyMmd = mapmd.getKeyClassMetaData(clr).getMetaDataForMember(mmd.getValueMetaData().getMappedBy());
JavaTypeMapping valueMapping = keyTable.getMemberMapping(valKeyMmd);
return exprFactory.newExpression(stmt, keySqlTbl, valueMapping);
}
}
throw new NucleusException("KEY(map) for the filter is not supported for " + mapExpr + ". Why not contribute support for it?");
}
use of org.datanucleus.store.rdbms.table.MapTable 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;
}
use of org.datanucleus.store.rdbms.table.MapTable 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;
}
}
Aggregations