Search in sources :

Example 51 with JavaTypeMapping

use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.

the class ElementContainerStore method getSizeStmt.

/**
 * Generate statement for getting the size of the container.
 * The order part is only present when an order mapping is used.
 * The discriminator part is only present when the element has a discriminator.
 * <PRE>
 * SELECT COUNT(*) FROM TBL THIS
 * [INNER JOIN ELEM_TBL ELEM ON TBL.COL = ELEM.ID] - when no null
 * [LEFT OUTER JOIN ELEM_TBL ELEM ON TBL.COL = ELEM.ID] - when allows null
 * WHERE THIS.OWNERCOL=?
 * [AND THIS.ORDERCOL IS NOT NULL]
 * [AND (DISCRIMINATOR=? OR DISCRMINATOR=? OR DISCRIMINATOR=? [OR DISCRIMINATOR IS NULL])]
 * [AND RELATION_DISCRIM=?]
 * </PRE>
 * The discriminator part includes all subclasses of the element type.
 * If the element is in a different table to the container then an INNER JOIN will be present to
 * link the two tables, and table aliases will be present also.
 * @return The Statement returning the size of the container.
 */
protected String getSizeStmt() {
    if (sizeStmt != null) {
        // Statement exists and didn't need any discriminator when setting up the statement so just reuse it
        return sizeStmt;
    }
    synchronized (this) {
        boolean usingDiscriminatorInSizeStmt = false;
        String containerAlias = "THIS";
        StringBuilder stmt = new StringBuilder();
        if (elementInfo == null) {
            // Serialised/embedded elements in a join table
            stmt.append("SELECT COUNT(*) FROM ").append(containerTable.toString()).append(" ").append(containerAlias);
            stmt.append(" WHERE ");
            BackingStoreHelper.appendWhereClauseForMapping(stmt, ownerMapping, containerAlias, true);
            if (orderMapping != null) {
                // eliminate records that are added but may not be positioned yet.
                for (int i = 0; i < orderMapping.getNumberOfDatastoreMappings(); i++) {
                    stmt.append(" AND ");
                    stmt.append(containerAlias).append(".").append(orderMapping.getDatastoreMapping(i).getColumn().getIdentifier().toString());
                    stmt.append(">=0");
                }
            }
            JavaTypeMapping softDeleteMapping = containerTable.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
            if (softDeleteMapping != null) {
                stmt.append(" AND ").append(containerAlias).append(".");
                stmt.append(softDeleteMapping.getDatastoreMapping(0).getColumn().getIdentifier().toString());
                // TODO Cater for columns that store the DELETED flag as ("Y","N") or (1,0)
                stmt.append("=FALSE");
            }
            if (relationDiscriminatorMapping != null) {
                BackingStoreHelper.appendWhereClauseForMapping(stmt, relationDiscriminatorMapping, containerAlias, false);
            }
            sizeStmt = stmt.toString();
            return sizeStmt;
        }
        if (usingJoinTable()) {
            // Join table collection/array, so do COUNT of join table
            String joinedElementAlias = "ELEM";
            ComponentInfo elemInfo = elementInfo[0];
            stmt.append("SELECT COUNT(*) FROM ").append(containerTable.toString()).append(" ").append(containerAlias);
            // Add join to element table if required (only allows for 1 element table currently)
            boolean joinedDiscrim = false;
            if (elemInfo.getDiscriminatorMapping() != null) {
                // Need join to the element table to restrict the discriminator
                joinedDiscrim = true;
                JavaTypeMapping elemIdMapping = elemInfo.getDatastoreClass().getIdMapping();
                stmt.append(allowNulls ? " LEFT OUTER JOIN " : " INNER JOIN ");
                stmt.append(elemInfo.getDatastoreClass().toString()).append(" ").append(joinedElementAlias).append(" ON ");
                for (int j = 0; j < elementMapping.getNumberOfDatastoreMappings(); j++) {
                    if (j > 0) {
                        stmt.append(" AND ");
                    }
                    stmt.append(containerAlias).append(".").append(elementMapping.getDatastoreMapping(j).getColumn().getIdentifier());
                    stmt.append("=");
                    stmt.append(joinedElementAlias).append(".").append(elemIdMapping.getDatastoreMapping(j).getColumn().getIdentifier());
                }
            }
            // TODO Add join to owner if ownerMapping is for supertable
            stmt.append(" WHERE ");
            BackingStoreHelper.appendWhereClauseForMapping(stmt, ownerMapping, containerAlias, true);
            if (orderMapping != null) {
                // eliminate records that are added but may not be positioned yet.
                for (int j = 0; j < orderMapping.getNumberOfDatastoreMappings(); j++) {
                    stmt.append(" AND ");
                    stmt.append(containerAlias).append(".").append(orderMapping.getDatastoreMapping(j).getColumn().getIdentifier().toString());
                    stmt.append(">=0");
                }
            }
            JavaTypeMapping softDeleteMapping = containerTable.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
            if (softDeleteMapping != null) {
                stmt.append(" AND ").append(containerAlias).append(".");
                stmt.append(softDeleteMapping.getDatastoreMapping(0).getColumn().getIdentifier().toString());
                stmt.append("=FALSE");
            }
            // Add a discriminator filter for collections with an element discriminator
            StringBuilder discrStmt = new StringBuilder();
            if (elemInfo.getDiscriminatorMapping() != null) {
                usingDiscriminatorInSizeStmt = true;
                JavaTypeMapping discrimMapping = elemInfo.getDiscriminatorMapping();
                Collection<String> classNames = storeMgr.getSubClassesForClass(elemInfo.getClassName(), true, clr);
                classNames.add(elemInfo.getClassName());
                for (String className : classNames) {
                    Class cls = clr.classForName(className);
                    if (!Modifier.isAbstract(cls.getModifiers())) {
                        for (int j = 0; j < discrimMapping.getNumberOfDatastoreMappings(); j++) {
                            if (discrStmt.length() > 0) {
                                discrStmt.append(" OR ");
                            }
                            discrStmt.append(joinedDiscrim ? joinedElementAlias : containerAlias);
                            discrStmt.append(".");
                            discrStmt.append(discrimMapping.getDatastoreMapping(j).getColumn().getIdentifier().toString());
                            discrStmt.append("=");
                            discrStmt.append(discrimMapping.getDatastoreMapping(j).getUpdateInputParameter());
                        }
                    }
                }
            }
            if (discrStmt.length() > 0) {
                stmt.append(" AND (");
                stmt.append(discrStmt);
                if (allowNulls) {
                    stmt.append(" OR ");
                    stmt.append(elemInfo.getDiscriminatorMapping().getDatastoreMapping(0).getColumn().getIdentifier().toString());
                    stmt.append(" IS NULL");
                }
                stmt.append(")");
            }
            if (relationDiscriminatorMapping != null) {
                BackingStoreHelper.appendWhereClauseForMapping(stmt, relationDiscriminatorMapping, containerAlias, false);
            }
        } else {
            // ForeignKey collection/array, so UNION all of the element COUNTs
            for (int i = 0; i < elementInfo.length; i++) {
                if (i > 0) {
                    stmt.append(" UNION ");
                }
                ComponentInfo elemInfo = elementInfo[i];
                stmt.append("SELECT COUNT(*),").append("'" + elemInfo.getAbstractClassMetaData().getName() + "'");
                stmt.append(" FROM ").append(elemInfo.getDatastoreClass().toString()).append(" ").append(containerAlias);
                stmt.append(" WHERE ");
                BackingStoreHelper.appendWhereClauseForMapping(stmt, ownerMapping, containerAlias, true);
                if (orderMapping != null) {
                    // eliminate records that are added but may not be positioned yet.
                    for (int j = 0; j < orderMapping.getNumberOfDatastoreMappings(); j++) {
                        stmt.append(" AND ");
                        stmt.append(containerAlias).append(".").append(orderMapping.getDatastoreMapping(j).getColumn().getIdentifier().toString());
                        stmt.append(">=0");
                    }
                }
                JavaTypeMapping softDeleteMapping = containerTable.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
                if (softDeleteMapping != null) {
                    stmt.append(" AND ").append(containerAlias).append(".");
                    stmt.append(softDeleteMapping.getDatastoreMapping(0).getColumn().getIdentifier().toString());
                    stmt.append("=FALSE");
                }
                // Add a discriminator filter for collections with an element discriminator
                StringBuilder discrStmt = new StringBuilder();
                if (elemInfo.getDiscriminatorMapping() != null) {
                    usingDiscriminatorInSizeStmt = true;
                    JavaTypeMapping discrimMapping = elemInfo.getDiscriminatorMapping();
                    Collection<String> classNames = storeMgr.getSubClassesForClass(elemInfo.getClassName(), true, clr);
                    classNames.add(elemInfo.getClassName());
                    for (String className : classNames) {
                        Class cls = clr.classForName(className);
                        if (!Modifier.isAbstract(cls.getModifiers())) {
                            for (int j = 0; j < discrimMapping.getNumberOfDatastoreMappings(); j++) {
                                if (discrStmt.length() > 0) {
                                    discrStmt.append(" OR ");
                                }
                                discrStmt.append(containerAlias).append(".").append(discrimMapping.getDatastoreMapping(j).getColumn().getIdentifier().toString());
                                discrStmt.append("=");
                                discrStmt.append(discrimMapping.getDatastoreMapping(j).getUpdateInputParameter());
                            }
                        }
                    }
                }
                if (discrStmt.length() > 0) {
                    stmt.append(" AND (");
                    stmt.append(discrStmt);
                    if (allowNulls) {
                        stmt.append(" OR ");
                        stmt.append(elemInfo.getDiscriminatorMapping().getDatastoreMapping(0).getColumn().getIdentifier().toString());
                        stmt.append(" IS NULL");
                    }
                    stmt.append(")");
                }
                if (relationDiscriminatorMapping != null) {
                    BackingStoreHelper.appendWhereClauseForMapping(stmt, relationDiscriminatorMapping, containerAlias, false);
                }
            }
        }
        if (!usingDiscriminatorInSizeStmt) {
            sizeStmt = stmt.toString();
        }
        return stmt.toString();
    }
}
Also used : JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)

