⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recognizer.java

📁 数据仓库展示程序
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                    if (avgAggUsage != null) {
                        makeMeasure(sumFactUsage, avgAggUsage);
                    }
                    if (sumAggUsage != null) {
                        makeMeasure(avgFactUsage, sumAggUsage);
                    }
                }
            }
        }
    }

    /**
     * Here we have the fact usage of either sum or avg and an aggregate usage
     * of the opposite type. We wish to make a new aggregate usage based
     * on the existing usage's column of the same type as the fact usage.
     *
     * @param factUsage fact usage
     * @param aggSiblingUsage existing sibling usage
     */
    protected void makeMeasure(final JdbcSchema.Table.Column.Usage factUsage,
                               final JdbcSchema.Table.Column.Usage aggSiblingUsage) {
        JdbcSchema.Table.Column aggColumn = aggSiblingUsage.getColumn();

        JdbcSchema.Table.Column.Usage aggUsage =
            aggColumn.newUsage(JdbcSchema.MEASURE_COLUMN_USAGE);

        aggUsage.setSymbolicName(factUsage.getSymbolicName());
        convertAggregator(aggUsage,
                          factUsage.getAggregator(),
                          aggSiblingUsage.getAggregator());

        aggUsage.rMeasure = factUsage.rMeasure;
    }

    /**
     * This method creates an aggregate table column measure usage from a fact
     * table column measure usage.
     *
     * @param factUsage
     * @param aggColumn
     */
    protected void makeMeasure(final JdbcSchema.Table.Column.Usage factUsage,
                               final JdbcSchema.Table.Column aggColumn) {
        JdbcSchema.Table.Column.Usage aggUsage =
            aggColumn.newUsage(JdbcSchema.MEASURE_COLUMN_USAGE);

        aggUsage.setSymbolicName(factUsage.getSymbolicName());
        convertAggregator(aggUsage, factUsage.getAggregator());

        aggUsage.rMeasure = factUsage.rMeasure;
    }

    /**
     * This method determine how may aggregate table column's match the fact
     * table foreign key column return in the number matched. For each matching
     * column a foreign key usage is created.
     *
     * @param factUsage
     * @return
     */
    protected abstract int matchForeignKey(JdbcSchema.Table.Column.Usage factUsage);

    /**
     * This method checks the foreign key columns.
     * <p>
     * For each foreign key column usage in the fact table, determine how many
     * aggregate table columns match that column usage. If there is more than
     * one match, then that is an error. If there were no matches, then the
     * foreign key usage is added to the list of fact column foreign key that
     * were not in the aggregate table. This list is returned by this method.
     * <p>
     * This matches foreign keys that were not "lost" or "collapsed".
     *
     * @return  list on not seen foreign key column usages
     */
    protected List checkForeignKeys() {
        msgRecorder.pushContextName("Recognizer.checkForeignKeys");

        try {

            List notSeenForeignKeys = Collections.EMPTY_LIST;

            for (Iterator it =
                dbFactTable.getColumnUsages(JdbcSchema.FOREIGN_KEY_COLUMN_USAGE);
                    it.hasNext(); ) {

                JdbcSchema.Table.Column.Usage factUsage =
                    (JdbcSchema.Table.Column.Usage) it.next();

                int nosMatched = matchForeignKey(factUsage);

                if (nosMatched > 1) {
                    String msg = mres.TooManyMatchingForeignKeyColumns.str(
                            aggTable.getName(),
                            dbFactTable.getName(),
                            new Integer(nosMatched),
                            factUsage.getColumn().getName()
                        );
                    msgRecorder.reportError(msg);

                    returnValue = false;

                } else if (nosMatched == 0) {
                    if (notSeenForeignKeys == Collections.EMPTY_LIST) {
                        notSeenForeignKeys = new ArrayList();
                    }
                    notSeenForeignKeys.add(factUsage);
                }
            }
            return notSeenForeignKeys;

        } finally {
            msgRecorder.popContextName();
        }
    }

    /**
     * This method identifies those columns in the aggregate table that match
     * "collapsed" dimension columns. Remember that a collapsed dimension is one
     * where the higher levels of some hierarchy are columns in the aggregate
     * table (and all of the lower levels are missing - it has aggregated up to
     * the first existing level).
     * <p>
     * Here, we do not start from the fact table, we iterator over each cube.
     * For each of the cube's dimensions, the dimension's hirarchies are
     * iterated over. In turn, each hierarchy's usage is iterated over.
     * if the hierarchy's usage's foreign key is not in the list of not seen
     * foreign keys (the notSeenForeignKeys parameter), then that hierarchy is
     * not considered. If the hierarchy's usage's foreign key is in the not seen
     * list, then starting with the hierarchy's top level, it is determined if
     * the combination of hierarchy, hierarchy usage, and level matches an
     * aggregated table column. If so, then a level usage is created for that
     * column and the hierarchy's next level is considered and so on until a
     * for a level an aggregate table column does not match. Then we continue
     * iterating over the hierarchy usages.
     * <p>
     * This check is different. The others mine the fact table usages. This
     * looks through the fact table's cubes' dimension, hierarchy,
     * hiearchy usages, levels to match up symbolic names for levels. The other
     * checks match on "physical" characteristics, the column name; this matches
     * on "logical" characteristics.
     * <p>
     * Note: Levels should not be created for foreign keys that WERE seen.
     * Currently, this is NOT checked explicitly. For the explicit rules any
     * extra columns MUST ge declared ignored or one gets an error.
     *
     * @param notSeenForeignKeys
     */
    protected void checkLevels(List notSeenForeignKeys) {

        // These are the factTable that do not appear in the aggTable.
        // 1) find all cubes with this given factTable
        // 1) per cube, find all usages with the column as foreign key
        // 2) for each usage, find dimension and its levels
        // 3) determine if level columns are represented

        // In generaly, there is only one cube.
        for (Iterator it = findCubes(); it.hasNext(); ) {
            RolapCube cube = (RolapCube) it.next();

            Dimension[] dims = cube.getDimensions();
            // start dimensions at 1 (0 is measures)
            for (int j = 1; j < dims.length; j++) {
                Dimension dim = dims[j];
                // Ok, got dimension.
                // See if any of the levels exist as columns in the
                // aggTable. This requires applying a map from:
                //   hierarchyName
                //   levelName
                //   levelColumnName
                // to each "unassigned" column in the aggTable.
                // Remember that the rule is if a level does appear,
                // then all of the higher levels must also appear.
                String dimName = dim.getName();

                Hierarchy[] hierarchies = dim.getHierarchies();
                for (int k = 0; k < hierarchies.length; k++) {
                    Hierarchy hierarchy = hierarchies[k];

                    HierarchyUsage[] hierarchyUsages =
                            cube.getUsages(hierarchy);
                    for (int m = 0; m < hierarchyUsages.length; m++) {
                        HierarchyUsage hierarchyUsage = hierarchyUsages[m];

                        // Search through the notSeenForeignKeys list
                        // making sure that this HierarchyUsage's
                        // foreign key is not in the list.
                        String foreignKey = hierarchyUsage.getForeignKey();
                        boolean b = inNotSeenForeignKeys(foreignKey,
                                                         notSeenForeignKeys);
                        if (! b) {
                            // It was not in the not seen list, so ignore
                            continue;
                        }


                        RolapLevel[] levels =
                                (RolapLevel[]) hierarchy.getLevels();
                        // If the top level is seen, then one or more
                        // lower levels may appear but there can be no
                        // missing levels between the top level and
                        // lowest level seen.
                        // On the other hand, if the top level is not
                        // seen, then no other levels should be present.
                        mid_level:
                        for (int n = 0; n < levels.length; n++) {
                            RolapLevel level = levels[n];
                            if (level.isAll()) {
                                continue mid_level;
                            }
                            if (matchLevel(hierarchy, hierarchyUsage, level)) {

                                continue mid_level;

                            } else {
                                // There were no matches, break
                                // For now, do not check lower levels
                                break mid_level;
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Return true if the foreignKey column name is in the list of not seen
     * foreign keys.
     *
     * @param foreignKey
     * @param notSeenForeignKeys
     * @return
     */
    boolean inNotSeenForeignKeys(String foreignKey, List notSeenForeignKeys) {
        for (Iterator it = notSeenForeignKeys.iterator(); it.hasNext(); ) {
            JdbcSchema.Table.Column.Usage usage =
                (JdbcSchema.Table.Column.Usage) it.next();
            if (usage.getColumn().getName().equals(foreignKey)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Debug method: Print out not seen foreign key list.
     *
     * @param notSeenForeignKeys
     */
    private void printNotSeenForeignKeys(List notSeenForeignKeys) {
        LOGGER.debug("Recognizer.printNotSeenForeignKeys: "
            + aggTable.getName());
        for (Iterator it = notSeenForeignKeys.iterator(); it.hasNext(); ) {
            JdbcSchema.Table.Column.Usage usage =
                (JdbcSchema.Table.Column.Usage) it.next();
            LOGGER.debug("  " + usage.getColumn().getName());
        }
    }

    /**
     * Here a measure ussage is created and the right join condition is
     * explicitly supplied. This is needed is when the aggregate table's column
     * names may not match those found in the RolapStar.
     *
     * @param factUsage
     * @param aggColumn
     * @param rightJoinConditionColumnName
     */
    protected void makeForeignKey(final JdbcSchema.Table.Column.Usage factUsage,
                                  final JdbcSchema.Table.Column aggColumn,
                                  final String rightJoinConditionColumnName) {
        JdbcSchema.Table.Column.Usage aggUsage =
            aggColumn.newUsage(JdbcSchema.FOREIGN_KEY_COLUMN_USAGE);
        aggUsage.setSymbolicName("FOREIGN_KEY");
        // Extract from RolapStar enough stuff to build
        // AggStar subtable except the column name of the right join
        // condition might be different
        aggUsage.rTable = factUsage.rTable;
        aggUsage.rightJoinConditionColumnName = rightJoinConditionColumnName;

        aggUsage.rColumn = factUsage.rColumn;
    }

    /**
     * Match a aggregate table column given the hierarchy, hierarchy usage, and
     * rolap level returning true if a match is found.
     *
     * @param hierarchy
     * @param hierarchyUsage
     * @param level
     * @return
     */
    protected abstract boolean matchLevel(final Hierarchy hierarchy,
                                          final HierarchyUsage hierarchyUsage,
                                          final RolapLevel level);

    /**
     * Make a level column usage.
     * <p>
     * Note there is a check in this code. If a given aggregate table column has
     * already has a level usage, then that usage must all refer to the same
     * hierarchy usage join table and column name as the one that calling this
     * method was to create. If there is an existing level usage for the
     * column and it matches something else, then it is an error.
     *
     * @param aggColumn
     * @param hierarchy
     * @param hierarchyUsage
     * @param factColumnName
     * @param levelColumnName
     * @param symbolicName
     */
    protected void makeLevel(final JdbcSchema.Table.Column aggColumn,
                             final Hierarchy hierarchy,
                             final HierarchyUsage hierarchyUsage,
                             final String factColumnName,
                             final String levelColumnName,
                             final String symbolicName) {

        msgRecorder.pushContextName("Recognizer.makeLevel");

        try {

        if (aggColumn.hasUsage(JdbcSchema.LEVEL_COLUMN_USAGE)) {
            // The column has at least one usage of level type
            // make sure we are looking at the
            // same table and column
            for (Iterator uit =
                aggColumn.getUsages(JdbcSchema.LEVEL_COLUMN_USAGE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -