Skip to content

Commit

Permalink
Add head, tail, and skip_dimension_properties args
Browse files Browse the repository at this point in the history
to to_mdx function
  • Loading branch information
MariusWirtz committed Apr 6, 2023
1 parent 50c350f commit d7f6a90
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 13 deletions.
49 changes: 38 additions & 11 deletions mdxpy/mdx.py
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ class HierarchizeSet(MdxHierarchySet):

def __init__(self, underlying_hierarchy_set: MdxHierarchySet):
super(HierarchizeSet, self).__init__(underlying_hierarchy_set.dimension,
underlying_hierarchy_set.hierarchy)
underlying_hierarchy_set.hierarchy)
self.underlying_hierarchy_set = underlying_hierarchy_set

def to_mdx(self) -> str:
Expand Down Expand Up @@ -1075,17 +1075,29 @@ def is_empty(self) -> bool:
def set_non_empty(self, non_empty: bool = True):
self.non_empty = non_empty

def to_mdx(self, tm1_ignore_bad_tuples=False) -> str:
def to_mdx(self, tm1_ignore_bad_tuples: bool = False, head: int = None, tail: int = None) -> str:
if self.is_empty():
return "{}"

return f"""{"NON EMPTY " if self.non_empty else ""}{"TM1IGNORE_BADTUPLES " if tm1_ignore_bad_tuples else ""}{self.dim_sets_to_mdx() if self.dim_sets else self.tuples_to_mdx()}"""
return f"""{"NON EMPTY " if self.non_empty else ""}{"TM1IGNORE_BADTUPLES " if tm1_ignore_bad_tuples else ""}{self.dim_sets_to_mdx(head, tail) if self.dim_sets else self.tuples_to_mdx(head, tail)}"""

def dim_sets_to_mdx(self) -> str:
return " * ".join(dim_set.to_mdx() for dim_set in self.dim_sets)
def dim_sets_to_mdx(self, head: int = None, tail: int = None) -> str:
mdx = " * ".join(dim_set.to_mdx() for dim_set in self.dim_sets)
if head is not None:
mdx = f"{{HEAD({mdx}, {head})}}"
if tail is not None:
mdx = f"{{TAIL({mdx}, {tail})}}"

def tuples_to_mdx(self) -> str:
return f"{{{','.join(tupl.to_mdx() for tupl in self.tuples)}}}"
return mdx

def tuples_to_mdx(self, head: int = None, tail: int = None) -> str:
mdx = f"{{{','.join(tupl.to_mdx() for tupl in self.tuples)}}}"
if head is not None:
mdx = f"{{HEAD({mdx}, {head})}}"
if tail is not None:
mdx = f"{{TAIL({mdx}, {tail})}}"

return mdx


class MdxBuilder:
Expand Down Expand Up @@ -1209,27 +1221,42 @@ def add_properties(self, axis: int, *args: Union[str, DimensionProperty]) -> 'Md

return self

def _axis_mdx(self, position):
def _axis_mdx(self, position: int, head: int = None, tail: int = None, skip_dimension_properties=False):
axis = self.axes[position]
axis_properties = self.axes_properties.get(position, MdxPropertiesTuple.empty())
if axis.is_empty():
return ""

if skip_dimension_properties:
return " ".join([
axis.to_mdx(self._tm1_ignore_bad_tuples, head, tail),
f"ON {position}"
])

return " ".join([
axis.to_mdx(self._tm1_ignore_bad_tuples),
axis.to_mdx(self._tm1_ignore_bad_tuples, head, tail),
"DIMENSION PROPERTIES",
"MEMBER_NAME" if axis_properties.is_empty() else axis_properties.to_mdx(),
f"ON {position}"
])

def to_mdx(self) -> str:
def to_mdx(self, head_columns: int = None, head_rows: int = None, tail_columns: int = None, tail_rows: int = None,
skip_dimension_properties: bool = False) -> str:
mdx_with = "WITH\r\n" + "\r\n".join(
calculated_member.to_mdx()
for calculated_member
in self.calculated_members) + "\r\n"

head_by_axis_position = {0: head_columns, 1: head_rows}
tail_by_axis_position = {0: tail_columns, 1: tail_rows}

mdx_axes = ",\r\n".join(
self._axis_mdx(position)
self._axis_mdx(
position,
# default for head, tail is False for axes beyond rows and columns
head=head_by_axis_position.get(position, False),
tail=tail_by_axis_position.get(position, False),
skip_dimension_properties=skip_dimension_properties)
for position
in self.axes)

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

