use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class MapSizeMethod 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 expr, List<SQLExpression> args) {
if (args != null && args.size() > 0) {
throw new NucleusException(Localiser.msg("060015", "size", "MapExpression"));
}
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
if (expr instanceof MapLiteral) {
// Just return the map length since we have the value
Map map = (Map) ((MapLiteral) expr).getValue();
return exprFactory.newLiteral(stmt, exprFactory.getMappingForType(int.class, false), Integer.valueOf(map.size()));
}
AbstractMemberMetaData ownerMmd = expr.getJavaTypeMapping().getMemberMetaData();
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
// TODO Allow for interface keys/values, etc
JavaTypeMapping ownerMapping = null;
Table mapTbl = null;
if (ownerMmd.getMap().getMapType() == MapType.MAP_TYPE_JOIN) {
// JoinTable
mapTbl = storeMgr.getTable(ownerMmd);
ownerMapping = ((JoinTable) mapTbl).getOwnerMapping();
} else if (ownerMmd.getMap().getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
// ForeignKey from value table to key
AbstractClassMetaData valueCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(ownerMmd.getMap().getValueType(), clr);
mapTbl = storeMgr.getDatastoreClass(ownerMmd.getMap().getValueType(), clr);
if (ownerMmd.getMappedBy() != null) {
ownerMapping = mapTbl.getMemberMapping(valueCmd.getMetaDataForMember(ownerMmd.getMappedBy()));
} else {
ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(ownerMmd, MappingType.EXTERNAL_FK);
}
} else if (ownerMmd.getMap().getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
// ForeignKey from key table to value
AbstractClassMetaData keyCmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(ownerMmd.getMap().getKeyType(), clr);
mapTbl = storeMgr.getDatastoreClass(ownerMmd.getMap().getKeyType(), clr);
if (ownerMmd.getMappedBy() != null) {
ownerMapping = mapTbl.getMemberMapping(keyCmd.getMetaDataForMember(ownerMmd.getMappedBy()));
} else {
ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(ownerMmd, MappingType.EXTERNAL_FK);
}
} else {
throw new NucleusException("Invalid map for " + expr + " in size() call");
}
SelectStatement subStmt = new SelectStatement(stmt, storeMgr, mapTbl, null, null);
subStmt.setClassLoaderResolver(clr);
JavaTypeMapping mapping = storeMgr.getMappingManager().getMappingWithDatastoreMapping(String.class, false, false, clr);
SQLExpression countExpr = exprFactory.newLiteral(subStmt, mapping, "COUNT(*)");
((StringLiteral) countExpr).generateStatementWithoutQuotes();
subStmt.select(countExpr, null);
SQLExpression elementOwnerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, expr.getSQLTable(), expr.getSQLTable().getTable().getIdMapping());
subStmt.whereAnd(elementOwnerExpr.eq(ownerIdExpr), true);
JavaTypeMapping subqMapping = exprFactory.getMappingForType(Integer.class, false);
SQLExpression subqExpr = new NumericSubqueryExpression(stmt, subStmt);
subqExpr.setJavaTypeMapping(subqMapping);
return subqExpr;
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class CollectionContainsMethod method containsAsJoin.
/**
* Method to return an expression for Collection.contains using INNER JOIN to the element.
* This is only for use when there are no "!contains" and no "OR" operations.
* Creates SQL by adding INNER JOIN to the join table (where it exists), and also to the element table
* adding an AND condition on the element (with value of the elemExpr).
* Returns a BooleanExpression "TRUE" (since the INNER JOIN will guarantee if the element is
* contained of not).
* @param stmt SQLStatement
* @param collExpr Collection expression
* @param elemExpr Expression for the element
* @param joinType Join type
* @return Contains expression
*/
protected SQLExpression containsAsJoin(SQLStatement stmt, CollectionExpression collExpr, SQLExpression elemExpr, SQLJoin.JoinType joinType) {
boolean elemIsUnbound = (elemExpr instanceof UnboundExpression);
String varName = null;
String elemAlias = null;
String elemType = null;
if (elemIsUnbound) {
varName = ((UnboundExpression) elemExpr).getVariableName();
NucleusLogger.QUERY.debug("collection.contains(" + elemExpr + ") binding unbound variable " + varName + " using INNER JOIN");
} else if (!stmt.getQueryGenerator().hasExplicitJoins()) {
if (stmt.getJoinTypeForTable(elemExpr.getSQLTable()) == JoinType.CROSS_JOIN) {
elemAlias = stmt.removeCrossJoin(elemExpr.getSQLTable());
elemIsUnbound = true;
elemType = elemExpr.getJavaTypeMapping().getType();
NucleusLogger.QUERY.debug("collection.contains(" + elemExpr + ") was previously bound as CROSS JOIN but changing to INNER JOIN");
}
}
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
AbstractMemberMetaData mmd = collExpr.getJavaTypeMapping().getMemberMetaData();
AbstractClassMetaData elemCmd = mmd.getCollection().getElementClassMetaData(clr);
CollectionTable joinTbl = (CollectionTable) storeMgr.getTable(mmd);
if (elemIsUnbound) {
Class varType = stmt.getQueryGenerator().getTypeOfVariable(varName);
if (varType != null) {
elemType = varType.getName();
elemCmd = storeMgr.getMetaDataManager().getMetaDataForClass(elemType, clr);
}
}
if (elemType == null) {
elemType = mmd.getCollection().getElementType();
}
if (joinTbl != null) {
// JoinTable Collection - join from owner to join, then from join to element
if (elemCmd == null) {
// Collection<Non-PC>
SQLTable joinSqlTbl = stmt.join(joinType, collExpr.getSQLTable(), collExpr.getSQLTable().getTable().getIdMapping(), joinTbl, elemAlias, joinTbl.getOwnerMapping(), null, null);
SQLExpression elemIdExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getElementMapping());
if (elemIsUnbound) {
// Bind the variable in the QueryGenerator
stmt.getQueryGenerator().bindVariable(varName, null, elemIdExpr.getSQLTable(), elemIdExpr.getJavaTypeMapping());
} else {
// Add restrict to element
addRestrictionOnElement(stmt, elemIdExpr, elemExpr);
}
} else {
// Collection<PC>
SQLTable joinSqlTbl = stmt.join(joinType, collExpr.getSQLTable(), collExpr.getSQLTable().getTable().getIdMapping(), joinTbl, null, joinTbl.getOwnerMapping(), null, null);
if (!mmd.getCollection().isEmbeddedElement()) {
DatastoreClass elemTbl = storeMgr.getDatastoreClass(elemType, clr);
SQLTable elemSqlTbl = null;
if (joinTbl.getElementMapping() instanceof ReferenceMapping && ((ReferenceMapping) joinTbl.getElementMapping()).getMappingStrategy() == ReferenceMapping.PER_IMPLEMENTATION_MAPPING) {
JavaTypeMapping elemMapping = null;
JavaTypeMapping[] elemImplMappings = ((ReferenceMapping) joinTbl.getElementMapping()).getJavaTypeMapping();
for (int i = 0; i < elemImplMappings.length; i++) {
if (elemImplMappings[i].getType().equals(elemCmd.getFullClassName())) {
elemMapping = elemImplMappings[i];
break;
}
}
elemSqlTbl = stmt.join(joinType, joinSqlTbl, elemMapping, joinTbl.getElementMapping(), elemTbl, elemAlias, elemTbl.getIdMapping(), null, null, null, true, null);
} else {
elemSqlTbl = stmt.join(joinType, joinSqlTbl, joinTbl.getElementMapping(), elemTbl, elemAlias, elemTbl.getIdMapping(), null, null);
}
SQLExpression elemIdExpr = exprFactory.newExpression(stmt, elemSqlTbl, elemTbl.getIdMapping());
if (elemIsUnbound) {
// Bind the variable in the QueryGenerator
stmt.getQueryGenerator().bindVariable(varName, elemCmd, elemIdExpr.getSQLTable(), elemIdExpr.getJavaTypeMapping());
} else {
// Add restrict to element
addRestrictionOnElement(stmt, elemIdExpr, elemExpr);
}
} else {
SQLExpression elemIdExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getElementMapping());
if (elemIsUnbound) {
// Bind the variable in the QueryGenerator
stmt.getQueryGenerator().bindVariable(varName, elemCmd, elemIdExpr.getSQLTable(), elemIdExpr.getJavaTypeMapping());
} else {
// Add restrict to element
addRestrictionOnElement(stmt, elemIdExpr, elemExpr);
}
}
}
} else {
// FK Collection - join from owner to element
DatastoreClass elemTbl = storeMgr.getDatastoreClass(mmd.getCollection().getElementType(), clr);
JavaTypeMapping ownerMapping = null;
if (mmd.getMappedBy() != null) {
ownerMapping = elemTbl.getMemberMapping(mmd.getRelatedMemberMetaData(clr)[0]);
} else {
ownerMapping = elemTbl.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
SQLTable elemSqlTbl = stmt.join(joinType, collExpr.getSQLTable(), collExpr.getSQLTable().getTable().getIdMapping(), elemTbl, elemAlias, ownerMapping, null, null);
if (elemIsUnbound) {
SQLExpression elemIdExpr = null;
if (!elemType.equals(mmd.getCollection().getElementType())) {
// Variable is defined as a subclass of the declared type so add extra join to variable type
DatastoreClass varTbl = storeMgr.getDatastoreClass(elemType, clr);
SQLTable varSqlTbl = stmt.join(joinType, elemSqlTbl, elemTbl.getIdMapping(), varTbl, null, varTbl.getIdMapping(), null, null);
elemIdExpr = exprFactory.newExpression(stmt, varSqlTbl, varTbl.getIdMapping());
} else {
elemIdExpr = exprFactory.newExpression(stmt, elemSqlTbl, elemTbl.getIdMapping());
}
// Bind the variable in the QueryGenerator
stmt.getQueryGenerator().bindVariable(varName, elemCmd, elemIdExpr.getSQLTable(), elemIdExpr.getJavaTypeMapping());
} else {
// Add restrict to element
SQLExpression elemIdExpr = exprFactory.newExpression(stmt, elemSqlTbl, elemTbl.getIdMapping());
addRestrictionOnElement(stmt, elemIdExpr, elemExpr);
}
}
JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, true));
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class CollectionSizeMethod 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 expr, List<SQLExpression> args) {
if (args != null && args.size() > 0) {
throw new NucleusException(Localiser.msg("060015", "size", "CollectionExpression"));
}
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
if (expr instanceof CollectionLiteral) {
// Just return the collection size since we have the value
Collection coll = (Collection) ((CollectionLiteral) expr).getValue();
return exprFactory.newLiteral(stmt, exprFactory.getMappingForType(int.class, false), Integer.valueOf(coll.size()));
}
AbstractMemberMetaData mmd = expr.getJavaTypeMapping().getMemberMetaData();
if (mmd.isSerialized()) {
throw new NucleusUserException("Cannot perform Collection.size when the collection is being serialised");
}
ApiAdapter api = stmt.getRDBMSManager().getApiAdapter();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
Class elementCls = clr.classForName(mmd.getCollection().getElementType());
if (!api.isPersistable(elementCls) && mmd.getJoinMetaData() == null) {
throw new NucleusUserException("Cannot perform Collection.size when the collection<Non-Persistable> is not in a join table");
}
String elementType = mmd.getCollection().getElementType();
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
// TODO Allow for interface elements, etc
JavaTypeMapping ownerMapping = null;
Table collectionTbl = null;
if (mmd.getMappedBy() != null) {
// Bidirectional
AbstractMemberMetaData elementMmd = mmd.getRelatedMemberMetaData(clr)[0];
if (mmd.getJoinMetaData() != null || elementMmd.getJoinMetaData() != null) {
// JoinTable
collectionTbl = storeMgr.getTable(mmd);
ownerMapping = ((JoinTable) collectionTbl).getOwnerMapping();
} else {
// ForeignKey
collectionTbl = storeMgr.getDatastoreClass(elementType, clr);
ownerMapping = collectionTbl.getMemberMapping(elementMmd);
}
} else {
// Unidirectional
if (mmd.getJoinMetaData() != null) {
// JoinTable
collectionTbl = storeMgr.getTable(mmd);
ownerMapping = ((JoinTable) collectionTbl).getOwnerMapping();
} else {
// ForeignKey
collectionTbl = storeMgr.getDatastoreClass(elementType, clr);
ownerMapping = ((DatastoreClass) collectionTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
}
SelectStatement subStmt = new SelectStatement(stmt, storeMgr, collectionTbl, null, null);
subStmt.setClassLoaderResolver(clr);
JavaTypeMapping mapping = storeMgr.getMappingManager().getMappingWithDatastoreMapping(String.class, false, false, clr);
SQLExpression countExpr = exprFactory.newLiteral(subStmt, mapping, "COUNT(*)");
((StringLiteral) countExpr).generateStatementWithoutQuotes();
subStmt.select(countExpr, null);
SQLExpression elementOwnerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, expr.getSQLTable(), expr.getSQLTable().getTable().getIdMapping());
subStmt.whereAnd(elementOwnerExpr.eq(ownerIdExpr), true);
JavaTypeMapping subqMapping = exprFactory.getMappingForType(Integer.class, false);
SQLExpression subqExpr = new NumericSubqueryExpression(stmt, subStmt);
subqExpr.setJavaTypeMapping(subqMapping);
return subqExpr;
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class JDOHelperGetVersionMethod 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<SQLExpression> args) {
if (args == null || args.size() == 0) {
throw new NucleusUserException("Cannot invoke JDOHelper.getVersion without an argument");
}
SQLExpression expr = args.get(0);
if (expr == null) {
throw new NucleusUserException("Cannot invoke JDOHelper.getVersion on null expression");
}
if (expr instanceof SQLLiteral) {
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
ApiAdapter api = storeMgr.getApiAdapter();
Object obj = ((SQLLiteral) expr).getValue();
if (obj == null || !api.isPersistable(obj)) {
return new NullLiteral(stmt, null, null, null);
}
Object ver = stmt.getRDBMSManager().getApiAdapter().getVersionForObject(obj);
JavaTypeMapping m = stmt.getSQLExpressionFactory().getMappingForType(ver.getClass(), true);
return new ObjectLiteral(stmt, m, ver, null);
} else if (ObjectExpression.class.isAssignableFrom(expr.getClass())) {
if (((ObjectExpression) expr).getJavaTypeMapping() instanceof PersistableMapping) {
JavaTypeMapping mapping = ((ObjectExpression) expr).getJavaTypeMapping();
DatastoreClass table = (DatastoreClass) expr.getSQLTable().getTable();
if (// Version of candidate
table.getIdMapping() == mapping) {
mapping = table.getSurrogateMapping(SurrogateColumnType.VERSION, true);
if (mapping == null) {
throw new NucleusUserException("Cannot use JDOHelper.getVersion on object that has no version information");
}
if (table.getVersionMetaData().getVersionStrategy() == VersionStrategy.VERSION_NUMBER) {
return new NumericExpression(stmt, expr.getSQLTable(), mapping);
}
return new TemporalExpression(stmt, expr.getSQLTable(), mapping);
}
throw new NucleusUserException("Dont currently support JDOHelper.getVersion(ObjectExpression) for expr=" + expr + " on table=" + expr.getSQLTable());
// TODO Implement this
}
return expr;
}
throw new IllegalExpressionOperationException("JDOHelper.getVersion", expr);
}
use of org.datanucleus.store.rdbms.table.DatastoreClass in project datanucleus-rdbms by datanucleus.
the class ListGetMethod method getAsInnerJoin.
/**
* Implementation of List.get() using an inner join to the table representing the list, adding a condition on the index and returning the element.
* @param stmt SQLStatement
* @param listExpr The list expression
* @param idxExpr The index expression
* @return The element expression
*/
protected SQLExpression getAsInnerJoin(SQLStatement stmt, CollectionExpression listExpr, SQLExpression idxExpr) {
JavaTypeMapping m = listExpr.getJavaTypeMapping();
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
AbstractMemberMetaData mmd = m.getMemberMetaData();
AbstractMemberMetaData[] relatedMmds = mmd.getRelatedMemberMetaData(clr);
if (mmd.getJoinMetaData() != null || relatedMmds != null && relatedMmds[0].getJoinMetaData() != null) {
// Join table List
CollectionTable joinTbl = (CollectionTable) storeMgr.getTable(mmd);
// Add join to join table
SQLTable joinSqlTbl = stmt.join(JoinType.INNER_JOIN, listExpr.getSQLTable(), listExpr.getSQLTable().getTable().getIdMapping(), joinTbl, null, joinTbl.getOwnerMapping(), null, null);
// Add condition on index
SQLExpression idxSqlExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getOrderMapping());
stmt.whereAnd(idxSqlExpr.eq(idxExpr), true);
// Return element expression
SQLExpression valueExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getElementMapping());
return valueExpr;
}
// FK List
DatastoreClass elementTbl = storeMgr.getDatastoreClass(mmd.getCollection().getElementType(), clr);
// Add join to element table
JavaTypeMapping targetMapping = null;
JavaTypeMapping orderMapping = null;
if (relatedMmds != null) {
targetMapping = elementTbl.getMemberMapping(relatedMmds[0]);
orderMapping = elementTbl.getExternalMapping(mmd, MappingType.EXTERNAL_INDEX);
} else {
targetMapping = elementTbl.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
orderMapping = elementTbl.getExternalMapping(mmd, MappingType.EXTERNAL_INDEX);
}
SQLTable elemSqlTbl = stmt.join(JoinType.INNER_JOIN, listExpr.getSQLTable(), listExpr.getSQLTable().getTable().getIdMapping(), elementTbl, null, targetMapping, null, null);
// Add condition on index
SQLExpression idxSqlExpr = exprFactory.newExpression(stmt, elemSqlTbl, orderMapping);
stmt.whereAnd(idxSqlExpr.eq(idxExpr), true);
// Return element expression
return exprFactory.newExpression(stmt, elemSqlTbl, elementTbl.getIdMapping());
}
Aggregations