SQLStatement sqlStmt = null;
// TODO This is the same as RDBMSJoinSetStore
final ClassLoaderResolver clr = ownerSM.getExecutionContext().getClassLoaderResolver();
RDBMSStoreManager storeMgr = (RDBMSStoreManager)this.storeMgr;
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
if (elementsAreEmbedded || elementsAreSerialised)
{
// Element = embedded, serialised (maybe Non-PC)
// Just select the join table since we're going to return the embedded/serialised columns from it
sqlStmt = new SQLStatement(storeMgr, containerTable, null, null);
sqlStmt.setClassLoaderResolver(clr);
// Select the element column - first select is assumed by SetStoreIterator
sqlStmt.select(sqlStmt.getPrimaryTable(), elementMapping, null);
}
else if (elementMapping instanceof ReferenceMapping)
{
// Element = Reference type (interface/Object)
// Just select the join table since we're going to return the implementation id columns only
sqlStmt = new SQLStatement(storeMgr, containerTable, null, null);
sqlStmt.setClassLoaderResolver(clr);
// Select the reference column(s) - first select is assumed by SetStoreIterator
sqlStmt.select(sqlStmt.getPrimaryTable(), elementMapping, null);
}
else
{
// Element = PC
// Join to the element table(s)
iteratorMappingClass = new StatementClassMapping();
for (int i = 0; i < elementInfo.length; i++)
{
// TODO This will only work if all element types have a discriminator
final int elementNo = i;
final Class elementCls = clr.classForName(elementInfo[elementNo].getClassName());
SQLStatement elementStmt = null;
if (elementInfo[elementNo].getDiscriminatorStrategy() != null &&
elementInfo[elementNo].getDiscriminatorStrategy() != DiscriminatorStrategy.NONE)
{
// The element uses a discriminator so just use that in the SELECT
String elementType = ownerMemberMetaData.getCollection().getElementType();
if (ClassUtils.isReferenceType(clr.classForName(elementType)))
{
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]);
}
StatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, cls,
true, null, null, containerTable, null, elementMapping);
if (allowNulls)
{
stmtGen.setOption(StatementGenerator.OPTION_ALLOW_NULLS);
}
elementStmt = stmtGen.getStatement();
}
else
{
StatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, elementCls,
true, null, null, containerTable, null, elementMapping);
if (allowNulls)
{
stmtGen.setOption(StatementGenerator.OPTION_ALLOW_NULLS);
}
elementStmt = stmtGen.getStatement();
}
iterateUsingDiscriminator = true;
}
else
{
// No discriminator, but subclasses so use UNIONs
StatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, elementCls, true, null,
null, containerTable, null, elementMapping);
stmtGen.setOption(StatementGenerator.OPTION_SELECT_NUCLEUS_TYPE);
if (allowNulls)
{
stmtGen.setOption(StatementGenerator.OPTION_ALLOW_NULLS);
}
iteratorMappingClass.setNucleusTypeColumnName(UnionStatementGenerator.NUC_TYPE_COLUMN);
elementStmt = stmtGen.getStatement();
}
if (sqlStmt == null)
{
sqlStmt = elementStmt;
}
else
{
sqlStmt.union(elementStmt);
}
}
// Select the required fields
SQLTable elementSqlTbl = sqlStmt.getTable(elementInfo[0].getDatastoreClass(),
sqlStmt.getPrimaryTable().getGroupName());
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingClass,
ownerSM.getExecutionContext().getFetchPlan(), elementSqlTbl, emd, 0);
}
// Apply condition on join-table owner field to filter by owner
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);
if (relationDiscriminatorMapping != null)
{
// Apply condition on distinguisher field to filter by distinguisher (when present)
SQLTable distSqlTbl =
SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), relationDiscriminatorMapping);
SQLExpression distExpr = exprFactory.newExpression(sqlStmt, distSqlTbl, relationDiscriminatorMapping);
SQLExpression distVal = exprFactory.newLiteral(sqlStmt, relationDiscriminatorMapping, relationDiscriminatorValue);
sqlStmt.whereAnd(distExpr.eq(distVal), true);
}
if (orderMapping != null)
{
// Order by the ordering column, when present
SQLTable orderSqlTbl =
SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), orderMapping);
SQLExpression[] orderExprs = new SQLExpression[orderMapping.getNumberOfDatastoreMappings()];
boolean descendingOrder[] = new boolean[orderMapping.getNumberOfDatastoreMappings()];
orderExprs[0] = exprFactory.newExpression(sqlStmt, orderSqlTbl, orderMapping);
sqlStmt.setOrdering(orderExprs, descendingOrder);
}
// Input parameter(s) - the owner
int inputParamNum = 1;