use of org.datanucleus.api.ApiAdapter in project datanucleus-rdbms by datanucleus.
the class MappingHelper method getObjectForDatastoreIdentity.
/**
* Get the object instance for a class using datastore identity
* @param ec ExecutionContext
* @param mapping The mapping in which this is returned
* @param rs the ResultSet
* @param resultIndexes indexes for the result set
* @param cmd the AbstractClassMetaData
* @return the id
*/
public static Object getObjectForDatastoreIdentity(ExecutionContext ec, JavaTypeMapping mapping, final ResultSet rs, int[] resultIndexes, AbstractClassMetaData cmd) {
// Datastore Identity - retrieve the OID for the class.
// Note that this is a temporary OID that is simply formed from the type of base class in the relationship
// and the id stored in the FK. The real OID for the object may be of a different class.
// For that reason we get the object by checking the inheritance (final param in getObjectById())
Object oid = null;
if (mapping.getNumberOfDatastoreMappings() > 0) {
oid = mapping.getDatastoreMapping(0).getObject(rs, resultIndexes[0]);
} else {
// 1-1 bidirectional "mapped-by" relation, so use ID mappings of related class to retrieve the value
if (// TODO why is it null for PC concrete classes?
mapping.getReferenceMapping() != null) {
return mapping.getReferenceMapping().getObject(ec, rs, resultIndexes);
}
Class fieldType = mapping.getMemberMetaData().getType();
JavaTypeMapping referenceMapping = mapping.getStoreManager().getDatastoreClass(fieldType.getName(), ec.getClassLoaderResolver()).getIdMapping();
oid = referenceMapping.getDatastoreMapping(0).getObject(rs, resultIndexes[0]);
}
if (oid != null) {
oid = ec.getNucleusContext().getIdentityManager().getDatastoreId(mapping.getType(), oid);
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("041034", oid));
}
}
ApiAdapter api = ec.getApiAdapter();
if (// why check this?
api.isPersistable(oid)) {
return oid;
}
return oid == null ? null : ec.findObject(oid, false, true, null);
}
use of org.datanucleus.api.ApiAdapter in project datanucleus-rdbms by datanucleus.
the class CollectionContainsMethod 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 || args.size() > 1) {
throw new NucleusException(Localiser.msg("060016", "contains", "CollectionExpression", 1));
}
CollectionExpression collExpr = (CollectionExpression) expr;
AbstractMemberMetaData mmd = collExpr.getJavaTypeMapping().getMemberMetaData();
SQLExpression elemExpr = args.get(0);
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
if (elemExpr.isParameter()) {
// Element is a parameter so make sure its type is set
if (mmd != null && mmd.getCollection() != null) {
Class elementCls = stmt.getQueryGenerator().getClassLoaderResolver().classForName(mmd.getCollection().getElementType());
stmt.getQueryGenerator().bindParameter(elemExpr.getParameterName(), elementCls);
}
}
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
if (collExpr instanceof CollectionLiteral) {
// Literal collection
CollectionLiteral lit = (CollectionLiteral) collExpr;
Collection coll = (Collection) lit.getValue();
JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
if (coll == null || coll.isEmpty()) {
return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
}
if (collExpr.isParameter()) {
stmt.getQueryGenerator().useParameterExpressionAsLiteral((CollectionLiteral) collExpr);
}
boolean useInExpression = false;
List<SQLExpression> collElementExprs = lit.getElementExpressions();
if (collElementExprs != null && !collElementExprs.isEmpty()) {
// Make sure the the collection element(s) are compatible with the elemExpr
boolean incompatible = true;
Class elemtype = clr.classForName(elemExpr.getJavaTypeMapping().getType());
Iterator<SQLExpression> collElementExprIter = collElementExprs.iterator();
while (collElementExprIter.hasNext()) {
SQLExpression collElementExpr = collElementExprIter.next();
Class collElemType = clr.classForName(collElementExpr.getJavaTypeMapping().getType());
if (elementTypeCompatible(elemtype, collElemType)) {
incompatible = false;
break;
}
}
if (incompatible) {
// The provided element type isn't assignable to any of the input collection elements!
return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
}
// Check if we should compare using an "IN (...)" expression
SQLExpression collElementExpr = collElementExprs.get(0);
if (collElementExpr instanceof StringExpression || collElementExpr instanceof NumericExpression || collElementExpr instanceof TemporalExpression || collElementExpr instanceof CharacterExpression || collElementExpr instanceof EnumExpression) {
useInExpression = true;
}
}
if (useInExpression) {
// Return "elem IN (val1, val2, ...)"
SQLExpression[] exprs = (collElementExprs != null ? collElementExprs.toArray(new SQLExpression[collElementExprs.size()]) : null);
return new InExpression(elemExpr, exprs);
}
// Return "elem == val1 || elem == val2 || elem == val3 ..."
BooleanExpression bExpr = null;
if (collElementExprs != null) {
for (int i = 0; i < collElementExprs.size(); i++) {
if (bExpr == null) {
bExpr = (collElementExprs.get(i)).eq(elemExpr);
} else {
bExpr = bExpr.ior((collElementExprs.get(i)).eq(elemExpr));
}
}
}
if (bExpr != null) {
bExpr.encloseInParentheses();
}
return bExpr;
}
if (mmd == null) {
throw new NucleusUserException("Cannot perform Collection.contains when the field metadata is not provided");
}
if (mmd.isSerialized()) {
throw new NucleusUserException("Cannot perform Collection.contains when the collection is being serialised");
}
ApiAdapter api = stmt.getRDBMSManager().getApiAdapter();
Class elementType = clr.classForName(mmd.getCollection().getElementType());
if (!api.isPersistable(elementType) && mmd.getJoinMetaData() == null) {
throw new NucleusUserException("Cannot perform Collection.contains when the collection<Non-Persistable> is not in a join table");
}
if (stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.FILTER) {
boolean useSubquery = getNeedsSubquery(stmt, collExpr, elemExpr);
JoinType joinType = JoinType.INNER_JOIN;
if (elemExpr instanceof UnboundExpression) {
// See if the user has defined what should be used
String varName = ((UnboundExpression) elemExpr).getVariableName();
String extensionName = "datanucleus.query.jdoql." + varName + ".join";
String extensionValue = (String) stmt.getQueryGenerator().getValueForExtension(extensionName);
if (extensionValue != null) {
if (extensionValue.equalsIgnoreCase("SUBQUERY")) {
useSubquery = true;
} else if (extensionValue.equalsIgnoreCase("INNERJOIN")) {
useSubquery = false;
} else if (extensionValue.equalsIgnoreCase("LEFTOUTERJOIN")) {
joinType = JoinType.LEFT_OUTER_JOIN;
}
}
}
if (useSubquery) {
return containsAsSubquery(stmt, collExpr, elemExpr);
}
return containsAsJoin(stmt, collExpr, elemExpr, joinType);
}
return containsAsSubquery(stmt, collExpr, elemExpr);
}
use of org.datanucleus.api.ApiAdapter in project datanucleus-rdbms by datanucleus.
the class CollectionIsEmptyMethod 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", "isEmpty", "CollectionExpression"));
}
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
if (expr instanceof CollectionLiteral) {
Collection coll = (Collection) ((CollectionLiteral) expr).getValue();
boolean isEmpty = (coll == null || coll.size() == 0);
JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, false);
return new BooleanLiteral(stmt, m, isEmpty ? Boolean.TRUE : Boolean.FALSE);
}
AbstractMemberMetaData mmd = ((CollectionExpression) expr).getJavaTypeMapping().getMemberMetaData();
if (mmd.isSerialized()) {
throw new NucleusUserException("Cannot perform Collection.isEmpty when the collection is being serialised");
}
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
ApiAdapter api = stmt.getRDBMSManager().getApiAdapter();
Class elementType = clr.classForName(mmd.getCollection().getElementType());
if (!api.isPersistable(elementType) && mmd.getJoinMetaData() == null) {
throw new NucleusUserException("Cannot perform Collection.isEmpty when the collection<Non-Persistable> is not in a join table");
}
SQLExpression sizeExpr = exprFactory.invokeMethod(stmt, Collection.class.getName(), "size", expr, args);
JavaTypeMapping mapping = exprFactory.getMappingForType(Integer.class, true);
SQLExpression zeroExpr = exprFactory.newLiteral(stmt, mapping, 0);
return sizeExpr.eq(zeroExpr);
}
use of org.datanucleus.api.ApiAdapter 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.api.ApiAdapter in project datanucleus-rdbms by datanucleus.
the class JDOHelperGetObjectIdMethod 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.getObjectId without an argument");
}
SQLExpression expr = args.get(0);
if (expr == null) {
return new NullLiteral(stmt, null, null, null);
}
if (expr instanceof SQLLiteral) {
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
ApiAdapter api = storeMgr.getApiAdapter();
Object id = api.getIdForObject(((SQLLiteral) expr).getValue());
if (id == null) {
return new NullLiteral(stmt, null, null, null);
}
JavaTypeMapping m = stmt.getSQLExpressionFactory().getMappingForType(id.getClass(), true);
return new ObjectLiteral(stmt, m, id, null);
} else if (ObjectExpression.class.isAssignableFrom(expr.getClass())) {
// When the expression represents a PC object need to extract out as the identity
if (expr.getJavaTypeMapping() instanceof PersistableMapping) {
JavaTypeMapping mapping = new PersistableIdMapping((PersistableMapping) expr.getJavaTypeMapping());
return new ObjectExpression(stmt, expr.getSQLTable(), mapping);
} else if (expr.getJavaTypeMapping() instanceof ReferenceMapping) {
JavaTypeMapping mapping = new ReferenceIdMapping((ReferenceMapping) expr.getJavaTypeMapping());
return new ObjectExpression(stmt, expr.getSQLTable(), mapping);
}
return expr;
}
throw new IllegalExpressionOperationException("JDOHelper.getObjectId", expr);
}
Aggregations