aggstar.java

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

JAVA
1,134
字号
/*
// $Id: //open/mondrian/src/main/mondrian/rolap/aggmatcher/AggStar.java#11 $
// 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.*;
import mondrian.recorder.MessageRecorder;
import mondrian.rolap.*;
import mondrian.rolap.sql.SqlQuery;
import mondrian.resource.MondrianResource;

import org.apache.log4j.Logger;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.*;
import java.util.*;

/**
 * This is an aggregate table version of a RolapStar for a fact table.
 * <p>
 * There is the following class structure:
 * <pre>
 * AggStar
 *   Table
 *     JoinCondition
 *     Column
 *     Level extends Column
 *   FactTable extends Table
 *     Measure extends Table.Column
 *   DimTable extends Table
 * <pre>
 * Each inner class is non-static meaning that instances have implied references
 * to the enclosing object.
 *
 * @author <a>Richard M. Emberson</a>
 * @version
 */
public class AggStar {
    private static final Logger LOGGER = Logger.getLogger(AggStar.class);

    static Logger getLogger() {
        return LOGGER;
    }

    private static final MondrianResource mres = MondrianResource.instance();

    /**
     * Creates an AggStar and all of its {@link Table}, {@link Table.Column}s,
     * etc.
     *
     * @param star
     * @param dbTable
     * @param msgRecorder
     * @return
     */
    public static AggStar makeAggStar(final RolapStar star,
                                      final JdbcSchema.Table dbTable,
                                      final MessageRecorder msgRecorder) {

        AggStar aggStar = new AggStar(star, dbTable);
        AggStar.FactTable aggStarFactTable = aggStar.getFactTable();

        //////////////////////////////////////////////////////////////////////
        //
        // load fact count
        for (Iterator it =
            dbTable.getColumnUsages(JdbcSchema.FACT_COUNT_COLUMN_USAGE);
                    it.hasNext();) {
            JdbcSchema.Table.Column.Usage usage =
                (JdbcSchema.Table.Column.Usage) it.next();
            aggStarFactTable.loadFactCount(usage);
        }
        //
        //////////////////////////////////////////////////////////////////////

        //////////////////////////////////////////////////////////////////////
        //
        // load measures
        for (Iterator it =
                dbTable.getColumnUsages(JdbcSchema.MEASURE_COLUMN_USAGE);
                it.hasNext();) {
            JdbcSchema.Table.Column.Usage usage =
                (JdbcSchema.Table.Column.Usage) it.next();
            aggStarFactTable.loadMeasure(usage);
        }
        //
        //////////////////////////////////////////////////////////////////////

        //////////////////////////////////////////////////////////////////////
        //
        // load foreign keys
        for (Iterator it =
                dbTable.getColumnUsages(JdbcSchema.FOREIGN_KEY_COLUMN_USAGE);
                it.hasNext();) {
            JdbcSchema.Table.Column.Usage usage =
                (JdbcSchema.Table.Column.Usage) it.next();
            aggStarFactTable.loadForeignKey(usage);
        }
        //
        //////////////////////////////////////////////////////////////////////

        //////////////////////////////////////////////////////////////////////
        //
        // load levels
        for (Iterator it =
                dbTable.getColumnUsages(JdbcSchema.LEVEL_COLUMN_USAGE);
                it.hasNext();) {
            JdbcSchema.Table.Column.Usage usage =
                (JdbcSchema.Table.Column.Usage) it.next();
            aggStarFactTable.loadLevel(usage);
        }
        //
        //////////////////////////////////////////////////////////////////////

        return aggStar;
    }

    private final RolapStar star;
    private final AggStar.FactTable aggTable;
    private final BitKey bitKey;
    private final AggStar.Table.Column[] columns;

    AggStar(final RolapStar star, final JdbcSchema.Table aggTable) {
        this.star = star;
        this.bitKey = BitKey.Factory.makeBitKey(star.getColumnCount());
        this.aggTable = new AggStar.FactTable(aggTable);
        this.columns = new AggStar.Table.Column[star.getColumnCount()];
    }

    public AggStar.FactTable getFactTable() {
        return aggTable;
    }

    /**
     * Returns a measure of the IO cost of querying this table. It can be
     * either the row count or the row count times the size of a row.
     * If the property {@link MondrianProperties#ChooseAggregateByVolume}
     * is true, then volume is returned, otherwise row count.
     */
    public int getSize() {
        return MondrianProperties.instance().ChooseAggregateByVolume.get() ?
                getFactTable().getVolume() :
                getFactTable().getNumberOfRows();
    }

    /**
     * Returns true if every bit set to 1 in the bitKey parameter is also
     * set to 1 in this AggStar's bitKey.
     *
     * @param bitKey
     * @param exact If true, bits must match exactly; if false, AggStar's
     *   bitKey can be a superset
     * @return
     */
    public boolean matches(final BitKey bitKey, boolean exact) {
        return exact ?
                getBitKey().equals(bitKey) :
                getBitKey().isSuperSetOf(bitKey);
    }

