use of org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory in project datanucleus-rdbms by datanucleus.
the class MapKeySetStore method getSQLStatementForIterator.
/**
* Method to generate an SQLStatement for iterating through keys of the map.
* Populates the iteratorMappingDef and iteratorMappingParams.
* Creates a statement that selects the key table(s), and adds any necessary join to the containerTable
* if that is not the key table. If the key 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 ownerOP ObjectProvider for the owner object
* @return The SQLStatement
*/
protected SelectStatement getSQLStatementForIterator(ObjectProvider ownerOP) {
SelectStatement sqlStmt = null;
ExecutionContext ec = ownerOP.getExecutionContext();
final ClassLoaderResolver clr = ec.getClassLoaderResolver();
final Class keyCls = 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 key has discriminator
if (ClassUtils.isReferenceType(keyCls)) {
// 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]);
}
sqlStmt = new DiscriminatorStatementGenerator(storeMgr, clr, cls, true, null, null).getStatement(ec);
} else {
sqlStmt = new DiscriminatorStatementGenerator(storeMgr, clr, clr.classForName(elementInfo[0].getClassName()), true, null, null).getStatement(ec);
}
containerSqlTbl = sqlStmt.getPrimaryTable();
iterateUsingDiscriminator = true;
if (mapType == MapType.MAP_TYPE_VALUE_IN_KEY) {
// Select key fields
containerSqlTbl = sqlStmt.getPrimaryTable();
iteratorMappingDef = new StatementClassMapping();
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
} else {
// MAP_TYPE_KEY_IN_VALUE, MAP_TYPE_JOIN
// Join to join table and select key fields
JavaTypeMapping keyIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), keyIdMapping, 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) {
// Select of key in key table (allow union of possible key types)
iteratorMappingDef = new StatementClassMapping();
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, keyCls, 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 {
// MAP_TYPE_KEY_IN_VALUE, MAP_TYPE_JOIN
if (elementCmd != null) {
// Select of key table, joining to join table
iteratorMappingDef = new StatementClassMapping();
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, keyCls, true, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
sqlStmt = stmtGen.getStatement(ec);
JavaTypeMapping keyIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), keyIdMapping, containerTable, null, elementMapping, null, null, true);
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
} else {
// Select of key in join table
sqlStmt = new SelectStatement(storeMgr, containerTable, null, null);
sqlStmt.setClassLoaderResolver(clr);
containerSqlTbl = sqlStmt.getPrimaryTable();
SQLTable elemSqlTblForKey = containerSqlTbl;
if (elementMapping.getTable() != containerSqlTbl.getTable()) {
elemSqlTblForKey = sqlStmt.getTableForDatastoreContainer(elementMapping.getTable());
if (elemSqlTblForKey == null) {
// Add join to element table
elemSqlTblForKey = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), sqlStmt.getPrimaryTable().getTable().getIdMapping(), elementMapping.getTable(), null, elementMapping.getTable().getIdMapping(), null, null, true);
}
}
sqlStmt.select(elemSqlTblForKey, 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.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
paramPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(paramPositions);
}
} else {
int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
paramPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(paramPositions);
}
iteratorMappingParams = new StatementParameterMapping();
iteratorMappingParams.addMappingForParameter("owner", ownerIdx);
return sqlStmt;
}
use of org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory 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 ownerOP ObjectProvider for the owner object
* @return The SQLStatement
*/
protected SelectStatement getSQLStatementForIterator(ObjectProvider ownerOP) {
SelectStatement sqlStmt = null;
ExecutionContext ec = ownerOP.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.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
paramPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(paramPositions);
}
} else {
int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
paramPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(paramPositions);
}
iteratorMappingParams = new StatementParameterMapping();
iteratorMappingParams.addMappingForParameter("owner", ownerIdx);
return sqlStmt;
}
use of org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory in project datanucleus-rdbms by datanucleus.
the class SQLStatement method getJoinConditionForJoin.
/**
* Convenience method to generate the join condition between source and target tables for the supplied mappings.
* @param sourceTable Source table
* @param sourceMapping Mapping in source table
* @param sourceParentMapping Optional parent of this source mapping (if joining an impl of an interface)
* @param targetTable Target table
* @param targetMapping Mapping in target table
* @param targetParentMapping Optional parent of this target mapping (if joining an impl of an interface)
* @param discrimValues Optional discriminator values to further restrict
* @return The join condition
*/
protected BooleanExpression getJoinConditionForJoin(SQLTable sourceTable, JavaTypeMapping sourceMapping, JavaTypeMapping sourceParentMapping, SQLTable targetTable, JavaTypeMapping targetMapping, JavaTypeMapping targetParentMapping, Object[] discrimValues) {
BooleanExpression joinCondition = null;
if (sourceMapping != null && targetMapping != null) {
// Join condition(s) - INNER, LEFT OUTER, RIGHT OUTER joins
if (sourceMapping.getNumberOfDatastoreMappings() != targetMapping.getNumberOfDatastoreMappings()) {
throw new NucleusException("Cannot join from " + sourceMapping + " to " + targetMapping + " since they have different numbers of datastore columns!");
}
SQLExpressionFactory factory = rdbmsMgr.getSQLExpressionFactory();
// Set joinCondition to be "source = target"
SQLExpression sourceExpr = null;
if (sourceParentMapping == null) {
sourceExpr = factory.newExpression(this, sourceTable != null ? sourceTable : primaryTable, sourceMapping);
} else {
sourceExpr = factory.newExpression(this, sourceTable != null ? sourceTable : primaryTable, sourceMapping, sourceParentMapping);
}
SQLExpression targetExpr = null;
if (targetParentMapping == null) {
targetExpr = factory.newExpression(this, targetTable, targetMapping);
} else {
targetExpr = factory.newExpression(this, targetTable, targetMapping, targetParentMapping);
}
joinCondition = sourceExpr.eq(targetExpr);
// Process discriminator for any additional conditions
JavaTypeMapping discrimMapping = targetTable.getTable().getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, false);
if (discrimMapping != null && discrimValues != null) {
SQLExpression discrimExpr = factory.newExpression(this, targetTable, discrimMapping);
BooleanExpression discrimCondition = null;
for (Object discrimValue : discrimValues) {
SQLExpression discrimVal = factory.newLiteral(this, discrimMapping, discrimValue);
BooleanExpression condition = discrimExpr.eq(discrimVal);
if (discrimCondition == null) {
discrimCondition = condition;
} else {
discrimCondition = discrimCondition.ior(condition);
}
}
if (discrimCondition != null) {
discrimCondition.encloseInParentheses();
joinCondition = joinCondition.and(discrimCondition);
}
}
}
return joinCondition;
}
use of org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory in project datanucleus-rdbms by datanucleus.
the class LocateBulkRequest method getStatement.
protected String getStatement(DatastoreClass table, ObjectProvider[] ops, boolean lock) {
RDBMSStoreManager storeMgr = table.getStoreManager();
ClassLoaderResolver clr = storeMgr.getNucleusContext().getClassLoaderResolver(null);
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
cmd = storeMgr.getMetaDataManager().getMetaDataForClass(table.getType(), clr);
ExecutionContext ec = ops[0].getExecutionContext();
SelectStatement sqlStatement = new SelectStatement(storeMgr, table, null, null);
// SELECT fields we require
resultMapping = new StatementClassMapping();
// a). PK fields
if (table.getIdentityType() == IdentityType.DATASTORE) {
JavaTypeMapping datastoreIdMapping = table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), datastoreIdMapping);
int[] cols = sqlStatement.select(expr, null);
StatementMappingIndex datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
datastoreIdx.setColumnPositions(cols);
resultMapping.addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
} else if (table.getIdentityType() == IdentityType.APPLICATION) {
int[] pkNums = cmd.getPKMemberPositions();
for (int i = 0; i < pkNums.length; i++) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[i]);
JavaTypeMapping pkMapping = table.getMemberMappingInDatastoreClass(mmd);
if (pkMapping == null) {
pkMapping = table.getMemberMapping(mmd);
}
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), pkMapping);
int[] cols = sqlStatement.select(expr, null);
StatementMappingIndex pkIdx = new StatementMappingIndex(pkMapping);
pkIdx.setColumnPositions(cols);
resultMapping.addMappingForMember(mmd.getAbsoluteFieldNumber(), pkIdx);
}
} else {
throw new NucleusUserException("Cannot locate objects using nondurable identity");
}
JavaTypeMapping verMapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, false);
if (verMapping != null) {
VersionMetaData currentVermd = table.getVersionMetaData();
if (currentVermd != null && currentVermd.getFieldName() == null) {
// Surrogate version column
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), verMapping);
int[] cols = sqlStatement.select(expr, null);
StatementMappingIndex mapIdx = new StatementMappingIndex(verMapping);
mapIdx.setColumnPositions(cols);
resultMapping.addMappingForMember(SurrogateColumnType.VERSION.getFieldNumber(), mapIdx);
}
}
int[] nonPkFieldNums = cmd.getNonPKMemberPositions();
if (nonPkFieldNums != null) {
for (int i = 0; i < nonPkFieldNums.length; i++) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(nonPkFieldNums[i]);
JavaTypeMapping mapping = table.getMemberMapping(mmd);
if (mapping != null && mapping.includeInFetchStatement()) {
if (mapping instanceof PersistableMapping) {
// Ignore 1-1/N-1 for now
continue;
}
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), mapping);
int[] cols = sqlStatement.select(expr, null);
StatementMappingIndex mapIdx = new StatementMappingIndex(mapping);
mapIdx.setColumnPositions(cols);
resultMapping.addMappingForMember(mmd.getAbsoluteFieldNumber(), mapIdx);
}
}
}
JavaTypeMapping multitenancyMapping = table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false);
if (multitenancyMapping != null) {
// Add WHERE clause restricting to tenant
SQLExpression tenantExpr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), multitenancyMapping);
SQLExpression tenantVal = exprFactory.newLiteral(sqlStatement, multitenancyMapping, ec.getNucleusContext().getMultiTenancyId(ec, cmd));
sqlStatement.whereAnd(tenantExpr.eq(tenantVal), true);
}
JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
if (softDeleteMapping != null) {
// Add WHERE clause restricting to soft-delete unset
SQLExpression softDeleteExpr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), softDeleteMapping);
SQLExpression softDeleteVal = exprFactory.newLiteral(sqlStatement, softDeleteMapping, Boolean.FALSE);
sqlStatement.whereAnd(softDeleteExpr.eq(softDeleteVal), true);
}
// Add WHERE clause restricting to the identities of the objects
mappingDefinitions = new StatementClassMapping[ops.length];
int inputParamNum = 1;
for (int i = 0; i < ops.length; i++) {
mappingDefinitions[i] = new StatementClassMapping();
if (table.getIdentityType() == IdentityType.DATASTORE) {
// Datastore identity value for input
JavaTypeMapping datastoreIdMapping = table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false);
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), datastoreIdMapping);
SQLExpression val = exprFactory.newLiteralParameter(sqlStatement, datastoreIdMapping, null, "ID");
sqlStatement.whereOr(expr.eq(val), true);
StatementMappingIndex datastoreIdx = new StatementMappingIndex(datastoreIdMapping);
mappingDefinitions[i].addMappingForMember(SurrogateColumnType.DATASTORE_ID.getFieldNumber(), datastoreIdx);
datastoreIdx.addParameterOccurrence(new int[] { inputParamNum++ });
} else if (table.getIdentityType() == IdentityType.APPLICATION) {
// Application identity value(s) for input
BooleanExpression pkExpr = null;
int[] pkNums = cmd.getPKMemberPositions();
for (int j = 0; j < pkNums.length; j++) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkNums[j]);
JavaTypeMapping pkMapping = table.getMemberMappingInDatastoreClass(mmd);
if (pkMapping == null) {
pkMapping = table.getMemberMapping(mmd);
}
SQLExpression expr = exprFactory.newExpression(sqlStatement, sqlStatement.getPrimaryTable(), pkMapping);
SQLExpression val = exprFactory.newLiteralParameter(sqlStatement, pkMapping, null, "PK" + j);
BooleanExpression fieldEqExpr = expr.eq(val);
if (pkExpr == null) {
pkExpr = fieldEqExpr;
} else {
pkExpr = pkExpr.and(fieldEqExpr);
}
StatementMappingIndex pkIdx = new StatementMappingIndex(pkMapping);
mappingDefinitions[i].addMappingForMember(mmd.getAbsoluteFieldNumber(), pkIdx);
int[] inputParams = new int[pkMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < pkMapping.getNumberOfDatastoreMappings(); k++) {
inputParams[k] = inputParamNum++;
}
pkIdx.addParameterOccurrence(inputParams);
}
if (pkExpr == null) {
throw new NucleusException("Unable to generate PK expression for WHERE clause of locate statement");
}
pkExpr = (BooleanExpression) pkExpr.encloseInParentheses();
sqlStatement.whereOr(pkExpr, true);
}
}
// Generate the appropriate JDBC statement allowing for locking
if (lock) {
sqlStatement.addExtension(SQLStatement.EXTENSION_LOCK_FOR_UPDATE, Boolean.TRUE);
return sqlStatement.getSQLText().toSQL();
}
return sqlStatement.getSQLText().toSQL();
}
use of org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory in project datanucleus-rdbms by datanucleus.
the class UnionStatementGenerator method getSelectStatementForCandidate.
/**
* Convenience method to return the SelectStatement for a particular class.
* Returns a SelectStatement with primaryTable of the "candidateTable", and which joins to the table of the class (if different).
* @param className The class name to generate the statement for
* @param ec ExecutionContext
* @return The SelectStatement
*/
protected SelectStatement getSelectStatementForCandidate(String className, ExecutionContext ec) {
DatastoreClass table = storeMgr.getDatastoreClass(className, clr);
if (table == null) {
// Subclass-table, so persisted into table(s) of subclasses
NucleusLogger.GENERAL.info("Generation of statement to retrieve objects of type " + candidateType.getName() + (includeSubclasses ? " including subclasses " : "") + " attempted to include " + className + " but this has no table of its own; ignored");
// TODO Cater for use of single subclass-table
return null;
}
// Start from an SQL SELECT of the candidate table
SelectStatement stmt = new SelectStatement(parentStmt, storeMgr, candidateTable, candidateTableAlias, candidateTableGroupName);
stmt.setClassLoaderResolver(clr);
stmt.setCandidateClassName(className);
String tblGroupName = stmt.getPrimaryTable().getGroupName();
if (table != candidateTable) {
// INNER JOIN from the root candidate table to this candidates table
JavaTypeMapping candidateIdMapping = candidateTable.getIdMapping();
JavaTypeMapping tableIdMapping = table.getIdMapping();
SQLTable tableSqlTbl = stmt.join(JoinType.INNER_JOIN, null, candidateIdMapping, table, null, tableIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
tblGroupName = tableSqlTbl.getGroupName();
}
// Add any discriminator restriction in this table for the specified class
// Caters for the case where we have more than 1 class stored in this table
SQLExpressionFactory factory = storeMgr.getSQLExpressionFactory();
JavaTypeMapping discriminatorMapping = table.getSurrogateMapping(SurrogateColumnType.DISCRIMINATOR, false);
DiscriminatorMetaData discriminatorMetaData = table.getDiscriminatorMetaData();
if (discriminatorMapping != null && discriminatorMetaData.getStrategy() != DiscriminatorStrategy.NONE) {
// Restrict to valid discriminator values where we have a discriminator specified on this table
AbstractClassMetaData targetCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(className, clr);
SQLExpression discExpr = factory.newExpression(stmt, stmt.getPrimaryTable(), discriminatorMapping);
SQLExpression discValExpr = factory.newLiteral(stmt, discriminatorMapping, targetCmd.getDiscriminatorValue());
stmt.whereAnd(discExpr.eq(discValExpr), false);
}
JavaTypeMapping multitenancyMapping = table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false);
if (multitenancyMapping != null) {
// Multi-tenancy restriction
AbstractClassMetaData cmd = table.getClassMetaData();
SQLTable tenantSqlTbl = stmt.getTable(multitenancyMapping.getTable(), tblGroupName);
SQLExpression tenantExpr = stmt.getSQLExpressionFactory().newExpression(stmt, tenantSqlTbl, multitenancyMapping);
SQLExpression tenantVal = stmt.getSQLExpressionFactory().newLiteral(stmt, multitenancyMapping, ec.getNucleusContext().getMultiTenancyId(ec, cmd));
stmt.whereAnd(tenantExpr.eq(tenantVal), true);
}
JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
if (softDeleteMapping != null && !hasOption(OPTION_INCLUDE_SOFT_DELETES)) {
// Soft-delete restriction
SQLTable softDeleteSqlTbl = stmt.getTable(softDeleteMapping.getTable(), tblGroupName);
SQLExpression softDeleteExpr = stmt.getSQLExpressionFactory().newExpression(stmt, softDeleteSqlTbl, softDeleteMapping);
SQLExpression softDeleteVal = stmt.getSQLExpressionFactory().newLiteral(stmt, softDeleteMapping, Boolean.FALSE);
stmt.whereAnd(softDeleteExpr.eq(softDeleteVal), true);
}
// Eliminate any subclasses (catered for in separate UNION statement)
Iterator<String> subIter = storeMgr.getSubClassesForClass(className, false, clr).iterator();
while (subIter.hasNext()) {
String subclassName = subIter.next();
DatastoreClass[] subclassTables = null;
DatastoreClass subclassTable = storeMgr.getDatastoreClass(subclassName, clr);
if (subclassTable == null) {
AbstractClassMetaData targetSubCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(subclassName, clr);
AbstractClassMetaData[] targetSubCmds = storeMgr.getClassesManagingTableForClass(targetSubCmd, clr);
subclassTables = new DatastoreClass[targetSubCmds.length];
for (int i = 0; i < targetSubCmds.length; i++) {
subclassTables[i] = storeMgr.getDatastoreClass(targetSubCmds[i].getFullClassName(), clr);
}
} else {
subclassTables = new DatastoreClass[1];
subclassTables[0] = subclassTable;
}
for (int i = 0; i < subclassTables.length; i++) {
if (subclassTables[i] != table) {
// Subclass of our class is stored in different table to the candidate so exclude it
// Adds FROM clause of "LEFT OUTER JOIN {subTable} ON ..."
// and WHERE clause of "{subTable}.ID = NULL"
JavaTypeMapping tableIdMapping = table.getIdMapping();
JavaTypeMapping subclassIdMapping = subclassTables[i].getIdMapping();
SQLTable sqlTableSubclass = stmt.join(JoinType.LEFT_OUTER_JOIN, null, tableIdMapping, subclassTables[i], null, subclassIdMapping, null, stmt.getPrimaryTable().getGroupName(), true);
SQLExpression subclassIdExpr = factory.newExpression(stmt, sqlTableSubclass, subclassIdMapping);
SQLExpression nullExpr = new NullLiteral(stmt, null, null, null);
stmt.whereAnd(subclassIdExpr.eq(nullExpr), false);
}
}
}
if (hasOption(OPTION_SELECT_DN_TYPE)) {
// Add SELECT of dummy metadata for this class ("'mydomain.MyClass' AS DN_TYPE")
addTypeSelectForClass(stmt, className);
}
return stmt;
}
Aggregations