Skip to content

Commit

Permalink
Specify thread-safety, timeout, statement cancel; Specify compliance …
Browse files Browse the repository at this point in the history
…levels; Specify access control; Specify internationalization; add OlapConnection.get/setLocale. Add diagram of object model to spec; Ensure that every public class and method has a full javadoc description. Implement timeout and cancel in mondrian driver; and test. Implement drill-through in mondrian driver; and test. Make CellSetAxis implement Iterable<Position>. Remove some unneeded methods from org.olap4j.type package. Rename SLICER to FILTER.

git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@40 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
julianhyde committed Nov 18, 2007
1 parent ad23a24 commit d65a89e
Show file tree
Hide file tree
Showing 56 changed files with 1,476 additions and 442 deletions.
Binary file modified doc/olap4j-arch.vsd
Binary file not shown.
Binary file added doc/olap4j-metadata.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
354 changes: 230 additions & 124 deletions doc/olap4j_fs.html

Large diffs are not rendered by default.

7 changes: 0 additions & 7 deletions doc/tasks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,15 @@ Remember that other people may be editing this file, so avoid non-mergeable edit
Specification
-------------

* D.1 add discussion of thread-safety
* D.1 add discussion of api for cancelling statements
* D.1 add discussion of compliance levels
* D.1 describe how members of axis can be accessed via iterator or list, with code examples
* 2.1.5 internationalization: move section elsewhere; what is the behavior of locale? does it belong to connection? fix and test Query.getLocale(). document that all methods which return localized strings take a locale parameter; that parameter may be null, in which case the connection's locale is used
* 2.7.2 diagram of object model
* 2.8 query model - barry and/or james complete?
* 2.9 layout - remove from spec?
* add mdx parser and mdx parse tree model to specification
* discuss access-control (each provider can have their own rules. can set access-control on the connection. metadata methods should be consistent with that.)

Javadoc
-------

* remove class OlapTest
* ensure that every public method has a javadoc description, including @param, @return and @throws declarations

Code
----
Expand Down
3 changes: 2 additions & 1 deletion src/mondrian/olap4j/Factory.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package mondrian.olap4j;

import mondrian.olap.Result;
import mondrian.olap.Query;

import java.util.Properties;
import java.util.List;
Expand Down Expand Up @@ -39,7 +40,7 @@ ResultSet newFixedResultSet(

MondrianOlap4jCellSet newCellSet(
MondrianOlap4jStatement olap4jStatement,
Result result);
Query query);

MondrianOlap4jPreparedStatement newPreparedStatement(
String mdx, MondrianOlap4jConnection olap4jConnection);
Expand Down
11 changes: 5 additions & 6 deletions src/mondrian/olap4j/FactoryJdbc3Impl.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
package mondrian.olap4j;

import mondrian.olap.Result;
import mondrian.olap.Query;

import java.sql.*;
import java.util.*;
Expand Down Expand Up @@ -50,9 +50,9 @@ public ResultSet newFixedResultSet(

public MondrianOlap4jCellSet newCellSet(
MondrianOlap4jStatement olap4jStatement,
Result result)
Query query)
{
return new MondrianOlap4jCellSetJdbc3(olap4jStatement, result);
return new MondrianOlap4jCellSetJdbc3(olap4jStatement, query);
}

