@@ -3,6 +3,7 @@ import { CubeMembers, SchemaContext } from '../ScaffoldingTemplate';
33import {
44 CubeDescriptor ,
55 DatabaseSchema ,
6+ Dimension ,
67 MemberType ,
78 ScaffoldingSchema ,
89 TableName ,
@@ -51,21 +52,39 @@ export abstract class BaseSchemaFormatter {
5152 tableNames : TableName [ ] ,
5253 schemaContext : SchemaContext = { }
5354 ) : SchemaFile [ ] {
54- const schemaForTables = this . scaffoldingSchema . generateForTables (
55+ const tableSchemas = this . scaffoldingSchema . generateForTables (
5556 tableNames . map ( ( n ) => this . scaffoldingSchema . resolveTableName ( n ) )
5657 ) ;
5758
58- return schemaForTables . map ( ( tableSchema ) => ( {
59- fileName : `${ tableSchema . cube } .${ this . fileExtension ( ) } ` ,
60- content : this . renderFile ( this . schemaDescriptorForTable ( tableSchema , schemaContext ) ) ,
61- } ) ) ;
59+ return this . generateFilesByTableSchemas ( tableSchemas , schemaContext ) ;
6260 }
6361
6462 public generateFilesByCubeDescriptors (
6563 cubeDescriptors : CubeDescriptor [ ] ,
6664 schemaContext : SchemaContext = { }
6765 ) : SchemaFile [ ] {
68- return this . schemaForTablesByCubeDescriptors ( cubeDescriptors ) . map ( ( tableSchema ) => ( {
66+ return this . generateFilesByTableSchemas ( this . tableSchemasByCubeDescriptors ( cubeDescriptors ) , schemaContext ) ;
67+ }
68+
69+ protected generateFilesByTableSchemas ( tableSchemas : TableSchema [ ] , schemaContext : SchemaContext = { } ) : SchemaFile [ ] {
70+ const cubeToDimensionNamesMap = new Map (
71+ tableSchemas . map ( tableSchema => [ tableSchema . cube , tableSchema . dimensions . map ( d => d . name ) ] )
72+ ) ;
73+
74+ tableSchemas = tableSchemas . map ( ( tableSchema ) => {
75+ const updatedJoins = tableSchema . joins . map ( ( join ) => ( {
76+ ...join ,
77+ thisTableColumnIncludedAsDimension : ! ! cubeToDimensionNamesMap . get ( tableSchema . cube ) ?. includes ( join . thisTableColumn ) ,
78+ columnToJoinIncludedAsDimension : ! ! cubeToDimensionNamesMap . get ( join . cubeToJoin ) ?. includes ( join . columnToJoin )
79+ } ) ) ;
80+
81+ return {
82+ ...tableSchema ,
83+ joins : updatedJoins
84+ } ;
85+ } ) ;
86+
87+ return tableSchemas . map ( ( tableSchema ) => ( {
6988 fileName : `${ tableSchema . cube } .${ this . fileExtension ( ) } ` ,
7089 content : this . renderFile ( this . schemaDescriptorForTable ( tableSchema , schemaContext ) ) ,
7190 } ) ) ;
@@ -85,7 +104,7 @@ export abstract class BaseSchemaFormatter {
85104 : undefined ;
86105 }
87106
88- protected memberName ( member ) {
107+ protected memberName ( member : { title : string } ) {
89108 const title = member . title . replace ( / [ ^ A - Z a - z 0 - 9 ] + / g, '_' ) . toLowerCase ( ) ;
90109
91110 if ( this . options . snakeCase ) {
@@ -106,7 +125,7 @@ export abstract class BaseSchemaFormatter {
106125 return ! ! name . match ( / ^ [ a - z 0 - 9 _ ] + $ / ) ;
107126 }
108127
109- public schemaDescriptorForTable ( tableSchema : TableSchema , schemaContext : SchemaContext = { } ) {
128+ protected schemaDescriptorForTable ( tableSchema : TableSchema , schemaContext : SchemaContext = { } ) {
110129 let table = `${
111130 tableSchema . schema ?. length ? `${ this . escapeName ( tableSchema . schema ) } .` : ''
112131 } ${ this . escapeName ( tableSchema . table ) } `;
@@ -130,23 +149,39 @@ export abstract class BaseSchemaFormatter {
130149 sql : `SELECT * FROM ${ table } ` ,
131150 } ;
132151
133- return {
134- cube : tableSchema . cube ,
135- ...sqlOption ,
136- ...dataSourceProp ,
152+ // Try to use dimension refs if possible
153+ // Source and target columns must be included in the respective cubes as dimensions
154+ // {CUBE.dimension_name} = {other_cube.other_dimension_name}
155+ // instead of
156+ // {CUBE}.dimension_name = {other_cube}.other_dimension_name
157+ const joins = tableSchema . joins
158+ . map ( ( j ) => {
159+ const thisTableColumnRef = j . thisTableColumnIncludedAsDimension
160+ ? this . cubeReference ( `CUBE.${ this . memberName ( { title : j . thisTableColumn } ) } ` )
161+ : `${ this . cubeReference ( 'CUBE' ) } .${ this . escapeName (
162+ j . thisTableColumn
163+ ) } `;
164+ const columnToJoinRef = j . columnToJoinIncludedAsDimension
165+ ? this . cubeReference ( `${ j . cubeToJoin } .${ this . memberName ( { title : j . columnToJoin } ) } ` )
166+ : `${ this . cubeReference ( j . cubeToJoin ) } .${ this . escapeName ( j . columnToJoin ) } ` ;
137167
138- joins : tableSchema . joins
139- . map ( ( j ) => ( {
168+ return ( {
140169 [ j . cubeToJoin ] : {
141- sql : `${ this . cubeReference ( 'CUBE' ) } .${ this . escapeName (
142- j . thisTableColumn
143- ) } = ${ this . cubeReference ( j . cubeToJoin ) } .${ this . escapeName ( j . columnToJoin ) } `,
170+ sql : `${ thisTableColumnRef } = ${ columnToJoinRef } ` ,
144171 relationship : this . options . snakeCase
145172 ? ( JOIN_RELATIONSHIP_MAP [ j . relationship ] ?? j . relationship )
146173 : j . relationship ,
147174 } ,
148- } ) )
149- . reduce ( ( a , b ) => ( { ...a , ...b } ) , { } ) ,
175+ } ) ;
176+ } )
177+ . reduce ( ( a , b ) => ( { ...a , ...b } ) , { } ) ;
178+
179+ return {
180+ cube : tableSchema . cube ,
181+ ...sqlOption ,
182+ ...dataSourceProp ,
183+
184+ joins,
150185 dimensions : tableSchema . dimensions . sort ( ( a ) => ( a . isPrimaryKey ? - 1 : 0 ) )
151186 . map ( ( m ) => ( {
152187 [ this . memberName ( m ) ] : {
@@ -189,7 +224,7 @@ export abstract class BaseSchemaFormatter {
189224 } ;
190225 }
191226
192- protected schemaForTablesByCubeDescriptors ( cubeDescriptors : CubeDescriptor [ ] ) {
227+ protected tableSchemasByCubeDescriptors ( cubeDescriptors : CubeDescriptor [ ] ) {
193228 const tableNames = cubeDescriptors . map ( ( { tableName } ) => tableName ) ;
194229 const generatedSchemaForTables = this . scaffoldingSchema . generateForTables (
195230 tableNames . map ( ( n ) => this . scaffoldingSchema . resolveTableName ( n ) )
0 commit comments