    /**
     * Get this AggStar's RolapStar.
     *
     * @return
     */
    public RolapStar getStar() {
        return star;
    }

    /**
     * Get the BitKey.
     *
     * @return
     */
    public BitKey getBitKey() {
        return bitKey;
    }

    /**
     * Get an SqlQuery instance.
     *
     * @return
     */
    private SqlQuery getSqlQuery() {
        return getStar().getSqlQuery();
    }

    /**
     * Get a java.sql.Connection.
     *
     * @return
     */
    public Connection getJdbcConnection() {
        return getStar().getJdbcConnection();
    }

    /**
     * Get the Measure at the given bit position or return null.
     * Note that there is no check that the bit position is within the range of
     * the array of columns.
     * Nor is there a check that the column type at that position is a Measure.
     *
     * @param bitPos
     * @return A Measure or null.
     */
    public AggStar.FactTable.Measure lookupMeasure(final int bitPos) {
        AggStar.Table.Column column = lookupColumn(bitPos);
        return (column instanceof AggStar.FactTable.Measure)
            ?  (AggStar.FactTable.Measure) column
            : null;
    }
    /**
     * Get the Level at the given bit position or return null.
     * Note that there is no check that the bit position is within the range of
     * the array of columns.
     * Nor is there a check that the column type at that position is a Level.
     *
     * @param bitPos
     * @return A Level or null.
     */
    public AggStar.Table.Level lookupLevel(final int bitPos) {
        AggStar.Table.Column column = lookupColumn(bitPos);
        return (column instanceof AggStar.FactTable.Level)
            ?  (AggStar.FactTable.Level) column
            : null;
    }

    /**
     * Get the Column at the bit position.
     * Note that there is no check that the bit position is within the range of
     * the array of columns.
     *
     * @param bitPos
     * @return
     */
    public AggStar.Table.Column lookupColumn(final int bitPos) {
        return columns[bitPos];
    }

    /**
     * This is called by within the Column constructor.
     *
     * @param column
     */
    private void addColumn(final AggStar.Table.Column column) {
        columns[column.getBitPosition()] = column;
    }

    /**
     * Base Table class for the FactTable and DimTable classes.
     * This class parallels the RolapStar.Table class.
     *
     */
    public abstract class Table {

        /**
         * The query join condition between a base table and this table (the
         * table that owns the join condition).
         */
        public class JoinCondition {
        	private final Logger LOGGER = Logger.getLogger(JoinCondition.class);
            // I think this is always a MondrianDef.Column
            private final MondrianDef.Expression left;
            private final MondrianDef.Expression right;

            private JoinCondition(final MondrianDef.Expression left,
                                  final MondrianDef.Expression right) {
                if (!(left instanceof MondrianDef.Column)) {
                    LOGGER.debug("JoinCondition.left NOT Column: "
                        +left.getClass().getName());
                }
                this.left = left;
                this.right = right;
            }

            /**
             * Get the enclosing AggStar.Table.
             *
             * @return
             */
            public Table getTable() {
                return AggStar.Table.this;
            }

            /**
             * This is used to create part of a SQL where clause.
             *
             * @param query
             * @return
             */
            String toString(final SqlQuery query) {
                StringBuffer buf = new StringBuffer(64);
                buf.append(left.getExpression(query));
                buf.append(" = ");
                buf.append(right.getExpression(query));
                return buf.toString();
            }
            public String toString() {
                StringWriter sw = new StringWriter(128);
                PrintWriter pw = new PrintWriter(sw);
                print(pw, "");
                pw.flush();
                return sw.toString();
            }

            /**
             * Prints this table and its children.
             */
            public void print(final PrintWriter pw, final String prefix) {
                SqlQuery sqlQueuy = getTable().getSqlQuery();
                pw.print(prefix);
                pw.println("JoinCondition:");
                String subprefix = prefix + "  ";

                pw.print(subprefix);
                pw.print("left=");
                pw.println(left.getExpression(sqlQueuy));

                pw.print(subprefix);
                pw.print("right=");
                pw.println(right.getExpression(sqlQueuy));
            }
        }


        /**
         * Base class for Level and Measure classes
         */
        public class Column {

            private final String name;
            private final MondrianDef.Expression expression;
            private final boolean isNumeric;
            /**
             * This is only used in RolapAggregationManager and adds
             * non-constraining columns making the drill-through queries
             * easier for humans to understand.
             */
            private final Column nameColumn;

            /** this has a unique value per star */
            private final int bitPosition;

            protected Column(final String name,
                             final MondrianDef.Expression expression,
                             final boolean isNumeric,
                             final int bitPosition) {
                this.name = name;
                this.expression = expression;
                this.isNumeric = isNumeric;
                this.bitPosition = bitPosition;

                this.nameColumn = null;

                // do not count the fact_count column
                if (bitPosition >= 0) {
                    AggStar.this.bitKey.setByPos(bitPosition);
                    AggStar.this.addColumn(this);
                }
            }

            /**
             * Get the name of the column (this is the name in the database).
             *
             * @return
             */
            public String getName() {

⌨️ 快捷键说明

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