public MondrianOlap4jPreparedStatement newPreparedStatement(
Expand Down Expand Up @@ -84,10 +84,9 @@ private static class MondrianOlap4jCellSetJdbc3
extends MondrianOlap4jCellSet
{
public MondrianOlap4jCellSetJdbc3(
MondrianOlap4jStatement olap4jStatement,
Result result)
MondrianOlap4jStatement olap4jStatement, Query query)
{
super(olap4jStatement, result);
super(olap4jStatement);
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/mondrian/olap4j/FactoryJdbc4Impl.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.io.InputStream;

import mondrian.olap.Result;
import mondrian.olap.Query;

/**
* Implementation of {@link Factory} for JDBC 4.0.
Expand Down Expand Up @@ -54,9 +55,9 @@ public ResultSet newFixedResultSet(

public MondrianOlap4jCellSet newCellSet(
MondrianOlap4jStatement olap4jStatement,
Result result)
Query query)
{
return new MondrianOlap4jCellSetJdbc4(olap4jStatement, result);
return new MondrianOlap4jCellSetJdbc4(olap4jStatement, query);
}

public MondrianOlap4jPreparedStatement newPreparedStatement(
Expand Down Expand Up @@ -381,9 +382,9 @@ public Struct createStruct(
private static class MondrianOlap4jCellSetJdbc4 extends MondrianOlap4jCellSet {
public MondrianOlap4jCellSetJdbc4(
MondrianOlap4jStatement olap4jStatement,
Result result)
Query query)
{
super(olap4jStatement, result);
super(olap4jStatement, query);
}

// implement java.sql.CellSet methods
Expand Down
29 changes: 24 additions & 5 deletions src/mondrian/olap4j/MondrianOlap4jCell.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
import org.olap4j.OlapException;
import org.olap4j.metadata.Property;

import javax.sql.DataSource;
import java.util.List;
import java.util.ArrayList;
import java.sql.ResultSet;
import java.sql.*;

/**
* Implementation of {@link Cell}
Expand Down Expand Up @@ -55,8 +56,8 @@ public int getOrdinal() {

public List<Integer> getCoordinateList() {
ArrayList<Integer> list = new ArrayList<Integer>(coordinates.length);
for (int i = 0; i < coordinates.length; i++) {
list.add(coordinates[i]);
for (int coordinate : coordinates) {
list.add(coordinate);
}
return list;
}
Expand Down Expand Up @@ -107,8 +108,26 @@ public String getFormattedValue() {
return cell.getFormattedValue();
}

public ResultSet drillThrough() {
throw new UnsupportedOperationException();
public ResultSet drillThrough() throws OlapException {
// REVIEW: This method returns a ResultSet without closing the
// Statement or the Connection. If we closed them, the ResultSet would
// be useless. But as it stands, we have a connection leak. Should we
// tell the client that they need to close the result set's connection?
if (!cell.canDrillThrough()) {
return null;
}
final String sql = cell.getDrillThroughSQL(false);
final MondrianOlap4jConnection olap4jConnection =
this.olap4jCellSet.olap4jStatement.olap4jConnection;
final DataSource dataSource =
olap4jConnection.connection.getDataSource();
try {
final Connection connection = dataSource.getConnection();
final Statement statement = connection.createStatement();
return statement.executeQuery(sql);
} catch (SQLException e) {
throw olap4jConnection.helper.toOlapException(e);
}
}
}

Expand Down
118 changes: 98 additions & 20 deletions src/mondrian/olap4j/MondrianOlap4jCellSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import org.olap4j.*;
import org.olap4j.Cell;
import org.olap4j.Position;
import mondrian.olap.*;
import mondrian.olap.Axis;

Expand All @@ -32,60 +33,83 @@
*/
abstract class MondrianOlap4jCellSet implements CellSet {
final MondrianOlap4jStatement olap4jStatement;
private final Result result;
final Query query;
private Result result;
protected boolean closed;
private final MondrianOlap4jCellSetMetaData metaData;
private final List<CellSetAxis> axisList =
new ArrayList<CellSetAxis>();
private CellSetAxis filterAxis;

public MondrianOlap4jCellSet(
MondrianOlap4jStatement olap4jStatement,
Result result)
Query query)
{
assert olap4jStatement != null;
assert result != null;
assert query != null;
this.olap4jStatement = olap4jStatement;
this.result = result;
this.query = query;
this.closed = false;
if (olap4jStatement instanceof MondrianOlap4jPreparedStatement) {
this.metaData =
((MondrianOlap4jPreparedStatement) olap4jStatement).cellSetMetaData;
((MondrianOlap4jPreparedStatement) olap4jStatement)
.cellSetMetaData;
} else {
this.metaData =
new MondrianOlap4jCellSetMetaData(
olap4jStatement, result.getQuery());
olap4jStatement, query);
}
}

public CellSetMetaData getMetaData() throws OlapException {
return metaData;
}
/**
* Executes a query. Not part of the olap4j API; internal to the mondrian
* driver.
*
* <p>This method may take some time. While it is executing, a client may
* execute {@link MondrianOlap4jStatement#cancel()}.
*/
void execute() {
query.setQueryTimeoutMillis(olap4jStatement.timeoutSeconds * 1000);
result = olap4jStatement.olap4jConnection.connection.execute(query);

public List<CellSetAxis> getAxes() {
// initialize axes
mondrian.olap.Axis[] axes = result.getAxes();
QueryAxis[] queryAxes = result.getQuery().getAxes();
assert axes.length == queryAxes.length;
ArrayList<CellSetAxis> list = new ArrayList<CellSetAxis>(axes.length);

for (int i = 0; i < axes.length; i++) {
Axis axis = axes[i];
QueryAxis queryAxis = queryAxes[i];
list.add(new MondrianOlap4jCellSetAxis(this, queryAxis, axis));
axisList.add(new MondrianOlap4jCellSetAxis(this, queryAxis, axis));
}

// initialize filter axis
final QueryAxis queryAxis = result.getQuery().getSlicerAxis();
final Axis axis = result.getSlicerAxis();
if (queryAxis == null) {
filterAxis = null;
} else {
filterAxis = new MondrianOlap4jCellSetAxis(this, queryAxis, axis);
}
return list;
}

public CellSetMetaData getMetaData() {
return metaData;
}

public List<CellSetAxis> getAxes() {
return axisList;
}

public CellSetAxis getFilterAxis() {
final Axis axis = result.getSlicerAxis();
final QueryAxis queryAxis = result.getQuery().getSlicerAxis();
return new MondrianOlap4jCellSetAxis(this, queryAxis, axis);
return filterAxis;
}

public Cell getCell(List<Integer> coordinates) {
int[] coords = new int[coordinates.size()];
for (int i = 0; i < coords.length; i++) {
coords[i] = coordinates.get(i);
}
mondrian.olap.Cell cell = result.getCell(coords);
return new MondrianOlap4jCell(coords, this, cell);
return getCellInternal(coords);
}

public Cell getCell(int ordinal) {
Expand All @@ -97,10 +121,64 @@ public Cell getCell(int ordinal) {
modulo *= axes[i].getPositions().size();
pos[i] = (ordinal % modulo) / prevModulo;
}
mondrian.olap.Cell cell = result.getCell(pos);
if (ordinal < 0 || ordinal >= modulo) {
throw new IndexOutOfBoundsException(
"Cell ordinal " + ordinal
+ ") lies outside CellSet bounds ("
+ getBoundsAsString() + ")");
}
return getCellInternal(pos);
}

public Cell getCell(Position... positions) {
int[] coords = new int[positions.length];
for (int i = 0; i < coords.length; i++) {
coords[i] = positions[i].getOrdinal();
}
return getCellInternal(coords);
}

private Cell getCellInternal(int[] pos) {
mondrian.olap.Cell cell;
try {
cell = result.getCell(pos);
} catch (MondrianException e) {
if (e.getMessage().indexOf("coordinates out of range") >= 0) {
throw new IndexOutOfBoundsException(
"Cell coordinates (" + getCoordsAsString(pos)
+ ") fall outside CellSet bounds ("
+ getCoordsAsString(pos) + ")");
} else {
throw e;
}
}
return new MondrianOlap4jCell(pos, this, cell);
}

private String getBoundsAsString() {
StringBuffer buf = new StringBuffer();
Axis[] axes = result.getAxes();
for (int i = 0; i < axes.length; i++) {
if (i > 0) {
buf.append(", ");
}
buf.append(axes[i].getPositions().size());
}
return buf.toString();
}

private static String getCoordsAsString(int[] pos) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < pos.length; i++) {
int po = pos[i];
if (i > 0) {
buf.append(", ");
}
buf.append(po);
}
return buf.toString();
}

public List<Integer> ordinalToCoordinates(int ordinal) {
throw new UnsupportedOperationException();
}
Expand Down
Loading

0 comments on commit d65a89e

Please sign in to comment.