/*
// $Id: //open/mondrian-release/3.2/src/main/mondrian/rolap/agg/DrillThroughQuerySpec.java#2 $
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2005-2009 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package mondrian.rolap.agg;
import mondrian.olap.Util;
import mondrian.olap.MondrianDef;
import mondrian.rolap.RolapStar;
import mondrian.rolap.StarColumnPredicate;
import mondrian.rolap.sql.SqlQuery;
import java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
/**
* Provides the information necessary to generate SQL for a drill-through
* request.
*
* @author jhyde
* @author Richard M. Emberson
* @version $Id: //open/mondrian-release/3.2/src/main/mondrian/rolap/agg/DrillThroughQuerySpec.java#2 $
*/
class DrillThroughQuerySpec extends AbstractQuerySpec {
private final CellRequest request;
private final List<String> columnNames;
private final int maxColumnNameLength;
public DrillThroughQuerySpec(CellRequest request, boolean countOnly) {
super(request.getMeasure().getStar(), countOnly);
this.request = request;
int tmpMaxColumnNameLength =
getStar().getSqlQueryDialect().getMaxColumnNameLength();
if (tmpMaxColumnNameLength == 0) {
// From java.sql.DatabaseMetaData: "a result of zero means that
// there is no limit or the limit is not known"
maxColumnNameLength = Integer.MAX_VALUE;
} else {
maxColumnNameLength = tmpMaxColumnNameLength;
}
this.columnNames = computeDistinctColumnNames();
}
private List<String> computeDistinctColumnNames() {
final List<String> columnNames = new ArrayList<String>();
final Set<String> columnNameSet = new HashSet<String>();
final RolapStar.Column[] columns = getColumns();
for (RolapStar.Column column : columns) {
addColumnName(column, columnNames, columnNameSet);
}
addColumnName(request.getMeasure(), columnNames, columnNameSet);
return columnNames;
}
private void addColumnName(
final RolapStar.Column column,
final List<String> columnNames,
final Set<String> columnNameSet)
{
String columnName = column.getName();
if (columnName != null) {
// nothing
} else if (column.getExpression() instanceof MondrianDef.Column) {
columnName = ((MondrianDef.Column) column.getExpression()).name;
} else {
columnName = "c" + Integer.toString(columnNames.size());
}
// Register the column name, and if it's not unique, append numeric
// suffixes until it is. Also make sure that it is within the
// range allowed by this SQL dialect.
String originalColumnName = columnName;
if (columnName.length() > maxColumnNameLength) {
columnName = columnName.substring(0, maxColumnNameLength);
}
for (int j = 0; !columnNameSet.add(columnName); j++) {
final String suffix = "_" + Integer.toString(j);
columnName = originalColumnName;
if (originalColumnName.length() + suffix.length()
> maxColumnNameLength)
{
columnName =
originalColumnName.substring(
0, maxColumnNameLength - suffix.length());
}
columnName += suffix;
}
columnNames.add(columnName);
}
public int getMeasureCount() {
return 1;
}
public RolapStar.Measure getMeasure(final int i) {
Util.assertTrue(i == 0);
return request.getMeasure();
}
public String getMeasureAlias(final int i) {
Util.assertTrue(i == 0);
return columnNames.get(columnNames.size() - 1);
}
public RolapStar.Column[] getColumns() {
return request.getConstrainedColumns();
}
public String getColumnAlias(final int i) {
return columnNames.get(i);
}
public StarColumnPredicate getColumnPredicate(final int i) {
final StarColumnPredicate constr = request.getValueList().get(i);
return (constr == null)
? LiteralStarPredicate.TRUE
: constr;
}
public String generateSqlQuery() {
SqlQuery sqlQuery = newSqlQuery();
nonDistinctGenerateSql(sqlQuery);
return sqlQuery.toString();
}
protected void addMeasure(final int i, final SqlQuery sqlQuery) {
RolapStar.Measure measure = getMeasure(i);
Util.assertTrue(measure.getTable() == getStar().getFactTable());
measure.getTable().addToFrom(sqlQuery, false, true);
if (!countOnly) {
String expr = measure.generateExprString(sqlQuery);
sqlQuery.addSelect(expr, getMeasureAlias(i));
}
}
protected boolean isAggregate() {
return false;
}
protected boolean isOrdered() {
return true;
}
}
// End DrillThroughQuerySpec.java