Skip to content

Commit 441e8fc

Browse files
committed
refactor(schema-compiler): Extract dimensionOnlyMeasureToHierarchy method
1 parent 7ca9497 commit 441e8fc

File tree

1 file changed

+51
-48
lines changed

1 file changed

+51
-48
lines changed

packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,13 +1696,60 @@ export class BaseQuery {
16961696
${this.query()}`;
16971697
}
16981698

1699+
dimensionOnlyMeasureToHierarchy(context, m) {
1700+
const measureName = typeof m.measure === 'string' ? m.measure : `${m.measure.cubeName}.${m.measure.name}`;
1701+
const memberNamesForMeasure = this.collectFrom(
1702+
[m],
1703+
this.collectMemberNamesFor.bind(this),
1704+
context ? ['collectMemberNamesFor', JSON.stringify(context)] : 'collectMemberNamesFor',
1705+
this.queryCache
1706+
);
1707+
const cubeNamesForMeasure = R.pipe(
1708+
R.map(member => this.memberInstanceByPath(member)),
1709+
// collectMemberNamesFor can return both view.dim and cube.dim
1710+
R.filter(member => member.definition().ownedByCube),
1711+
R.map(member => member.cube()),
1712+
// Single member expression can reference multiple dimensions from same cube
1713+
R.uniq,
1714+
)(
1715+
memberNamesForMeasure
1716+
);
1717+
1718+
let cubeNameToAttach;
1719+
switch (cubeNamesForMeasure.length) {
1720+
case 0:
1721+
// For zero reference measure there's nothing to derive info about measure from
1722+
// So it assume that it's a regular measure, and it will be evaluated on top of join tree
1723+
return [measureName, [{
1724+
multiplied: false,
1725+
measure: m.measure,
1726+
}]];
1727+
case 1:
1728+
[cubeNameToAttach] = cubeNamesForMeasure;
1729+
break;
1730+
default:
1731+
throw new Error(`Expected single cube for dimension-only measure ${measureName}, got ${cubeNamesForMeasure}`);
1732+
}
1733+
1734+
const multiplied = this.multipliedJoinRowResult(cubeNameToAttach) || false;
1735+
1736+
const attachedMeasure = {
1737+
...m.measure,
1738+
originalCubeName: m.measure.cubeName,
1739+
cubeName: cubeNameToAttach
1740+
};
1741+
1742+
return [measureName, [{
1743+
multiplied,
1744+
measure: attachedMeasure,
1745+
}]];
1746+
}
1747+
16991748
collectRootMeasureToHieararchy(context) {
17001749
const notAddedMeasureFilters = R.flatten(this.measureFilters.map(f => f.getMembers()))
17011750
.filter(f => R.none(m => m.measure === f.measure, this.measures));
17021751

17031752
return R.fromPairs(this.measures.concat(notAddedMeasureFilters).map(m => {
1704-
const measureName = typeof m.measure === 'string' ? m.measure : `${m.measure.cubeName}.${m.measure.name}`;
1705-
17061753
const collectedMeasures = this.collectFrom(
17071754
[m],
17081755
this.collectMultipliedMeasures(context),
@@ -1724,53 +1771,9 @@ export class BaseQuery {
17241771
// Measures like this needs a special treatment to attach them to cube and decide if they are multiplied or not
17251772
// This would return measure object in `measure`, not path
17261773
// TODO return measure object for every measure
1727-
1728-
const memberNamesForMeasure = this.collectFrom(
1729-
[m],
1730-
this.collectMemberNamesFor.bind(this),
1731-
context ? ['collectMemberNamesFor', JSON.stringify(context)] : 'collectMemberNamesFor',
1732-
this.queryCache
1733-
);
1734-
const cubeNamesForMeasure = R.pipe(
1735-
R.map(member => this.memberInstanceByPath(member)),
1736-
// collectMemberNamesFor can return both view.dim and cube.dim
1737-
R.filter(member => member.definition().ownedByCube),
1738-
R.map(member => member.cube()),
1739-
// Single member expression can reference multiple dimensions from same cube
1740-
R.uniq,
1741-
)(
1742-
memberNamesForMeasure
1743-
);
1744-
1745-
let cubeNameToAttach;
1746-
switch (cubeNamesForMeasure.length) {
1747-
case 0:
1748-
// For zero reference measure there's nothing to derive info about measure from
1749-
// So it assume that it's a regular measure, and it will be evaluated on top of join tree
1750-
return [measureName, [{
1751-
multiplied: false,
1752-
measure: m.measure,
1753-
}]];
1754-
case 1:
1755-
[cubeNameToAttach] = cubeNamesForMeasure;
1756-
break;
1757-
default:
1758-
throw new Error(`Expected single cube for dimension-only measure ${measureName}, got ${cubeNamesForMeasure}`);
1759-
}
1760-
1761-
const multiplied = this.multipliedJoinRowResult(cubeNameToAttach) || false;
1762-
1763-
const attachedMeasure = {
1764-
...m.measure,
1765-
originalCubeName: m.measure.cubeName,
1766-
cubeName: cubeNameToAttach
1767-
};
1768-
1769-
return [measureName, [{
1770-
multiplied,
1771-
measure: attachedMeasure,
1772-
}]];
1774+
return this.dimensionOnlyMeasureToHierarchy(context, m);
17731775
}
1776+
const measureName = typeof m.measure === 'string' ? m.measure : `${m.measure.cubeName}.${m.measure.name}`;
17741777
return [measureName, collectedMeasures];
17751778
}));
17761779
}

0 commit comments

Comments
 (0)