Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions packages/cubejs-api-gateway/openspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ components:
type: "string"
shortTitle:
type: "string"
V1CubeMetaDimensionGranularity:
type: "object"
required:
- name
- title
properties:
name:
type: "string"
title:
type: "string"
V1CubeMetaDimension:
type: "object"
required:
Expand All @@ -110,6 +120,10 @@ components:
type: "string"
type:
type: "string"
granularities:
type: array
items:
$ref: "#/components/schemas/V1CubeMetaDimensionGranularity"
V1CubeMetaMeasure:
type: "object"
required:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class CubeToMetaTransformer {
*/
transform(cube) {
const cubeTitle = cube.title || this.titleize(cube.name);

const isCubeVisible = this.isVisible(cube, true);

return {
Expand Down Expand Up @@ -80,6 +80,13 @@ export class CubeToMetaTransformer {
? this.isVisible(nameToDimension[1], !nameToDimension[1].primaryKey)
: false,
primaryKey: !!nameToDimension[1].primaryKey,
granularities:
nameToDimension[1].granularities
? R.compose(R.map((g) => ({
name: g[0],
title: this.title(cubeTitle, g, true),
})), R.toPairs)(nameToDimension[1].granularities)
: undefined,
})),
R.toPairs
)(cube.dimensions || {}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const BaseDimensionWithoutSubQuery = {
then: Joi.object().pattern(identifierRegex,
Joi.alternatives([
Joi.object().keys({
title: Joi.string(),
interval: GranularityInterval.required(),
origin: Joi.string().required().custom((value, helpers) => {
const date = new Date(value);
Expand All @@ -122,6 +123,7 @@ const BaseDimensionWithoutSubQuery = {
}),
}),
Joi.object().keys({
title: Joi.string(),
interval: GranularityInterval.required().custom((value, helper) => {
const intParsed = value.split(' ');
const msg = { custom: 'Arbitrary intervals cannot be used without origin point specified' };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,8 @@ describe('Cube Validation', () => {
{
const cube = newCube({
half_year: {
interval: '6 months'
interval: '6 months',
title: 'Half year intervals'
}
});

Expand Down Expand Up @@ -675,6 +676,7 @@ describe('Cube Validation', () => {
half_year: {
interval: '6 months',
offset: '4 weeks 5 days 6 hours',
title: 'Half year intervals title'
}
});

Expand Down Expand Up @@ -757,6 +759,7 @@ describe('Cube Validation', () => {
half_year: {
interval: '15 days',
offset: '1 hours 7 minutes 8 seconds',
title: 'Just title'
}
});

Expand Down Expand Up @@ -847,6 +850,7 @@ describe('Cube Validation', () => {
half_year: {
interval: '10 months',
origin: '2024-04',
title: 'Someone loves number 10'
}
});

Expand Down
29 changes: 28 additions & 1 deletion packages/cubejs-schema-compiler/test/unit/schema.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { prepareCompiler } from './PrepareCompiler';
import { createCubeSchema } from './utils';
import { createCubeSchema, createCubeSchemaWithCustomGranularities } from './utils';

describe('Schema Testing', () => {
const schemaCompile = async () => {
Expand Down Expand Up @@ -294,6 +294,33 @@ describe('Schema Testing', () => {
expect(segments.find((segment) => segment.name === 'CubeA.sfUsers').description).toBe('SF users segment from createCubeSchema');
});

it('custom granularities in meta', async () => {
const { compiler, metaTransformer } = prepareCompiler([
createCubeSchemaWithCustomGranularities('orders')
]);
await compiler.compile();

const { dimensions } = metaTransformer.cubes[0].config;

expect(dimensions).toBeDefined();
expect(dimensions.length).toBeGreaterThan(0);

const dg = dimensions.find((dimension) => dimension.name === 'orders.createdAt');
expect(dg).toBeDefined();
expect(dg.granularities).toBeDefined();
expect(dg.granularities.length).toBeGreaterThan(0);

// Granularity defined with title
let gr = dg.granularities.find(g => g.name === 'half_year');
expect(gr).toBeDefined();
expect(gr.title).toBe('6 month intervals');

// // Granularity defined without title -> titlize()
gr = dg.granularities.find(g => g.name === 'half_year_by_1st_june');
expect(gr).toBeDefined();
expect(gr.title).toBe('Half Year By1 St June');
});

it('join types', async () => {
const { compiler, cubeEvaluator } = prepareCompiler([
createCubeSchema({
Expand Down
2 changes: 2 additions & 0 deletions packages/cubejs-schema-compiler/test/unit/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,10 @@ export function createCubeSchemaWithCustomGranularities(name: string): string {
granularities: {
half_year: {
interval: '6 months',
title: '6 month intervals'
},
half_year_by_1st_april: {
title: 'Half year from Apr to Oct',
interval: '6 months',
offset: '3 months'
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,10 +324,12 @@ describe('Yaml Schema Testing', () => {
granularities:
- name: six_months
interval: 6 months
title: 6 month intervals
- name: three_months_offset
interval: 3 months
offset: 2 weeks
- name: fiscal_year_1st_april
title: Fiscal year by Apr
interval: 1 year
origin: >
2024-04-01
Expand Down
Loading