Example 52 with JavaTypeMapping

use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.

the class SQLText method applyParametersToStatement.

/**
 * Method to set the parameters in the supplied PreparedStatement using their mappings and
 * provided values.
 * @param ec execution context
 * @param ps The PreparedStatement
 */
public void applyParametersToStatement(ExecutionContext ec, PreparedStatement ps) {
    if (parameters != null) {
        int num = 1;
        Iterator<SQLStatementParameter> i = parameters.iterator();
        while (i.hasNext()) {
            SQLStatementParameter param = i.next();
            JavaTypeMapping mapping = param.getMapping();
            if (mapping != null) {
                Object value = param.getValue();
                if (param.getColumnNumber() >= 0) {
                    Object colValue = null;
                    if (value != null) {
                        // Parameter is for a particular column of the overall object/mapping
                        // so assume that the object is persistable (or id of persistable)
                        ClassLoaderResolver clr = ec.getClassLoaderResolver();
                        AbstractClassMetaData cmd = ec.getMetaDataManager().getMetaDataForClass(mapping.getType(), clr);
                        RDBMSStoreManager storeMgr = mapping.getStoreManager();
                        if (cmd.getIdentityType() == IdentityType.DATASTORE) {
                            colValue = mapping.getValueForDatastoreMapping(ec.getNucleusContext(), param.getColumnNumber(), value);
                        } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
                            colValue = SQLStatementHelper.getValueForPrimaryKeyIndexOfObjectUsingReflection(value, param.getColumnNumber(), cmd, storeMgr, clr);
                        }
                    }
                    mapping.getDatastoreMapping(param.getColumnNumber()).setObject(ps, num, colValue);
                    num++;
                } else {
                    mapping.setObject(ec, ps, MappingHelper.getMappingIndices(num, mapping), value);
                    if (mapping.getNumberOfDatastoreMappings() > 0) {
                        num += mapping.getNumberOfDatastoreMappings();
                    } else {
                        num += 1;
                    }
                }
            }
        }
    }
}
Also used : JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager)

