From f7363a7eb91f74e5bb4d2729ade64a6c7a6268a9 Mon Sep 17 00:00:00 2001 From: Luc Boudreau Date: Mon, 20 Jul 2009 17:47:11 +0000 Subject: [PATCH] In the XMLA driver, Dimensions are inserted according to their correct ordinal value, as specified by DIMENSION_ORDINAL. Also added a test for that. Fixes https://sourceforge.net/tracker/?func=detail&aid=2823612&group_id=168953&atid=848534 git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@270 c6a108a4-781c-0410-a6c6-c2d559e19af0 --- .../driver/xmla/DeferredNamedListImpl.java | 6 ----- .../driver/xmla/XmlaOlap4jConnection.java | 25 +++++++++++++++++-- .../driver/xmla/XmlaOlap4jDimension.java | 9 ++++++- testsrc/org/olap4j/ConnectionTest.java | 25 +++++++++++++++++++ 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/org/olap4j/driver/xmla/DeferredNamedListImpl.java b/src/org/olap4j/driver/xmla/DeferredNamedListImpl.java index e9fa1c7..ed836e5 100644 --- a/src/org/olap4j/driver/xmla/DeferredNamedListImpl.java +++ b/src/org/olap4j/driver/xmla/DeferredNamedListImpl.java @@ -24,12 +24,6 @@ * collections loaded immediately, loading the catalog would immediately load * all sub-objects into memory, taking a lot of memory and time. * - *

(The above description is only intended to be illustrative. The XMLA - * driver schema does not use deferred lists at every level; in particular, - * it loads each cube in one swoop, fetching all dimensions, hierarchies and - * levels of that cube, in order to reduce the number of metadata requests - * submitted.)

- * *

This class is not gc-friendly at present. Once populated, * DeferredNamedListImpl holds hard references * to the objects it contains, so they are not available to be diff --git a/src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java b/src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java index 95c4197..f093fb9 100644 --- a/src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java +++ b/src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java @@ -930,11 +930,32 @@ public void handle( Dimension.Type.forXmlaOrdinal(dimensionType); final String defaultHierarchyUniqueName = stringElement(row, "DEFAULT_HIERARCHY"); + final Integer dimensionOrdinal = + integerElement(row, "DIMENSION_ORDINAL"); XmlaOlap4jDimension dimension = new XmlaOlap4jDimension( context.olap4jCube, dimensionUniqueName, dimensionName, dimensionCaption, description, type, - defaultHierarchyUniqueName); - list.add(dimension); + defaultHierarchyUniqueName, + dimensionOrdinal == null ? 0 : dimensionOrdinal); + list.add(dimension); + if (dimensionOrdinal != null) { + Collections.sort( + list, + new Comparator () { + public int compare( + XmlaOlap4jDimension d1, + XmlaOlap4jDimension d2) + { + if (d1.getOrdinal() == d2.getOrdinal()) { + return 0; + } else if (d1.getOrdinal() > d2.getOrdinal()) { + return 1; + } else { + return -1; + } + } + }); + } this.cubeForCallback.dimensionsByUname.put( dimension.getUniqueName(), dimension); diff --git a/src/org/olap4j/driver/xmla/XmlaOlap4jDimension.java b/src/org/olap4j/driver/xmla/XmlaOlap4jDimension.java index aa6791e..1381973 100644 --- a/src/org/olap4j/driver/xmla/XmlaOlap4jDimension.java +++ b/src/org/olap4j/driver/xmla/XmlaOlap4jDimension.java @@ -28,6 +28,7 @@ class XmlaOlap4jDimension final Type type; final NamedList hierarchies; private final String defaultHierarchyUniqueName; + private final int ordinal; XmlaOlap4jDimension( XmlaOlap4jCube olap4jCube, @@ -36,13 +37,15 @@ class XmlaOlap4jDimension String caption, String description, Type type, - String defaultHierarchyUniqueName) + String defaultHierarchyUniqueName, + int ordinal) { super(uniqueName, name, caption, description); this.defaultHierarchyUniqueName = defaultHierarchyUniqueName; assert olap4jCube != null; this.olap4jCube = olap4jCube; this.type = type; + this.ordinal = ordinal; String[] dimensionRestrictions = { "CATALOG_NAME", @@ -91,6 +94,10 @@ public boolean equals(Object obj) { && this.uniqueName.equals( ((XmlaOlap4jDimension) obj).getUniqueName()); } + + public int getOrdinal() { + return ordinal; + } } // End XmlaOlap4jDimension.java diff --git a/testsrc/org/olap4j/ConnectionTest.java b/testsrc/org/olap4j/ConnectionTest.java index d8463a6..ba78698 100644 --- a/testsrc/org/olap4j/ConnectionTest.java +++ b/testsrc/org/olap4j/ConnectionTest.java @@ -2487,6 +2487,31 @@ public void testBuildQuery2() throws ClassNotFoundException, SQLException { + "ROW:[TV] COL:[Unit Sales] CELL:3,607\n", sw.toString()); } + + /** + * Verifies the order of dimensions; they must conform to their + * ordinal value. + * @throws Exception If something turns sour. + */ + public void testCubeDimensionsOrder() throws Exception { + String dimNames = "[Measures];[Store];[Store Size in SQFT];" + + "[Store Type];[Time];[Product];[Promotion Media];[Promotions];" + + "[Customers];[Education Level];[Gender];[Marital Status];" + + "[Yearly Income];"; + Class.forName(tester.getDriverClassName()); + connection = tester.createConnection(); + OlapConnection olapConnection = + tester.getWrapper().unwrap(connection, OlapConnection.class); + Cube cube = olapConnection.getSchema().getCubes().get("Sales"); + StringBuilder sb = new StringBuilder(); + for (Dimension dimension : cube.getDimensions()) { + sb.append(dimension.getUniqueName()) + .append(";"); + } + TestContext.assertEqualsVerbose( + dimNames, + sb.toString()); + } } // End ConnectionTest.java