setup(
name="mdxpy",
version='1.2',
version='1.3',
maintainer='Marius Wirtz',
maintainer_email='[email protected]',
license="MIT-LICENSE",
Expand Down
55 changes: 54 additions & 1 deletion test.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ def test_mdx_set_cross_joins(self):
" * {[dimension].[dimension].[element3]}}",
mdx_set.to_mdx())


def test_mdx_set_tuples(self):
mdx_set = MdxSet.tuples([
MdxTuple([Member.of("dimension1", "element1"), Member.of("dimension2", "element3")]),
Expand Down Expand Up @@ -843,6 +844,58 @@ def test_mdx_build_with_multi_calculated_member(self):
"WHERE ([dim2].[dim2].[totaldim2])",
mdx)

def test_mdx_builder_to_mdx_skip_dimension_properties(self):
mdx = MdxBuilder.from_cube("cube") \
.rows_non_empty() \
.add_hierarchy_set_to_row_axis(MdxHierarchySet.all_leaves("Dim1")) \
.columns_non_empty() \
.add_hierarchy_set_to_column_axis(MdxHierarchySet.member(Member.of("Dim2", "Elem2"))) \
.where(Member.of("Dim3", "Elem3"), Member.of("Dim4", "Elem4")) \
.to_mdx(skip_dimension_properties=True)

self.assertEqual(
"SELECT\r\n"
"NON EMPTY {[dim2].[dim2].[elem2]} ON 0,\r\n"
"NON EMPTY {TM1FILTERBYLEVEL({TM1SUBSETALL([dim1].[dim1])},0)} ON 1\r\n"
"FROM [cube]\r\n"
"WHERE ([dim3].[dim3].[elem3],[dim4].[dim4].[elem4])",
mdx)

def test_mdx_builder_to_mdx_head_tail_columns(self):
mdx = MdxBuilder.from_cube("cube") \
.add_hierarchy_set_to_column_axis(MdxHierarchySet.all_leaves("Dim1")) \
.columns_non_empty() \
.add_hierarchy_set_to_column_axis(MdxHierarchySet.member(Member.of("Dim2", "Elem2"))) \
.where(Member.of("Dim3", "Elem3"), Member.of("Dim4", "Elem4")) \
.to_mdx(head_columns=2, tail_columns=1)

self.assertEqual(
"SELECT\r\n"
"NON EMPTY {TAIL({HEAD({TM1FILTERBYLEVEL({TM1SUBSETALL([dim1].[dim1])},0)} * {[dim2].[dim2].[elem2]}, 2)}, 1)} "
"DIMENSION PROPERTIES MEMBER_NAME ON 0\r\n"
"FROM [cube]\r\n"
"WHERE ([dim3].[dim3].[elem3],[dim4].[dim4].[elem4])",
mdx)

def test_mdx_builder_to_mdx_head_tail_rows_and_columns(self):
mdx = MdxBuilder.from_cube("cube") \
.add_hierarchy_set_to_column_axis(MdxHierarchySet.all_leaves("Dim1")) \
.columns_non_empty() \
.add_hierarchy_set_to_row_axis(MdxHierarchySet.all_leaves("Dim2")) \
.rows_non_empty() \
.where(Member.of("Dim3", "Elem3"), Member.of("Dim4", "Elem4")) \
.to_mdx(head_columns=4, tail_columns=2, head_rows=2, tail_rows=1)

self.assertEqual(
"SELECT\r\n"
"NON EMPTY {TAIL({HEAD({TM1FILTERBYLEVEL({TM1SUBSETALL([dim1].[dim1])},0)}, 4)}, 2)} "
"DIMENSION PROPERTIES MEMBER_NAME ON 0,\r\n"
"NON EMPTY {TAIL({HEAD({TM1FILTERBYLEVEL({TM1SUBSETALL([dim2].[dim2])},0)}, 2)}, 1)} "
"DIMENSION PROPERTIES MEMBER_NAME ON 1\r\n"
"FROM [cube]\r\n"
"WHERE ([dim3].[dim3].[elem3],[dim4].[dim4].[elem4])",
mdx)

def test_OrderType_ASC(self):
order = Order("asc")
self.assertEqual(order, Order.ASC)
Expand Down Expand Up @@ -953,4 +1006,4 @@ def test_level_expression_name(self):

def test_level_expression_member_level(self):
level = MdxLevelExpression.member_level(Member.of("Dimension1", "Hierarchy1", "Element1"))
self.assertEqual("[dimension1].[hierarchy1].[element1].LEVEL", level.to_mdx())
self.assertEqual("[dimension1].[hierarchy1].[element1].LEVEL", level.to_mdx())

0 comments on commit d7f6a90

Please sign in to comment.