agggen.java

来自「数据仓库展示程序」· Java 代码 · 共 983 行 · 第 1/3 页

JAVA
983
字号
/*
// $Id: //open/mondrian/src/main/mondrian/rolap/aggmatcher/AggGen.java#6 $
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2001-2005 Kana Software, Inc. and others.
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
// jhyde, 12 August, 2001
*/

package mondrian.rolap.aggmatcher;

import mondrian.olap.MondrianDef;
import mondrian.olap.Util;
import mondrian.rolap.RolapStar;
import mondrian.rolap.sql.SqlQuery;
import mondrian.rolap.RolapAggregator;
import org.apache.log4j.Logger;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.sql.SQLException;
import java.sql.Types;

/** 
 * This class is used to create "lost" and "collapsed" aggregate table 
 * creation sql (creates the rdbms table and inserts into it from the base
 * fact table).
 * 
 * @author <a>Richard M. Emberson</a>
 * @version 
 */
public class AggGen {
    private static final Logger LOGGER = Logger.getLogger(AggGen.class);

    private final RolapStar star;
    private final RolapStar.Column[] columns;

    /** map RolapStar.Table to list of JdbcSchema Column Usages */
    private final Map collapsedColumnUsages;

    /** set of JdbcSchema Column Usages */
    private final Set notLostColumnUsages;

    /** list of JdbcSchema Column Usages */
    private final List measures;
    private boolean isReady;

    public AggGen(RolapStar star, RolapStar.Column[] columns) {
        this.star = star;
        this.columns = columns;
        this.notLostColumnUsages = new HashSet();
        this.collapsedColumnUsages = new HashMap();
        this.measures = new ArrayList();
        init();
    }
    private Logger getLogger() {
        return LOGGER;
    }

    /** 
     * Return true if this instance is ready to generate the sql. If false,
     * then something went wrong as it was trying to understand the columns. 
     * 
     * @return 
     */
    public boolean isReady() {
        return isReady;
    }

    protected RolapStar.Table getFactTable() {
        return star.getFactTable();
    }
    protected String getFactTableName() {
        return getFactTable().getAlias();
    }
    protected SqlQuery getSqlQuery() {
        return star.getSqlQuery();
    }
    protected String getFactCount() {
        return "fact_count";
    }
    protected JdbcSchema.Table getTable(JdbcSchema db, RolapStar.Table rt) {
        JdbcSchema.Table jt = getTable(db, rt.getAlias());
        return (jt == null)
            ? getTable(db, rt.getTableName())
            : jt;
    }
    protected JdbcSchema.Table getTable(JdbcSchema db, String name) {
        return db.getTable(name);
    }
    protected JdbcSchema.Table.Column getColumn(JdbcSchema.Table table, 
                        String name) {
        return table.getColumn(name);
    }
    protected String getRolapStarColumnName(RolapStar.Column rColumn) {
        MondrianDef.Expression expr = rColumn.getExpression();
        if (expr instanceof MondrianDef.Column) {
            MondrianDef.Column cx = (MondrianDef.Column) expr;
            String name = cx.getColumnName();
            return name;
        }
        return null;
    }
    protected void addForeignKeyToNotLostColumnUsages(
            JdbcSchema.Table.Column column) {

        // first make sure its not already in
        String cname = column.getName();
        for (Iterator it = notLostColumnUsages.iterator(); it.hasNext(); ) {
            JdbcSchema.Table.Column.Usage usage = 
                    (JdbcSchema.Table.Column.Usage) it.next();
            JdbcSchema.Table.Column c = usage.getColumn();
            if (cname.equals(c.getName())) {
                return;
            }
        }
        JdbcSchema.Table.Column.Usage usage = null;
        if (column.hasUsage(JdbcSchema.FOREIGN_KEY_COLUMN_USAGE)) {
            Iterator it = column.getUsages(JdbcSchema.FOREIGN_KEY_COLUMN_USAGE);
            it.hasNext();
            usage = (JdbcSchema.Table.Column.Usage) it.next();
        } else {
            usage = column.newUsage(JdbcSchema.FOREIGN_KEY_COLUMN_USAGE);
            usage.setSymbolicName(JdbcSchema.FOREIGN_KEY_COLUMN_NAME);
        }
        notLostColumnUsages.add(usage);
    }
    
