Daanse Tutorial - Writeback Text Aggregation
Daanse Tutorial — Writeback with text aggregation.
This is the minimal example demonstrating two-kind writeback in one cube:
- a numeric
Amountmeasure backed bySumMeasureover anAMOUNTcolumn, with the usual allocation-policy semantics on write-back; - a text
Commentsmeasure backed byTextAggMeasureover aCOMMENTcolumn. On read it concatenates every matching cell'sCOMMENTvalue using the configured separator; on write the daanse runtime appends a single row to the writeback table with the typed string for the cell's exact coordinates.
The writeback table FACTWB carries one WritebackAttribute for the dimension and two WritebackMeasures — one numeric, one text. The runtime detects the text target from its aggregator type (ListAggAggregator ⇒ Datatype.VARCHAR) and short-circuits the allocation flow for that path, so text values land verbatim instead of being split numerically across descendants.
Database Schema
The database schema contains two tables:
FACT—CATEGORY,AMOUNT,COMMENT. One row per posting.CATEGORY—CATEGORY,NAME. The single dimension table.FACTWB—CATEGORY,AMOUNT,COMMENT,ID,USER. The writeback target.IDis filled by the engine with a UUID,USERwith the session user.
<relational:Schema xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:relational="http://www.omg.org/spec/CWM/1.1/resource/relational" xmi:id="_schema">
<ownedElement xsi:type="relational:Table" xmi:id="_table_fact" name="FACT">
<feature xsi:type="relational:Column" xmi:id="_column_fact_category" name="CATEGORY"/>
<feature xsi:type="relational:Column" xmi:id="_column_fact_amount" name="AMOUNT"/>
<feature xsi:type="relational:Column" xmi:id="_column_fact_comment" name="COMMENT"/>
</ownedElement>
<ownedElement xsi:type="relational:Table" xmi:id="_table_category" name="CATEGORY">
<feature xsi:type="relational:Column" xmi:id="_column_category_category" name="CATEGORY"/>
<feature xsi:type="relational:Column" xmi:id="_column_category_name" name="NAME"/>
</ownedElement>
<ownedElement xsi:type="relational:Table" xmi:id="_table_factwb" name="FACTWB">
<feature xsi:type="relational:Column" xmi:id="_column_factwb_category" name="CATEGORY"/>
<feature xsi:type="relational:Column" xmi:id="_column_factwb_amount" name="AMOUNT"/>
<feature xsi:type="relational:Column" xmi:id="_column_factwb_comment" name="COMMENT"/>
<feature xsi:type="relational:Column" xmi:id="_column_factwb_id" name="ID"/>
<feature xsi:type="relational:Column" xmi:id="_column_factwb_user" name="USER"/>
</ownedElement>
</relational:Schema>Note: This is only a symbolic example. For the exact definition, see the Definition section.
Fact Query
Plain TableSource over the FACT table.
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:relational="http://www.omg.org/spec/CWM/1.1/resource/relational" xmlns:rolapsrc="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/database/source">
<rolapsrc:TableSource xmi:id="_tablesource_fact" table="_table_fact"/>
<relational:Table xmi:id="_table_fact" name="FACT">
<feature xsi:type="relational:Column" xmi:id="_column_fact_category" name="CATEGORY"/>
<feature xsi:type="relational:Column" xmi:id="_column_fact_amount" name="AMOUNT"/>
<feature xsi:type="relational:Column" xmi:id="_column_fact_comment" name="COMMENT"/>
</relational:Table>
</xmi:XMI>Note: This is only a symbolic example. For the exact definition, see the Definition section.
Category dimension
Single dimension Category with one explicit hierarchy and one level keyed on CATEGORY. The fact joins on FACT.CATEGORY = CATEGORY.CATEGORY.
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:relational="http://www.omg.org/spec/CWM/1.1/resource/relational" xmlns:rolapdim="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/dimension" xmlns:rolaphier="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/dimension/hierarchy" xmlns:rolaplev="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/dimension/hierarchy/level" xmlns:rolapsrc="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/database/source">
<rolapdim:StandardDimension xmi:id="_standarddimension_category" name="Category" hierarchies="_explicithierarchy_category"/>
<relational:Table xmi:id="_table_category" name="CATEGORY">
<feature xsi:type="relational:Column" xmi:id="_column_category_category" name="CATEGORY"/>
<feature xsi:type="relational:Column" xmi:id="_column_category_name" name="NAME"/>
</relational:Table>
<rolaplev:Level xmi:id="_level_category" name="Category" column="_column_category_category" nameColumn="_column_category_name" uniqueMembers="true"/>
<rolapsrc:TableSource xmi:id="_tablesource_category" table="_table_category"/>
<rolaphier:ExplicitHierarchy xmi:id="_explicithierarchy_category" name="Category" allMemberName="All Categories" primaryKey="_column_category_category" source="_tablesource_category" levels="_level_category"/>
</xmi:XMI>Note: This is only a symbolic example. For the exact definition, see the Definition section.
Measures (numeric + text)
Two stored measures share the same fact source:
Amount—SumMeasure(AMOUNT). Numeric, currency-formatted.Comments—TextAggMeasure(COMMENT, separator = " | "). The read-side aggregator concatenates all matching comments at every level the slice rolls up to.
Writeback (FACTWB)
The cube wires both measures into the same FACTWB writeback table:
WritebackTable("FACTWB") [database.writeback]
├── WritebackAttribute(Category connector) → CATEGORY [database.writeback]
├── WritebackMeasure("Amount") → AMOUNT [olap.cube.measure]
└── WritebackMeasure("Comments") → COMMENT [olap.cube.measure]Where these classes live in the ecore. WritebackMeasure is no longer a sibling of the writeback infrastructure (WritebackTable, WritebackAttribute). It now sits in the olap/cube/measure/ ecore package next to SumMeasure, TextAggMeasure and the other base measures, because a writeback measure is conceptually a measure — it names a cube measure by its logical name and just happens to be paired with a database column for persistence. Concretely:
- Java package:
org.eclipse.daanse.rolap.mapping.model.olap.cube.measure.WritebackMeasure(was…database.writeback.WritebackMeasure). - Factory call:
MeasureFactory.eINSTANCE.createWritebackMeasure()(wasWritebackFactory.eINSTANCE.createWritebackMeasure()). - XMI namespace prefix:
rolapmeas:WritebackMeasure(wasrolapdwriteback:WritebackMeasure).
Runtime behaviour. When the client calls Cell.setValue([Measures].[Amount], 42.0, ...) the runtime allocates the numeric value across the cell's leaves (per AllocationPolicy) and emits one or more rows with AMOUNT populated. When the client calls Cell.setValue([Measures].[Comments], "on track", ...) the runtime recognises the TextAggMeasure target by its aggregator (ListAggAggregator ⇒ Datatype.VARCHAR), bypasses allocation, and emits exactly one row keyed by the cell's coordinates with COMMENT set and AMOUNT left NULL. The engine appends ID = UUID() and USER = sessionUser.
Re-running an MDX query for either measure folds the new writeback row in via the normal aggregation path — SUM for Amount, TextAgg (string concat) for Comments.
<rolapwb:WritebackTable xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:rolapwb="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/database/writeback" xmi:id="_writebacktable_factwb" name="FACTWB">
<writebackAttribute xmi:id="_writebackattribute_category">
<column href="_column_factwb_category"/>
<dimensionConnector href="_dimensionconnector_category"/>
</writebackAttribute>
<writebackMeasure xmi:id="_writebackmeasure_amount" name="Amount">
<column href="_column_factwb_amount"/>
</writebackMeasure>
<writebackMeasure xmi:id="_writebackmeasure_comments" name="Comments">
<column href="_column_factwb_comment"/>
</writebackMeasure>
</rolapwb:WritebackTable>Note: This is only a symbolic example. For the exact definition, see the Definition section.
Cube C
One physical cube C over the FACT table with one DimensionConnector and one MeasureGroup holding both measures, referencing the FACTWB writeback table.
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:relational="http://www.omg.org/spec/CWM/1.1/resource/relational" xmlns:rolapcube="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/cube" xmlns:rolapdim="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/dimension" xmlns:rolaphier="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/dimension/hierarchy" xmlns:rolaplev="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/dimension/hierarchy/level" xmlns:rolapmeas="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/cube/measure" xmlns:rolapsrc="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/database/source">
<rolapcube:PhysicalCube xmi:id="_physicalcube_c" name="C" source="_tablesource_fact">
<dimensionConnectors xmi:id="_dimensionconnector_category" foreignKey="_column_fact_category" dimension="_standarddimension_category" overrideDimensionName="Category"/>
<writebackTable xmi:id="_writebacktable_factwb" name="FACTWB">
<writebackAttribute xmi:id="_writebackattribute_category" dimensionConnector="_dimensionconnector_category">
<column href="_column_factwb_category"/>
</writebackAttribute>
<writebackMeasure xmi:id="_writebackmeasure_amount" name="Amount">
<column href="_column_factwb_amount"/>
</writebackMeasure>
<writebackMeasure xmi:id="_writebackmeasure_comments" name="Comments">
<column href="_column_factwb_comment"/>
</writebackMeasure>
</writebackTable>
<measureGroups xmi:id="_measuregroup">
<measures xsi:type="rolapmeas:SumMeasure" xmi:id="_summeasure_amount" name="Amount" formatString=",##0" column="_column_fact_amount"/>
<measures xsi:type="rolapmeas:TextAggMeasure" xmi:id="_textaggmeasure_comments" name="Comments" column="_column_fact_comment" separator=" | ">
<orderByColumns href="_orderedcolumn_comment"/>
</measures>
</measureGroups>
</rolapcube:PhysicalCube>
<rolaphier:ExplicitHierarchy xmi:id="_explicithierarchy_category" name="Category" allMemberName="All Categories" primaryKey="_column_category_category" source="_tablesource_category" levels="_level_category"/>
<rolapsrc:TableSource xmi:id="_tablesource_fact" table="_table_fact"/>
<relational:Table xmi:id="_table_category" name="CATEGORY">
<feature xsi:type="relational:Column" xmi:id="_column_category_category" name="CATEGORY"/>
<feature xsi:type="relational:Column" xmi:id="_column_category_name" name="NAME"/>
</relational:Table>
<relational:Table xmi:id="_table_fact" name="FACT">
<feature xsi:type="relational:Column" xmi:id="_column_fact_category" name="CATEGORY"/>
<feature xsi:type="relational:Column" xmi:id="_column_fact_amount" name="AMOUNT"/>
<feature xsi:type="relational:Column" xmi:id="_column_fact_comment" name="COMMENT"/>
</relational:Table>
<rolapsrc:TableSource xmi:id="_tablesource_category" table="_table_category"/>
<rolaplev:Level xmi:id="_level_category" name="Category" column="_column_category_category" nameColumn="_column_category_name" uniqueMembers="true"/>
<rolapdim:StandardDimension xmi:id="_standarddimension_category" name="Category" hierarchies="_explicithierarchy_category"/>
</xmi:XMI>Note: This is only a symbolic example. For the exact definition, see the Definition section.
Definition
This file represents the complete definition of the catalog.
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:relational="http://www.omg.org/spec/CWM/1.1/resource/relational" xmlns:rolapcat="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/catalog" xmlns:rolapcube="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/cube" xmlns:rolapdim="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/dimension" xmlns:rolaphier="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/dimension/hierarchy" xmlns:rolaplev="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/dimension/hierarchy/level" xmlns:rolapmeas="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/olap/cube/measure" xmlns:rolaprel="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/database/relational" xmlns:rolapsrc="https://www.daanse.org/spec/org.eclipse.daanse.rolap.mapping/database/source">
<rolaprel:OrderedColumn xmi:id="_orderedcolumn_comment" column="_column_fact_comment"/>
<relational:SQLSimpleType xmi:id="_sqlsimpletype_character_varying" name="CHARACTER VARYING" structuralFeature="_column_fact_comment _column_fact_category _column_category_category _column_factwb_category _column_factwb_comment _column_factwb_id _column_category_name _column_factwb_user" typeNumber="12"/>
<relational:SQLSimpleType xmi:id="_sqlsimpletype_integer" name="INTEGER" structuralFeature="_column_factwb_amount _column_fact_amount" typeNumber="4"/>
<rolapcat:Catalog xmi:id="_catalog_writeback_text_aggregation" description="Minimal writeback example: numeric SumMeasure + text TextAggMeasure in the same writeback table." name="Daanse Tutorial - Writeback Text Aggregation" cubes="_physicalcube_c" dbschemas="_schema"/>
<relational:Schema xmi:id="_schema">
<ownedElement xsi:type="relational:Table" xmi:id="_table_fact" name="FACT">
<feature xsi:type="relational:Column" xmi:id="_column_fact_category" name="CATEGORY" type="_sqlsimpletype_character_varying"/>
<feature xsi:type="relational:Column" xmi:id="_column_fact_amount" name="AMOUNT" type="_sqlsimpletype_integer"/>
<feature xsi:type="relational:Column" xmi:id="_column_fact_comment" name="COMMENT" type="_sqlsimpletype_character_varying"/>
</ownedElement>
<ownedElement xsi:type="relational:Table" xmi:id="_table_category" name="CATEGORY">
<feature xsi:type="relational:Column" xmi:id="_column_category_category" name="CATEGORY" type="_sqlsimpletype_character_varying"/>
<feature xsi:type="relational:Column" xmi:id="_column_category_name" name="NAME" type="_sqlsimpletype_character_varying"/>
</ownedElement>
<ownedElement xsi:type="relational:Table" xmi:id="_table_factwb" name="FACTWB">
<feature xsi:type="relational:Column" xmi:id="_column_factwb_category" name="CATEGORY" type="_sqlsimpletype_character_varying"/>
<feature xsi:type="relational:Column" xmi:id="_column_factwb_amount" name="AMOUNT" type="_sqlsimpletype_integer"/>
<feature xsi:type="relational:Column" xmi:id="_column_factwb_comment" name="COMMENT" type="_sqlsimpletype_character_varying"/>
<feature xsi:type="relational:Column" xmi:id="_column_factwb_id" name="ID" type="_sqlsimpletype_character_varying"/>
<feature xsi:type="relational:Column" xmi:id="_column_factwb_user" name="USER" type="_sqlsimpletype_character_varying"/>
</ownedElement>
</relational:Schema>
<rolapsrc:TableSource xmi:id="_tablesource_fact" table="_table_fact"/>
<rolapsrc:TableSource xmi:id="_tablesource_category" table="_table_category"/>
<rolaplev:Level xmi:id="_level_category" name="Category" column="_column_category_category" nameColumn="_column_category_name" uniqueMembers="true"/>
<rolaphier:ExplicitHierarchy xmi:id="_explicithierarchy_category" name="Category" allMemberName="All Categories" primaryKey="_column_category_category" source="_tablesource_category" levels="_level_category"/>
<rolapdim:StandardDimension xmi:id="_standarddimension_category" name="Category" hierarchies="_explicithierarchy_category"/>
<rolapcube:PhysicalCube xmi:id="_physicalcube_c" name="C" source="_tablesource_fact">
<dimensionConnectors xmi:id="_dimensionconnector_category" foreignKey="_column_fact_category" dimension="_standarddimension_category" overrideDimensionName="Category"/>
<writebackTable xmi:id="_writebacktable_factwb" name="FACTWB">
<writebackAttribute xmi:id="_writebackattribute_category" column="_column_factwb_category" dimensionConnector="_dimensionconnector_category"/>
<writebackMeasure xmi:id="_writebackmeasure_amount" column="_column_factwb_amount" name="Amount"/>
<writebackMeasure xmi:id="_writebackmeasure_comments" column="_column_factwb_comment" name="Comments"/>
</writebackTable>
<measureGroups xmi:id="_measuregroup">
<measures xsi:type="rolapmeas:SumMeasure" xmi:id="_summeasure_amount" name="Amount" formatString="#,##0" column="_column_fact_amount"/>
<measures xsi:type="rolapmeas:TextAggMeasure" xmi:id="_textaggmeasure_comments" name="Comments" column="_column_fact_comment" orderByColumns="_orderedcolumn_comment" separator=" | "/>
</measureGroups>
</rolapcube:PhysicalCube>
</xmi:XMI>Tutorial Zip
This file contains the data-tables as csv and the mapping as xmi file.