Skip to content

Commit 253c0a7

Browse files
HCK-10156: enable dbt feature (#104)
* HCK-10156: add dbt provider * HCK-10156: enable dbt feature
1 parent 9444d5d commit 253c0a7

File tree

5 files changed

+170
-1
lines changed

5 files changed

+170
-1
lines changed

esbuild.package.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ esbuild
1414
entryPoints: [
1515
path.resolve(__dirname, 'forward_engineering', 'api.js'),
1616
path.resolve(__dirname, 'forward_engineering', 'ddlProvider.js'),
17+
path.resolve(__dirname, 'forward_engineering', 'dbtProvider.js'),
1718
path.resolve(__dirname, 'reverse_engineering', 'api.js'),
1819
],
1920
bundle: true,

forward_engineering/dbtProvider.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* @typedef {import('./types').ColumnDefinition} ColumnDefinition
3+
* @typedef {import('./types').JsonSchema} JsonSchema
4+
* @typedef {import('./types').ConstraintDto} ConstraintDto
5+
*/
6+
const { toLower, toUpper } = require('lodash');
7+
8+
const types = require('./configs/types');
9+
const defaultTypes = require('./configs/defaultTypes');
10+
const { decorateType } = require('./helpers/columnDefinitionHelper');
11+
const getKeyHelper = require('./helpers/keyHelper');
12+
13+
class DbtProvider {
14+
/**
15+
* @type {AppInstance}
16+
*/
17+
#appInstance;
18+
19+
/**
20+
* @param {{ appInstance: AppInstance }}
21+
*/
22+
constructor({ appInstance }) {
23+
this.#appInstance = appInstance;
24+
}
25+
26+
/**
27+
* @param {{ appInstance }}
28+
* @returns {DbtProvider}
29+
*/
30+
static createDbtProvider({ appInstance }) {
31+
return new DbtProvider({ appInstance });
32+
}
33+
34+
/**
35+
* @param {string} type
36+
* @returns {string | undefined}
37+
*/
38+
getDefaultType(type) {
39+
return defaultTypes[type];
40+
}
41+
42+
/**
43+
* @returns {Record<string, object>}
44+
*/
45+
getTypesDescriptors() {
46+
return types;
47+
}
48+
49+
/**
50+
* @param {string} type
51+
* @returns {boolean}
52+
*/
53+
hasType(type) {
54+
return Object.keys(types).map(toLower).includes(toLower(type));
55+
}
56+
57+
/**
58+
* @param {{ type: string; columnDefinition: ColumnDefinition }}
59+
* @returns {string}
60+
*/
61+
decorateType({ type, columnDefinition }) {
62+
return decorateType(toUpper(type), columnDefinition);
63+
}
64+
65+
/**
66+
* @param {{ jsonSchema: JsonSchema }}
67+
* @returns {ConstraintDto[]}
68+
*/
69+
getCompositeKeyConstraints({ jsonSchema }) {
70+
const keyHelper = getKeyHelper(this.#appInstance);
71+
72+
return keyHelper.getCompositeKeyConstraints({ jsonSchema });
73+
}
74+
75+
/**
76+
* @param {{ columnDefinition: ColumnDefinition; jsonSchema: JsonSchema }}
77+
* @returns {ConstraintDto[]}
78+
*/
79+
getColumnConstraints({ columnDefinition, jsonSchema }) {
80+
const keyHelper = getKeyHelper(this.#appInstance);
81+
82+
return keyHelper.getColumnConstraints({ columnDefinition });
83+
}
84+
}
85+
86+
module.exports = DbtProvider;

forward_engineering/helpers/keyHelper.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* @typedef {import('../types').ColumnDefinition} ColumnDefinition
3+
* @typedef {import('../types').ConstraintDto} ConstraintDto
4+
* @typedef {import('../types').JsonSchema} JsonSchema
5+
*/
6+
17
const _ = require('lodash');
28

39
module.exports = app => {
@@ -210,10 +216,54 @@ module.exports = app => {
210216
};
211217
};
212218

219+
/**
220+
* @param {{ columnDefinition: ColumnDefinition }}
221+
* @returns {ConstraintDto | undefined}
222+
*/
223+
const getPrimaryKeyConstraint = ({ columnDefinition }) => {
224+
if (!isPrimaryKey(columnDefinition) && !isInlinePrimaryKey(columnDefinition)) {
225+
return;
226+
}
227+
228+
return hydratePrimaryKeyOptions(_.get(columnDefinition, 'primaryKeyOptions.[0]', {}));
229+
};
230+
231+
/**
232+
* @param {{ columnDefinition: ColumnDefinition }}
233+
* @returns {ConstraintDto | undefined}
234+
*/
235+
const getUniqueKeyConstraint = ({ columnDefinition }) => {
236+
if (!isUnique(columnDefinition) && !isInlineUnique(columnDefinition)) {
237+
return;
238+
}
239+
240+
return hydrateUniqueOptions(_.get(columnDefinition, 'uniqueKeyOptions.[0]', {}));
241+
};
242+
243+
const getCompositeKeyConstraints = ({ jsonSchema }) => {
244+
const compositePrimaryKeys = getCompositePrimaryKeys(jsonSchema);
245+
const compositeUniqueKeys = getCompositeUniqueKeys(jsonSchema);
246+
247+
return [...compositePrimaryKeys, ...compositeUniqueKeys];
248+
};
249+
250+
/**
251+
* @param {{ columnDefinition: ColumnDefinition }}
252+
* @returns {ConstraintDto[]}
253+
*/
254+
const getColumnConstraints = ({ columnDefinition }) => {
255+
const primaryKeyConstraint = getPrimaryKeyConstraint({ columnDefinition });
256+
const uniqueKeyConstraint = getUniqueKeyConstraint({ columnDefinition });
257+
258+
return [primaryKeyConstraint, uniqueKeyConstraint].filter(Boolean);
259+
};
260+
213261
return {
214262
getTableKeyConstraints,
215263
isInlineUnique,
216264
isInlinePrimaryKey,
217265
getTablePartitionKey,
266+
getCompositeKeyConstraints,
267+
getColumnConstraints,
218268
};
219269
};

forward_engineering/types.d.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
export type ColumnDefinition = {
2+
name: string;
3+
type: string;
4+
isActivated: boolean;
5+
length?: number;
6+
precision?: number;
7+
primaryKey?: boolean;
8+
scale?: number;
9+
timePrecision?: number;
10+
unique?: boolean;
11+
};
12+
13+
export type ConstraintDtoColumn = {
14+
name: string;
15+
isActivated: boolean;
16+
};
17+
18+
export type KeyType = 'PRIMARY KEY' | 'UNIQUE';
19+
20+
export type ConstraintDto = {
21+
keyType: KeyType;
22+
name: string;
23+
columns?: ConstraintDtoColumn[];
24+
};
25+
26+
export type JsonSchema = Record<string, unknown>;

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@
1616
"nestedCollections": false,
1717
"disablePatternField": true,
1818
"disableMultipleTypes": true,
19-
"enableForwardEngineering": true,
19+
"enableForwardEngineering": {
20+
"jsonDocument": true,
21+
"jsonSchema": true,
22+
"excel": true,
23+
"plugin": true,
24+
"dbt": true
25+
},
2026
"disableReverseEngineering": false,
2127
"disableChoices": true,
2228
"enableJsonType": true,

0 commit comments

Comments
 (0)