From de77341088e19ce482eabe804a15a39914ec8b34 Mon Sep 17 00:00:00 2001 From: Luc Boudreau Date: Mon, 25 May 2009 17:30:13 +0000 Subject: [PATCH] Added two methods to move a dimension along an axis. Created test cases. Fixed issue where calling set() on the QueryAxis's dimensions was loosing one object of the collection due to an overwrite. git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@244 c6a108a4-781c-0410-a6c6-c2d559e19af0 --- src/org/olap4j/query/QueryAxis.java | 37 ++++++++++- testsrc/org/olap4j/OlapTest.java | 95 +++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 2 deletions(-) diff --git a/src/org/olap4j/query/QueryAxis.java b/src/org/olap4j/query/QueryAxis.java index cc888ef..d85c5a3 100644 --- a/src/org/olap4j/query/QueryAxis.java +++ b/src/org/olap4j/query/QueryAxis.java @@ -12,6 +12,7 @@ import org.olap4j.Axis; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.AbstractList; @@ -79,6 +80,34 @@ public String getName() { return location.getCaption(query.getLocale()); } + /** + * Places a QueryDimension object one position before in the + * list of current dimensions. Uses a 0 based index. + * For example, to place the 5th dimension on the current axis + * one position before, one would need to call pullUp(4), + * so the dimension would then use axis index 4 and the previous + * dimension at that position gets pushed down one position. + * @param index The index of the dimension to move up one notch. + * It uses a zero based index. + */ + public void pullUp(int index) { + Collections.swap(this.dimensions, index, index - 1); + } + + /** + * Places a QueryDimension object one position lower in the + * list of current dimensions. Uses a 0 based index. + * For example, to place the 4th dimension on the current axis + * one position lower, one would need to call pushDown(3), + * so the dimension would then use axis index 4 and the previous + * dimension at that position gets pulled up one position. + * @param index The index of the dimension to move down one notch. + * It uses a zero based index. + */ + public void pushDown(int index) { + Collections.swap(this.dimensions, index, index + 1); + } + /** * Returns whether this QueryAxis filters out empty rows. * If true, axis filters out empty rows, and the MDX to evaluate the axis @@ -120,7 +149,9 @@ public int size() { } public QueryDimension set(int index, QueryDimension dimension) { - if (dimension.getAxis() != null) { + if (dimension.getAxis() != null && + dimension.getAxis() != QueryAxis.this) + { dimension.getAxis().getDimensions().remove(dimension); } dimension.setAxis(QueryAxis.this); @@ -131,7 +162,9 @@ public void add(int index, QueryDimension dimension) { if (this.contains(dimension)) { throw new IllegalStateException("dimension already on this axis"); } - if (dimension.getAxis() != null) { + if (dimension.getAxis() != null && + dimension.getAxis() != QueryAxis.this) + { // careful! potential for loop dimension.getAxis().getDimensions().remove(dimension); } diff --git a/testsrc/org/olap4j/OlapTest.java b/testsrc/org/olap4j/OlapTest.java index e5e9aaf..f4c2a0d 100644 --- a/testsrc/org/olap4j/OlapTest.java +++ b/testsrc/org/olap4j/OlapTest.java @@ -633,6 +633,101 @@ public void testSortDimension() { } + public void testDimensionsOrder() { + try { + Cube cube = getFoodmartCube("Sales"); + if (cube == null) { + fail("Could not find Sales cube"); + } + Query query = new Query("my query", cube); + + // create selections + + QueryDimension productDimension = query.getDimension("Product"); + Member drinkMember = cube.lookupMember("Product", "Drink"); + Selection drinkSelection = + productDimension.createSelection(drinkMember, + Selection.Operator.CHILDREN); + productDimension.getSelections().add(drinkSelection); + + QueryDimension storeDimension = query.getDimension("Store"); + Member usaMember = cube.lookupMember("Store", "USA"); + Selection usaSelection = + storeDimension.createSelection(usaMember, + Selection.Operator.INCLUDE_CHILDREN); + storeDimension.getSelections().add(usaSelection); + + QueryDimension timeDimension = query.getDimension("Time"); + Member year1997Member = cube.lookupMember("Time", "1997"); + Selection year1997Selection = + timeDimension.createSelection(year1997Member, + Selection.Operator.CHILDREN); + timeDimension.getSelections().add(year1997Selection); + + QueryDimension measuresDimension = query.getDimension("Measures"); + Member storeSalesMember = cube.lookupMember("Measures", "Store Sales"); + Selection storeSalesSelection = + measuresDimension.createSelection(storeSalesMember, + Selection.Operator.MEMBER); + measuresDimension.getSelections().add(storeSalesSelection); + + query.getAxes().get(Axis.ROWS).getDimensions().add(productDimension); + query.getAxes().get(Axis.ROWS).getDimensions().add(storeDimension); + query.getAxes().get(Axis.ROWS).getDimensions().add(timeDimension); + query.getAxes().get(Axis.COLUMNS).getDimensions().add(measuresDimension); + + query.validate(); + + SelectNode mdx = query.getSelect(); + String mdxString = mdx.toString(); + assertEquals( + mdxString, + TestContext.fold("SELECT\n" + + "{[Measures].[Store Sales]} ON COLUMNS,\n" + + "CrossJoin({[Product].[All Products].[Drink].Children}, " + + "CrossJoin({{[Store].[All Stores].[USA], " + + "[Store].[All Stores].[USA].Children}}, " + + "{[Time].[1997].Children})) ON ROWS\n" + + "FROM [Sales]")); + + // Push down the Products dimension. + query.getAxes().get(Axis.ROWS).pushDown(0); + + query.validate(); + + mdx = query.getSelect(); + mdxString = mdx.toString(); + assertEquals( + mdxString, + TestContext.fold("SELECT\n" + + "{[Measures].[Store Sales]} ON COLUMNS,\n" + + "CrossJoin({{[Store].[All Stores].[USA], " + + "[Store].[All Stores].[USA].Children}}, " + + "CrossJoin({[Product].[All Products].[Drink].Children}, " + + "{[Time].[1997].Children})) ON ROWS\n" + + "FROM [Sales]")); + + // Pull Up the Time dimension. + query.getAxes().get(Axis.ROWS).pullUp(2); + + query.validate(); + + mdx = query.getSelect(); + mdxString = mdx.toString(); + assertEquals( + mdxString, + TestContext.fold("SELECT\n" + + "{[Measures].[Store Sales]} ON COLUMNS,\n" + + "CrossJoin({{[Store].[All Stores].[USA], " + + "[Store].[All Stores].[USA].Children}}, " + + "CrossJoin({[Time].[1997].Children}, " + + "{[Product].[All Products].[Drink].Children})) ON ROWS\n" + + "FROM [Sales]")); + } catch (Exception e) { + e.printStackTrace(); + fail(); + } + } public static void listHierarchies(Dimension dimension) {