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 + -
显示快捷键?