    /** 
     * The columns are the RolapStar columns taking part in an aggregation
     * request. This is what happens.
     * First, for each column, walk up the column's table until one level below
     * the base fact table. The left join condition contains the base fact table
     * and the foreign key column name. This column should not be lost.
     * Get the base fact table's measure columns.
     * With a list of columns that should not be lost and measure, one can
     * create lost create and insert commands.
     */
    private void init() {
        JdbcSchema db = JdbcSchema.makeDB(star.getDataSource());
        try {
            db.load();
        } catch (SQLException ex) {
            getLogger().error(ex);
            return;
        }

        JdbcSchema.Table factTable = getTable(db, getFactTableName());
        if (factTable == null) {
            StringBuffer buf = new StringBuffer(64);
            buf.append("Init: ");
            buf.append("No fact table with name \"");
            buf.append(getFactTableName());
            buf.append("\"");
            getLogger().warn(buf.toString());
            return;
        }
        try {
            factTable.load();
        } catch (SQLException ex) {
            getLogger().error(ex);
            return;
        }

        if (getLogger().isDebugEnabled()) {
            StringBuffer buf = new StringBuffer(512);
            buf.append("Init: ");
            buf.append("RolapStar:");
            buf.append(Util.nl);
            buf.append(getFactTable());
            buf.append(Util.nl);
            buf.append("FactTable:");
            buf.append(Util.nl);
            buf.append(factTable);
            getLogger().debug(buf.toString());
        }

        // do foreign keys
        for (int i = 0; i < columns.length; i++) {
            RolapStar.Column column = columns[i];
            if (getLogger().isDebugEnabled()) {
                StringBuffer buf = new StringBuffer(64);
                buf.append("Init: ");
                buf.append("Column: ");
                buf.append(column);
                getLogger().debug(buf.toString());
            }
            RolapStar.Table table = column.getTable();

            if (table.getParentTable() == null) {
                // this is for those crazy dimensions which are in the
                // fact table, you know, non-shared with no table element

                // How the firetruck to enter information for the
                // collapsed case. This column is in the base fact table
                // and can be part of a dimension hierarchy but no where
                // in the RolapStar is this hiearchy captured - ugg.
                if (! addSpecialCollapsedColumn(db, column)) {
                    return;
                }


                MondrianDef.Expression expr = column.getExpression();
                if (expr instanceof MondrianDef.Column) {
                    MondrianDef.Column exprColumn = (MondrianDef.Column) expr;
                    String name = exprColumn.getColumnName();
                    JdbcSchema.Table.Column c = getColumn(factTable, name);
                    if (c == null) {
                        StringBuffer buf = new StringBuffer(64);
                        buf.append("Init: ");
                        buf.append("FactTable:");
                        buf.append(getFactTableName());
                        buf.append(Util.nl);
                        buf.append("No Column with name \"");
                        buf.append(name);
                        buf.append("\"");
                        getLogger().warn(buf.toString());
                        return;
                    }
                    if (getLogger().isDebugEnabled()) {
                        getLogger().debug("  Jdbc Column: c="+c);
                    }
                    addForeignKeyToNotLostColumnUsages(c);
                }

            } else {

                if (! addCollapsedColumn(db, column)) {
                    return;
                }

                while (table.getParentTable().getParentTable() != null) {
                    table = table.getParentTable();
                }
                RolapStar.Condition cond = table.getCondition();
                if (getLogger().isDebugEnabled()) {
                    getLogger().debug("  RolapStar.Condition: cond="+cond);
                }
                MondrianDef.Expression left = cond.getLeft();
                if (left instanceof MondrianDef.Column) {
                    MondrianDef.Column leftColumn = (MondrianDef.Column) left;
                    String name = leftColumn.getColumnName();
                    JdbcSchema.Table.Column c = getColumn(factTable, name);
                    if (c == null) {
                        StringBuffer buf = new StringBuffer(64);
                        buf.append("Init: ");
                        buf.append("FactTable:");
                        buf.append(getFactTableName());
                        buf.append(Util.nl);
                        buf.append("No Column with name \"");
                        buf.append(name);
                        buf.append("\"");
                        getLogger().warn(buf.toString());
                        return;
                    }
                    if (getLogger().isDebugEnabled()) {
                        getLogger().debug("  Jdbc Column: c="+c);
                    }
                    addForeignKeyToNotLostColumnUsages(c);
                }
            }
        }

        // do measures
        for (Iterator it = getFactTable().getColumns(); it.hasNext(); ) {
            RolapStar.Column rColumn = (RolapStar.Column) it.next();
            String name = getRolapStarColumnName(rColumn);
            if (name == null) {
                StringBuffer buf = new StringBuffer(64);
                buf.append("Init: ");
                buf.append("For fact table \"");
                buf.append(getFactTableName());
                buf.append("\", could not get column name for RolapStar.Column: ");
                buf.append(rColumn);
                getLogger().warn(buf.toString());
                return;
            }
            RolapAggregator aggregator = null;
            String symbolicName = null;
            if (! (rColumn instanceof RolapStar.Measure)) {
                // TODO: whats the solution to this?
                // its a funky dimension column in the fact table!!!
                getLogger().warn("not a measure: " +name);
                continue;
            } else {
                RolapStar.Measure rMeasure = (RolapStar.Measure) rColumn;
                aggregator = rMeasure.getAggregator();
            }
            JdbcSchema.Table.Column c = getColumn(factTable, name);
            if (c == null) {
                StringBuffer buf = new StringBuffer(64);
                buf.append("For RolapStar: \"");
                buf.append(getFactTable().getAlias());
                buf.append("\" measure with name, ");
                buf.append(name);
                buf.append(", is not a column name. ");
                buf.append("The measure's column name may be an expression");
                buf.append(" and currently AggGen does not handle expressions.");
                buf.append(" You will have to add this measure to the");
                buf.append(" aggregate table definition by hand.");
                getLogger().warn(buf.toString());
                continue;
            }
            if (getLogger().isDebugEnabled()) {
                getLogger().debug("  Jdbc Column m="+c);
            }
/*
            JdbcSchema.Table.Column.Usage usage = 
                c.newUsage(JdbcSchema.MEASURE_COLUMN_USAGE);
            usage.setAggregator(aggregator);
            usage.setSymbolicName(rColumn.getName());
            measures.add(usage);
*/

            JdbcSchema.Table.Column.Usage usage = null;
            if (c.hasUsage(JdbcSchema.MEASURE_COLUMN_USAGE)) {
                for (Iterator uit = 
                    c.getUsages(JdbcSchema.MEASURE_COLUMN_USAGE);
                    uit.hasNext(); ) {

⌨️ 快捷键说明

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