Example 53 with JavaTypeMapping

use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.

the class SelectStatement method addOrderingColumnsToSelect.

/**
 * Convenience method to add any necessary columns to the SELECT that are needed
 * by the ordering constraint.
 */
protected void addOrderingColumnsToSelect() {
    if (// Don't do this for subqueries, since we will be selecting just the necessary column(s)
    orderingExpressions != null && parent == null) {
        // Add any ordering columns to the SELECT
        DatastoreAdapter dba = getDatastoreAdapter();
        if (dba.supportsOption(DatastoreAdapter.ORDERBY_USING_SELECT_COLUMN_INDEX)) {
            // Order using the indexes of the ordering columns in the SELECT
            orderingColumnIndexes = new int[orderingExpressions.length];
            // Add the ordering columns to the selected list, saving the positions
            for (int i = 0; i < orderingExpressions.length; ++i) {
                orderingColumnIndexes[i] = selectItem(orderingExpressions[i].toSQLText(), null, !aggregated);
                if (unions != null && allowUnions) {
                    Iterator<SelectStatement> iterator = unions.iterator();
                    while (iterator.hasNext()) {
                        SelectStatement stmt = iterator.next();
                        stmt.selectItem(orderingExpressions[i].toSQLText(), null, !aggregated);
                    }
                }
            }
        } else if (dba.supportsOption(DatastoreAdapter.INCLUDE_ORDERBY_COLS_IN_SELECT)) {
            // Order using column aliases "NUCORDER{i}"
            for (int i = 0; i < orderingExpressions.length; ++i) {
                if (orderingExpressions[i] instanceof ResultAliasExpression) {
                // Nothing to do since this is ordering by a result alias
                } else if (orderingExpressions[i].getNumberOfSubExpressions() == 1 || aggregated) {
                    String orderExprAlias = rdbmsMgr.getIdentifierFactory().getIdentifierInAdapterCase("NUCORDER" + i);
                    if (unions != null && allowUnions) {
                        Iterator<SelectStatement> iterator = unions.iterator();
                        while (iterator.hasNext()) {
                            SelectStatement stmt = iterator.next();
                            stmt.selectItem(orderingExpressions[i].toSQLText(), aggregated ? null : orderExprAlias, !aggregated);
                        }
                    }
                    selectItem(orderingExpressions[i].toSQLText(), aggregated ? null : orderExprAlias, !aggregated);
                } else {
                    JavaTypeMapping m = orderingExpressions[i].getJavaTypeMapping();
                    DatastoreMapping[] mappings = m.getDatastoreMappings();
                    for (int j = 0; j < mappings.length; j++) {
                        String alias = rdbmsMgr.getIdentifierFactory().getIdentifierInAdapterCase("NUCORDER" + i + "_" + j);
                        DatastoreIdentifier aliasId = rdbmsMgr.getIdentifierFactory().newColumnIdentifier(alias);
                        SQLColumn col = new SQLColumn(orderingExpressions[i].getSQLTable(), mappings[j].getColumn(), aliasId);
                        selectItem(new SQLText(col.getColumnSelectString()), alias, !aggregated);
                        if (unions != null && allowUnions) {
                            Iterator<SelectStatement> iterator = unions.iterator();
                            while (iterator.hasNext()) {
                                SelectStatement stmt = iterator.next();
                                stmt.selectItem(new SQLText(col.getColumnSelectString()), alias, !aggregated);
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : ResultAliasExpression(org.datanucleus.store.rdbms.sql.expression.ResultAliasExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) DatastoreMapping(org.datanucleus.store.rdbms.mapping.datastore.DatastoreMapping) DatastoreIdentifier(org.datanucleus.store.rdbms.identifier.DatastoreIdentifier) DatastoreAdapter(org.datanucleus.store.rdbms.adapter.DatastoreAdapter)

Example 54 with JavaTypeMapping

use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.

the class UnionStatementGenerator method addTypeSelectForClass.

/**
 * Convenience method to add a SELECT of a dummy column accessible as "DN_TYPE" storing the class name.
 * @param stmt SQLStatement
 * @param className Name of the class
 */
private void addTypeSelectForClass(SelectStatement stmt, String className) {
    // Add SELECT of dummy metadata for this class ("'mydomain.MyClass' AS DN_TYPE")
    /*if (hasOption(OPTION_ALLOW_NULLS))
        {
            NullLiteral nullLtl = new NullLiteral(stmt, null, null, null);
            stmt.select(nullLtl, NUC_TYPE_COLUMN);
        }
        else
        {*/
    // Add SELECT of dummy column accessible as "DN_TYPE" containing the classname
    JavaTypeMapping m = storeMgr.getMappingManager().getMapping(String.class);
    String nuctypeName = className;
    if (maxClassNameLength > nuctypeName.length()) {
        nuctypeName = StringUtils.leftAlignedPaddedString(nuctypeName, maxClassNameLength);
    }
    StringLiteral lit = new StringLiteral(stmt, m, nuctypeName, null);
    stmt.select(lit, DN_TYPE_COLUMN);
/*}*/
}
Also used : StringLiteral(org.datanucleus.store.rdbms.sql.expression.StringLiteral) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)

Example 55 with JavaTypeMapping

use of org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping in project datanucleus-rdbms by datanucleus.

the class SQLStatementHelper method getValueForPrimaryKeyIndexOfObjectUsingReflection.

/**
 * Convenience method to use reflection to extract the value of a PK field of the provided object.
 * @param value The value of the overall object
 * @param index Index of the PK field whose value we need to return
 * @param cmd Metadata for the class
 * @param storeMgr Store manager
 * @param clr ClassLoader resolver
 * @return Value of this index of the PK field
 */
public static Object getValueForPrimaryKeyIndexOfObjectUsingReflection(Object value, int index, AbstractClassMetaData cmd, RDBMSStoreManager storeMgr, ClassLoaderResolver clr) {
    if (cmd.getIdentityType() == IdentityType.DATASTORE) {
        throw new NucleusException("This method does not support datastore-identity");
    }
    int position = 0;
    int[] pkPositions = cmd.getPKMemberPositions();
    for (int pkPosition : pkPositions) {
        AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkPosition);
        Object memberValue = null;
        if (mmd instanceof FieldMetaData) {
            memberValue = ClassUtils.getValueOfFieldByReflection(value, mmd.getName());
        } else {
            memberValue = ClassUtils.getValueOfMethodByReflection(value, ClassUtils.getJavaBeanGetterName(mmd.getName(), false));
        }
        if (storeMgr.getApiAdapter().isPersistable(mmd.getType())) {
            // Compound PK field, so recurse
            // TODO Cater for cases without own table ("subclass-table")
            AbstractClassMetaData subCmd = storeMgr.getMetaDataManager().getMetaDataForClass(mmd.getType(), clr);
            DatastoreClass subTable = storeMgr.getDatastoreClass(mmd.getTypeName(), clr);
            JavaTypeMapping subMapping = subTable.getIdMapping();
            Object subValue = getValueForPrimaryKeyIndexOfObjectUsingReflection(memberValue, index - position, subCmd, storeMgr, clr);
            if (index < position + subMapping.getNumberOfDatastoreMappings()) {
                return subValue;
            }
            position = position + subMapping.getNumberOfDatastoreMappings();
        } else {
            // Normal PK field
            if (position == index) {
                if (mmd instanceof FieldMetaData) {
                    return ClassUtils.getValueOfFieldByReflection(value, mmd.getName());
                }
                return ClassUtils.getValueOfMethodByReflection(value, ClassUtils.getJavaBeanGetterName(mmd.getName(), false));
            }
            position++;
        }
    }
    return null;
}
Also used : FieldMetaData(org.datanucleus.metadata.FieldMetaData) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SecondaryDatastoreClass(org.datanucleus.store.rdbms.table.SecondaryDatastoreClass) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Aggregations

JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)230 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)96 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)82 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)82 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)81 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)76 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)69 ArrayList (java.util.ArrayList)66 NucleusException (org.datanucleus.exceptions.NucleusException)57 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)50 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)47 NumericExpression (org.datanucleus.store.rdbms.sql.expression.NumericExpression)43 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)37 PersistableMapping (org.datanucleus.store.rdbms.mapping.java.PersistableMapping)30 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)30 StringExpression (org.datanucleus.store.rdbms.sql.expression.StringExpression)27 List (java.util.List)25 ReferenceMapping (org.datanucleus.store.rdbms.mapping.java.ReferenceMapping)22 StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)21 StringLiteral (org.datanucleus.store.rdbms.sql.expression.StringLiteral)21