Search in sources :

Example 31 with ApiAdapter

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);
}
Also used : ApiAdapter(org.datanucleus.api.ApiAdapter) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Example 32 with ApiAdapter

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);
}
Also used : SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) InExpression(org.datanucleus.store.rdbms.sql.expression.InExpression) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression) CollectionLiteral(org.datanucleus.store.rdbms.sql.expression.CollectionLiteral) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) CollectionExpression(org.datanucleus.store.rdbms.sql.expression.CollectionExpression) TemporalExpression(org.datanucleus.store.rdbms.sql.expression.TemporalExpression) ApiAdapter(org.datanucleus.api.ApiAdapter) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression) JoinType(org.datanucleus.store.rdbms.sql.SQLJoin.JoinType) EnumExpression(org.datanucleus.store.rdbms.sql.expression.EnumExpression) CharacterExpression(org.datanucleus.store.rdbms.sql.expression.CharacterExpression) StringExpression(org.datanucleus.store.rdbms.sql.expression.StringExpression) Collection(java.util.Collection) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 33 with ApiAdapter

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);
}
Also used : SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) ApiAdapter(org.datanucleus.api.ApiAdapter) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) BooleanLiteral(org.datanucleus.store.rdbms.sql.expression.BooleanLiteral) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) CollectionLiteral(org.datanucleus.store.rdbms.sql.expression.CollectionLiteral) Collection(java.util.Collection) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 34 with ApiAdapter

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;
}
Also used : SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) ApiAdapter(org.datanucleus.api.ApiAdapter) Table(org.datanucleus.store.rdbms.table.Table) JoinTable(org.datanucleus.store.rdbms.table.JoinTable) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) NumericSubqueryExpression(org.datanucleus.store.rdbms.sql.expression.NumericSubqueryExpression) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) CollectionLiteral(org.datanucleus.store.rdbms.sql.expression.CollectionLiteral) SelectStatement(org.datanucleus.store.rdbms.sql.SelectStatement) StringLiteral(org.datanucleus.store.rdbms.sql.expression.StringLiteral) Collection(java.util.Collection) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 35 with ApiAdapter

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);
}
Also used : ApiAdapter(org.datanucleus.api.ApiAdapter) ObjectLiteral(org.datanucleus.store.rdbms.sql.expression.ObjectLiteral) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) SQLLiteral(org.datanucleus.store.rdbms.sql.expression.SQLLiteral) ReferenceIdMapping(org.datanucleus.store.rdbms.mapping.java.ReferenceIdMapping) PersistableIdMapping(org.datanucleus.store.rdbms.mapping.java.PersistableIdMapping) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) IllegalExpressionOperationException(org.datanucleus.store.rdbms.sql.expression.IllegalExpressionOperationException) PersistableMapping(org.datanucleus.store.rdbms.mapping.java.PersistableMapping) ReferenceMapping(org.datanucleus.store.rdbms.mapping.java.ReferenceMapping) NullLiteral(org.datanucleus.store.rdbms.sql.expression.NullLiteral) ObjectExpression(org.datanucleus.store.rdbms.sql.expression.ObjectExpression)

Aggregations

ApiAdapter (org.datanucleus.api.ApiAdapter)53 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)19 ObjectProvider (org.datanucleus.state.ObjectProvider)16 ExecutionContext (org.datanucleus.ExecutionContext)12 Map (java.util.Map)11 NucleusException (org.datanucleus.exceptions.NucleusException)11 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)10 Iterator (java.util.Iterator)8 NucleusObjectNotFoundException (org.datanucleus.exceptions.NucleusObjectNotFoundException)8 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)8 Collection (java.util.Collection)7 HashMap (java.util.HashMap)7 RelationType (org.datanucleus.metadata.RelationType)7 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)7 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)6 ClassNotResolvedException (org.datanucleus.exceptions.ClassNotResolvedException)6 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)5 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)5 TypeManager (org.datanucleus.store.types.TypeManager)5 SortedMap (java.util.SortedMap)4