@dbml/connector 5.0.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/connectors/mssql/expect-out-files/schema.json +238 -113
- package/__tests__/connectors/mysql/expect-out-files/schema.json +132 -2
- package/__tests__/connectors/postgres/expect-out-files/schema.json +219 -8
- package/dist/connectors/bigqueryConnector.js +5 -4
- package/dist/connectors/mssqlConnector.js +82 -149
- package/dist/connectors/mysqlConnector.js +67 -8
- package/dist/connectors/postgresConnector.d.ts +1 -1
- package/dist/connectors/postgresConnector.js +115 -42
- package/dist/connectors/snowflakeConnector.js +8 -6
- package/dist/connectors/types.d.ts +10 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +17 -7
- package/dist/utils/helpers.d.ts +2 -1
- package/dist/utils/helpers.js +14 -3
- package/dist/utils/parseSchema.d.ts +1 -1
- package/dist/utils/parseSchema.js +13 -13
- package/eslint.config.ts +70 -0
- package/jest.config.ts +2 -2
- package/package.json +15 -6
- package/src/connectors/bigqueryConnector.ts +5 -4
- package/src/connectors/mssqlConnector.ts +92 -162
- package/src/connectors/mysqlConnector.ts +77 -12
- package/src/connectors/postgresConnector.ts +126 -44
- package/src/connectors/snowflakeConnector.ts +24 -19
- package/src/connectors/types.ts +20 -65
- package/src/index.ts +1 -1
- package/src/utils/helpers.ts +30 -12
- package/src/utils/parseSchema.ts +11 -11
- package/test-output.log +18 -0
- package/tsconfig.json +1 -1
- package/.eslintrc.json +0 -24
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.fetchSchemaJson = void 0;
|
|
4
|
-
/* eslint-disable camelcase */
|
|
5
4
|
const pg_1 = require("pg");
|
|
6
5
|
const parseSchema_1 = require("../utils/parseSchema");
|
|
7
6
|
const getValidatedClient = async (connection) => {
|
|
@@ -63,13 +62,15 @@ const getDbdefault = (data_type, column_default, default_type) => {
|
|
|
63
62
|
const generateField = (row) => {
|
|
64
63
|
const { column_name, data_type, character_maximum_length, numeric_precision, numeric_scale, udt_schema, udt_name, identity_increment, is_nullable, column_default, default_type, column_comment, } = row;
|
|
65
64
|
const dbdefault = column_default && default_type !== 'increment' ? getDbdefault(data_type, column_default, default_type) : null;
|
|
66
|
-
const fieldType = data_type === 'USER-DEFINED'
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
const fieldType = data_type === 'USER-DEFINED'
|
|
66
|
+
? {
|
|
67
|
+
type_name: udt_name,
|
|
68
|
+
schemaName: udt_schema,
|
|
69
|
+
}
|
|
70
|
+
: {
|
|
71
|
+
type_name: getFieldType(data_type, udt_name, character_maximum_length, numeric_precision, numeric_scale),
|
|
72
|
+
schemaName: null,
|
|
73
|
+
};
|
|
73
74
|
return {
|
|
74
75
|
name: column_name,
|
|
75
76
|
type: fieldType,
|
|
@@ -241,7 +242,7 @@ const generateRawRefs = async (client, schemas) => {
|
|
|
241
242
|
});
|
|
242
243
|
return refs;
|
|
243
244
|
};
|
|
244
|
-
const
|
|
245
|
+
const generateIndexesAndConstraints = async (client, schemas) => {
|
|
245
246
|
const indexListSql = `
|
|
246
247
|
WITH user_tables AS (
|
|
247
248
|
SELECT
|
|
@@ -288,8 +289,8 @@ const generateIndexes = async (client, schemas) => {
|
|
|
288
289
|
ii.is_unique,
|
|
289
290
|
ii.is_primary,
|
|
290
291
|
ii.index_type,
|
|
291
|
-
ii.columns,
|
|
292
|
-
ii.expressions,
|
|
292
|
+
ii.columns AS index_columns,
|
|
293
|
+
ii.expressions AS index_expressions,
|
|
293
294
|
ii.constraint_type -- Retained constraint type here
|
|
294
295
|
FROM
|
|
295
296
|
user_tables ut
|
|
@@ -304,34 +305,36 @@ const generateIndexes = async (client, schemas) => {
|
|
|
304
305
|
;
|
|
305
306
|
`;
|
|
306
307
|
const indexListResult = await client.query(indexListSql);
|
|
307
|
-
const {
|
|
308
|
-
const { constraint_type,
|
|
309
|
-
if (
|
|
308
|
+
const { outOfLineIndexes, inlineIndexes } = indexListResult.rows.reduce((acc, row) => {
|
|
309
|
+
const { constraint_type, index_columns } = row;
|
|
310
|
+
if (index_columns === 'null' || index_columns.trim() === '')
|
|
310
311
|
return acc;
|
|
311
|
-
const isSingleColumn =
|
|
312
|
-
const
|
|
313
|
-
if (
|
|
314
|
-
acc.
|
|
312
|
+
const isSingleColumn = index_columns.split(',').length === 1;
|
|
313
|
+
const isInlineIndex = isSingleColumn && (constraint_type === 'PRIMARY KEY' || constraint_type === 'UNIQUE');
|
|
314
|
+
if (isInlineIndex) {
|
|
315
|
+
acc.inlineIndexes.push(row);
|
|
315
316
|
}
|
|
316
317
|
else {
|
|
317
|
-
acc.
|
|
318
|
+
acc.outOfLineIndexes.push(row);
|
|
318
319
|
}
|
|
319
320
|
return acc;
|
|
320
|
-
}, {
|
|
321
|
-
const indexes =
|
|
322
|
-
const { table_schema, table_name, index_name, index_type,
|
|
323
|
-
const indexColumns =
|
|
321
|
+
}, { outOfLineIndexes: [], inlineIndexes: [] });
|
|
322
|
+
const indexes = outOfLineIndexes.reduce((acc, indexRow) => {
|
|
323
|
+
const { table_schema, table_name, index_name, index_type, index_columns, index_expressions, is_primary, is_unique, } = indexRow;
|
|
324
|
+
const indexColumns = index_columns.split(',').map((column) => {
|
|
324
325
|
return {
|
|
325
326
|
type: 'column',
|
|
326
327
|
value: column.trim(),
|
|
327
328
|
};
|
|
328
329
|
});
|
|
329
|
-
const indexExpressions =
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
330
|
+
const indexExpressions = index_expressions
|
|
331
|
+
? index_expressions.split(',').map((expression) => {
|
|
332
|
+
return {
|
|
333
|
+
type: 'expression',
|
|
334
|
+
value: expression,
|
|
335
|
+
};
|
|
336
|
+
})
|
|
337
|
+
: [];
|
|
335
338
|
const index = {
|
|
336
339
|
name: index_name,
|
|
337
340
|
type: index_type,
|
|
@@ -339,6 +342,8 @@ const generateIndexes = async (client, schemas) => {
|
|
|
339
342
|
...indexColumns,
|
|
340
343
|
...indexExpressions,
|
|
341
344
|
],
|
|
345
|
+
pk: !!is_primary,
|
|
346
|
+
unique: !is_primary && !!is_unique,
|
|
342
347
|
};
|
|
343
348
|
const key = `${table_schema}.${table_name}`;
|
|
344
349
|
if (acc[key]) {
|
|
@@ -349,27 +354,94 @@ const generateIndexes = async (client, schemas) => {
|
|
|
349
354
|
}
|
|
350
355
|
return acc;
|
|
351
356
|
}, {});
|
|
352
|
-
const tableConstraints =
|
|
353
|
-
|
|
357
|
+
const tableConstraints = {};
|
|
358
|
+
inlineIndexes.forEach((row) => {
|
|
359
|
+
const { table_schema, table_name, index_columns, constraint_type, } = row;
|
|
354
360
|
const key = `${table_schema}.${table_name}`;
|
|
355
|
-
if (!
|
|
356
|
-
|
|
357
|
-
const columnNames =
|
|
361
|
+
if (!tableConstraints[key])
|
|
362
|
+
tableConstraints[key] = {};
|
|
363
|
+
const columnNames = index_columns.split(',').map((column) => column.trim());
|
|
358
364
|
columnNames.forEach((columnName) => {
|
|
359
|
-
if (!
|
|
360
|
-
|
|
365
|
+
if (!tableConstraints[key][columnName])
|
|
366
|
+
tableConstraints[key][columnName] = { checks: [] };
|
|
361
367
|
if (constraint_type === 'PRIMARY KEY') {
|
|
362
|
-
|
|
368
|
+
tableConstraints[key][columnName].pk = true;
|
|
363
369
|
}
|
|
364
|
-
if (constraint_type === 'UNIQUE' && !
|
|
365
|
-
|
|
370
|
+
if (constraint_type === 'UNIQUE' && !tableConstraints[key][columnName].pk) {
|
|
371
|
+
tableConstraints[key][columnName].unique = true;
|
|
366
372
|
}
|
|
367
373
|
});
|
|
368
|
-
return acc;
|
|
369
374
|
}, {});
|
|
375
|
+
const checkListSql = `
|
|
376
|
+
SELECT
|
|
377
|
+
n.nspname AS table_schema,
|
|
378
|
+
c.relname AS table_name,
|
|
379
|
+
MAX(a.attname) AS column_name,
|
|
380
|
+
con.conname AS check_name,
|
|
381
|
+
pg_get_constraintdef(con.oid) AS check_definition,
|
|
382
|
+
CASE
|
|
383
|
+
WHEN COUNT(*) = 1 THEN TRUE
|
|
384
|
+
ELSE FALSE
|
|
385
|
+
END AS is_column_constraint
|
|
386
|
+
FROM
|
|
387
|
+
pg_catalog.pg_constraint AS con
|
|
388
|
+
JOIN
|
|
389
|
+
pg_catalog.pg_class AS c
|
|
390
|
+
ON con.conrelid = c.oid
|
|
391
|
+
LEFT JOIN
|
|
392
|
+
pg_catalog.pg_namespace AS n
|
|
393
|
+
ON c.relnamespace = n.oid
|
|
394
|
+
LEFT JOIN
|
|
395
|
+
pg_catalog.pg_attribute AS a
|
|
396
|
+
ON a.attrelid = c.oid AND a.attnum = ANY(con.conkey)
|
|
397
|
+
WHERE con.contype = 'c' -- 'c' for CHECK constraints
|
|
398
|
+
${(0, parseSchema_1.buildSchemaQuery)('n.nspname', schemas)}
|
|
399
|
+
GROUP BY
|
|
400
|
+
con.conname,
|
|
401
|
+
n.nspname,
|
|
402
|
+
c.relname,
|
|
403
|
+
con.oid
|
|
404
|
+
`;
|
|
405
|
+
const checkListResult = await client.query(checkListSql);
|
|
406
|
+
const checks = {};
|
|
407
|
+
checkListResult.rows.forEach((row) => {
|
|
408
|
+
const { table_schema, table_name, check_name, check_definition, column_name, is_column_constraint, } = row;
|
|
409
|
+
if (typeof table_schema !== 'string' || typeof table_name !== 'string' || typeof check_definition !== 'string') {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
if (!check_definition.match(/CHECK \(\(.*\)\)/)) {
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
if (is_column_constraint && typeof column_name !== 'string') {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
const key = `${table_schema}.${table_name}`;
|
|
419
|
+
if (is_column_constraint) {
|
|
420
|
+
if (!tableConstraints[key])
|
|
421
|
+
tableConstraints[key] = {};
|
|
422
|
+
if (!tableConstraints[key][column_name])
|
|
423
|
+
tableConstraints[key][column_name] = { checks: [] };
|
|
424
|
+
tableConstraints[key][column_name].checks.push({
|
|
425
|
+
name: check_name || undefined,
|
|
426
|
+
// The check definition has the form: `CHECK ((expr))`
|
|
427
|
+
// The expression starts at 8 and ends at -2
|
|
428
|
+
expression: check_definition.slice(8, -2),
|
|
429
|
+
});
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
if (!checks[key])
|
|
433
|
+
checks[key] = [];
|
|
434
|
+
checks[key].push({
|
|
435
|
+
name: check_name || undefined,
|
|
436
|
+
// The check definition has the form: `CHECK ((expr))`
|
|
437
|
+
// The expression starts at 8 and ends at -2
|
|
438
|
+
expression: check_definition.slice(8, -2),
|
|
439
|
+
});
|
|
440
|
+
});
|
|
370
441
|
return {
|
|
371
442
|
indexes,
|
|
372
443
|
tableConstraints,
|
|
444
|
+
checks,
|
|
373
445
|
};
|
|
374
446
|
};
|
|
375
447
|
const generateRawEnums = async (client, schemas) => {
|
|
@@ -414,7 +486,7 @@ const fetchSchemaJson = async (connection) => {
|
|
|
414
486
|
const { connectionString, schemas } = (0, parseSchema_1.parseConnectionString)(connection, 'jdbc');
|
|
415
487
|
const client = await getValidatedClient(connectionString);
|
|
416
488
|
const tablesAndFieldsRes = generateTablesAndFields(client, schemas);
|
|
417
|
-
const indexesRes =
|
|
489
|
+
const indexesRes = generateIndexesAndConstraints(client, schemas);
|
|
418
490
|
const refsRes = generateRawRefs(client, schemas);
|
|
419
491
|
const enumsRes = generateRawEnums(client, schemas);
|
|
420
492
|
const res = await Promise.all([
|
|
@@ -425,7 +497,7 @@ const fetchSchemaJson = async (connection) => {
|
|
|
425
497
|
]);
|
|
426
498
|
client.end();
|
|
427
499
|
const { tables, fields } = res[0];
|
|
428
|
-
const { indexes, tableConstraints } = res[1];
|
|
500
|
+
const { indexes, tableConstraints, checks } = res[1];
|
|
429
501
|
const refs = res[2];
|
|
430
502
|
const enums = res[3];
|
|
431
503
|
return {
|
|
@@ -435,6 +507,7 @@ const fetchSchemaJson = async (connection) => {
|
|
|
435
507
|
enums,
|
|
436
508
|
indexes,
|
|
437
509
|
tableConstraints,
|
|
510
|
+
checks,
|
|
438
511
|
};
|
|
439
512
|
};
|
|
440
513
|
exports.fetchSchemaJson = fetchSchemaJson;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable camelcase */
|
|
3
2
|
//
|
|
4
3
|
// Description:
|
|
5
4
|
// Snowflake info schema lacks reference direction for relationships.
|
|
@@ -40,7 +39,7 @@ const executeQuery = (connection, sqlText) => {
|
|
|
40
39
|
return new Promise((resolve, reject) => {
|
|
41
40
|
console.log('Executing query...');
|
|
42
41
|
connection.execute({
|
|
43
|
-
sqlText
|
|
42
|
+
sqlText,
|
|
44
43
|
complete: (err, stmt, rows) => {
|
|
45
44
|
if (err) {
|
|
46
45
|
reject(err);
|
|
@@ -51,7 +50,7 @@ const executeQuery = (connection, sqlText) => {
|
|
|
51
50
|
resolve(rows);
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
|
-
}
|
|
53
|
+
},
|
|
55
54
|
});
|
|
56
55
|
});
|
|
57
56
|
};
|
|
@@ -203,14 +202,14 @@ const generateTablesAndFields = async (conn, schemas) => {
|
|
|
203
202
|
};
|
|
204
203
|
const createConstraintKeysMap = (keys, schemas, constraintType) => {
|
|
205
204
|
return keys.reduce((acc, row) => {
|
|
206
|
-
const { schema_name, table_name, column_name, constraint_name } = row;
|
|
205
|
+
const { schema_name, table_name, column_name, constraint_name, } = row;
|
|
207
206
|
const selectedSchema = schemas.length > 0 ? schemas.includes(schema_name) : true;
|
|
208
207
|
if (!selectedSchema) {
|
|
209
208
|
return acc;
|
|
210
209
|
}
|
|
211
210
|
const key = `${schema_name}.${table_name}.${constraint_name}`;
|
|
212
211
|
if (acc[key]) {
|
|
213
|
-
const columnNames = acc[key]
|
|
212
|
+
const { columnNames } = acc[key];
|
|
214
213
|
columnNames.push(column_name);
|
|
215
214
|
return acc;
|
|
216
215
|
}
|
|
@@ -238,13 +237,14 @@ const generateIndexes = async (conn, databaseName, schemas) => {
|
|
|
238
237
|
const uniqueKeysByConstraint = createConstraintKeysMap(uniqueKeys, schemas, 'unique');
|
|
239
238
|
const allConstraints = [Object.values(primaryKeysByConstraint), Object.values(uniqueKeysByConstraint)].flat();
|
|
240
239
|
const { indexes, tableConstraints } = allConstraints.reduce((acc, row) => {
|
|
241
|
-
const { schemaName, tableName, constraintName, columnNames, type, primary, unique } = row;
|
|
240
|
+
const { schemaName, tableName, constraintName, columnNames, type, primary, unique, } = row;
|
|
242
241
|
const key = `${schemaName}.${tableName}`;
|
|
243
242
|
if (columnNames.length < 2) {
|
|
244
243
|
acc.tableConstraints[key] = {
|
|
245
244
|
[columnNames[0]]: {
|
|
246
245
|
pk: primary,
|
|
247
246
|
unique,
|
|
247
|
+
checks: [],
|
|
248
248
|
},
|
|
249
249
|
};
|
|
250
250
|
return acc;
|
|
@@ -304,6 +304,8 @@ const fetchSchemaJson = async (connection) => {
|
|
|
304
304
|
enums: [],
|
|
305
305
|
indexes,
|
|
306
306
|
tableConstraints,
|
|
307
|
+
// Checks are not supported in snowflake
|
|
308
|
+
checks: {},
|
|
307
309
|
};
|
|
308
310
|
};
|
|
309
311
|
exports.fetchSchemaJson = fetchSchemaJson;
|
|
@@ -28,10 +28,18 @@ interface Table {
|
|
|
28
28
|
interface FieldsDictionary {
|
|
29
29
|
[key: string]: Field[];
|
|
30
30
|
}
|
|
31
|
+
interface CheckConstraint {
|
|
32
|
+
name?: string;
|
|
33
|
+
expression: string;
|
|
34
|
+
}
|
|
35
|
+
interface CheckConstraintDictionary {
|
|
36
|
+
[tableName: string]: CheckConstraint[];
|
|
37
|
+
}
|
|
31
38
|
interface TableConstraint {
|
|
32
39
|
[fieldName: string]: {
|
|
33
40
|
pk?: boolean;
|
|
34
41
|
unique?: boolean;
|
|
42
|
+
checks: CheckConstraint[];
|
|
35
43
|
};
|
|
36
44
|
}
|
|
37
45
|
interface TableConstraintsDictionary {
|
|
@@ -78,6 +86,7 @@ interface DatabaseSchema {
|
|
|
78
86
|
tableConstraints: TableConstraintsDictionary;
|
|
79
87
|
refs: Ref[];
|
|
80
88
|
indexes: IndexesDictionary;
|
|
89
|
+
checks: CheckConstraintDictionary;
|
|
81
90
|
}
|
|
82
91
|
interface BigQueryCredentials {
|
|
83
92
|
projectId?: string;
|
|
@@ -87,9 +96,4 @@ interface BigQueryCredentials {
|
|
|
87
96
|
};
|
|
88
97
|
datasets: string[];
|
|
89
98
|
}
|
|
90
|
-
|
|
91
|
-
columns: string[];
|
|
92
|
-
enumValues: EnumValue[];
|
|
93
|
-
constraint_name: string;
|
|
94
|
-
}
|
|
95
|
-
export { NoteInfo, TypeInfo, DefaultType, DefaultInfo, Field, Table, FieldsDictionary, TableConstraint, TableConstraintsDictionary, RefEndpoint, Ref, EnumValue, Enum, IndexColumn, Index, IndexesDictionary, DatabaseSchema, BigQueryCredentials, EnumValuesDict, };
|
|
99
|
+
export { NoteInfo, TypeInfo, DefaultType, DefaultInfo, Field, Table, FieldsDictionary, TableConstraint, TableConstraintsDictionary, RefEndpoint, Ref, EnumValue, Enum, IndexColumn, Index, IndexesDictionary, DatabaseSchema, BigQueryCredentials, CheckConstraintDictionary, };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import * as connector from
|
|
1
|
+
import * as connector from './connectors/connector';
|
|
2
2
|
export { connector, };
|
package/dist/index.js
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
36
|
exports.connector = void 0;
|
|
27
37
|
const connector = __importStar(require("./connectors/connector"));
|
package/dist/utils/helpers.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { FieldsDictionary, IndexesDictionary, Table, TableConstraintsDictionary } from '../connectors/types';
|
|
1
|
+
import { CheckConstraintDictionary, FieldsDictionary, IndexesDictionary, Table, TableConstraintsDictionary } from '../connectors/types';
|
|
2
2
|
export declare function getIntersection<T>(firstList: T[], secondList: T[]): T[];
|
|
3
3
|
export declare function getTableSchemaKey(schemaName: string, tableName: string): string;
|
|
4
4
|
export declare function mergeTables(firstTableList: Table[], secondTable: Table[]): Table[];
|
|
5
5
|
export declare function mergeFieldDictionary(firstDict: FieldsDictionary, secondDict: FieldsDictionary): FieldsDictionary;
|
|
6
6
|
export declare function mergeIndexDictionary(firstDict: IndexesDictionary, secondDict: IndexesDictionary): IndexesDictionary;
|
|
7
7
|
export declare function mergeTableConstraintDictionary(firstDict: TableConstraintsDictionary, secondDict: TableConstraintsDictionary): TableConstraintsDictionary;
|
|
8
|
+
export declare function mergeCheckConstraintDictionary(firstDict: CheckConstraintDictionary, secondDict: CheckConstraintDictionary): CheckConstraintDictionary;
|
package/dist/utils/helpers.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.mergeTables = mergeTables;
|
|
|
6
6
|
exports.mergeFieldDictionary = mergeFieldDictionary;
|
|
7
7
|
exports.mergeIndexDictionary = mergeIndexDictionary;
|
|
8
8
|
exports.mergeTableConstraintDictionary = mergeTableConstraintDictionary;
|
|
9
|
+
exports.mergeCheckConstraintDictionary = mergeCheckConstraintDictionary;
|
|
9
10
|
function getIntersection(firstList, secondList) {
|
|
10
11
|
return firstList.filter((item) => secondList.includes(item));
|
|
11
12
|
}
|
|
@@ -19,7 +20,7 @@ function mergeTables(firstTableList, secondTable) {
|
|
|
19
20
|
return firstTableList.concat(secondTable);
|
|
20
21
|
}
|
|
21
22
|
function mergeFieldDictionary(firstDict, secondDict) {
|
|
22
|
-
const result =
|
|
23
|
+
const result = { ...firstDict };
|
|
23
24
|
Object.keys(secondDict).forEach((key) => {
|
|
24
25
|
if (!result[key]) {
|
|
25
26
|
result[key] = [];
|
|
@@ -29,7 +30,7 @@ function mergeFieldDictionary(firstDict, secondDict) {
|
|
|
29
30
|
return result;
|
|
30
31
|
}
|
|
31
32
|
function mergeIndexDictionary(firstDict, secondDict) {
|
|
32
|
-
const result =
|
|
33
|
+
const result = { ...firstDict };
|
|
33
34
|
Object.keys(secondDict).forEach((key) => {
|
|
34
35
|
if (!result[key]) {
|
|
35
36
|
result[key] = [];
|
|
@@ -39,7 +40,7 @@ function mergeIndexDictionary(firstDict, secondDict) {
|
|
|
39
40
|
return result;
|
|
40
41
|
}
|
|
41
42
|
function mergeTableConstraintDictionary(firstDict, secondDict) {
|
|
42
|
-
const result =
|
|
43
|
+
const result = { ...firstDict };
|
|
43
44
|
Object.keys(secondDict).forEach((key) => {
|
|
44
45
|
if (!result[key]) {
|
|
45
46
|
result[key] = {};
|
|
@@ -48,3 +49,13 @@ function mergeTableConstraintDictionary(firstDict, secondDict) {
|
|
|
48
49
|
});
|
|
49
50
|
return result;
|
|
50
51
|
}
|
|
52
|
+
function mergeCheckConstraintDictionary(firstDict, secondDict) {
|
|
53
|
+
const result = { ...firstDict };
|
|
54
|
+
Object.keys(secondDict).forEach((key) => {
|
|
55
|
+
if (!result[key]) {
|
|
56
|
+
result[key] = [];
|
|
57
|
+
}
|
|
58
|
+
result[key] = result[key].concat(secondDict[key]);
|
|
59
|
+
});
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const parseSchema: (schemas: string | undefined) => string[];
|
|
1
2
|
export declare const parseJdbcSchema: (connectionString: string) => {
|
|
2
3
|
connectionString: string;
|
|
3
4
|
schemas: string[];
|
|
@@ -7,4 +8,3 @@ export declare const parseConnectionString: (connectionString: string, connectio
|
|
|
7
8
|
schemas: string[];
|
|
8
9
|
};
|
|
9
10
|
export declare const buildSchemaQuery: (columnName: string, schemas: string[], prefix?: string) => string;
|
|
10
|
-
export declare const parseSchema: (schemas: string | undefined) => string[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.buildSchemaQuery = exports.parseConnectionString = exports.parseJdbcSchema = exports.parseSchema = void 0;
|
|
4
4
|
// You cannot use the "=" inside database's schema name. It will be treated as a delimiter.
|
|
5
5
|
const SCHEMAS_DELIMITER = 'schemas=';
|
|
6
6
|
const haveSchemas = (str) => {
|
|
@@ -13,6 +13,18 @@ const noSchemaResult = (connectionString) => ({
|
|
|
13
13
|
connectionString,
|
|
14
14
|
schemas: [],
|
|
15
15
|
});
|
|
16
|
+
// Inputs: schemas string -> Output: schema array string[]
|
|
17
|
+
// schema1, schema2 -> ['schema1', 'schema2']
|
|
18
|
+
// schema3,schema4 -> ['schema3", 'schema4']
|
|
19
|
+
// "schema5,gg", "schema6", schema7 -> ['schema5,gg', 'schema6', 'schema7']
|
|
20
|
+
// schema8 -> ['schema8']
|
|
21
|
+
const parseSchema = (schemas) => {
|
|
22
|
+
if (!schemas)
|
|
23
|
+
return [];
|
|
24
|
+
const schemasWithDoubleQuotes = schemas.split(/,(?=(?:[^"]*(?:"[^"]*")*)*$)/).map((s) => s.trim());
|
|
25
|
+
return schemasWithDoubleQuotes.map((s) => s.replace(/"/g, ''));
|
|
26
|
+
};
|
|
27
|
+
exports.parseSchema = parseSchema;
|
|
16
28
|
const parseOdbcSchema = (connectionString) => {
|
|
17
29
|
const connectionParts = connectionString.split(';');
|
|
18
30
|
const schemasPart = connectionParts.find((part) => haveSchemas(part));
|
|
@@ -45,15 +57,3 @@ const buildSchemaQuery = (columnName, schemas, prefix = 'AND') => {
|
|
|
45
57
|
return `${prefix} ${columnName} IN (${schemas.map((schema) => `'${schema}'`).join(', ')})`;
|
|
46
58
|
};
|
|
47
59
|
exports.buildSchemaQuery = buildSchemaQuery;
|
|
48
|
-
// Inputs: schemas string -> Output: schema array string[]
|
|
49
|
-
// schema1, schema2 -> ['schema1', 'schema2']
|
|
50
|
-
// schema3,schema4 -> ['schema3", 'schema4']
|
|
51
|
-
// "schema5,gg", "schema6", schema7 -> ['schema5,gg', 'schema6', 'schema7']
|
|
52
|
-
// schema8 -> ['schema8']
|
|
53
|
-
const parseSchema = (schemas) => {
|
|
54
|
-
if (!schemas)
|
|
55
|
-
return [];
|
|
56
|
-
const schemasWithDoubleQuotes = schemas.split(/,(?=(?:[^"]*(?:"[^"]*")*)*$)/).map((s) => s.trim());
|
|
57
|
-
return schemasWithDoubleQuotes.map((s) => s.replace(/"/g, ''));
|
|
58
|
-
};
|
|
59
|
-
exports.parseSchema = parseSchema;
|
package/eslint.config.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import eslint from '@eslint/js';
|
|
2
|
+
import { defineConfig } from 'eslint/config';
|
|
3
|
+
import tseslint from 'typescript-eslint';
|
|
4
|
+
import tsparser from '@typescript-eslint/parser';
|
|
5
|
+
import stylistic from '@stylistic/eslint-plugin';
|
|
6
|
+
|
|
7
|
+
export default defineConfig(
|
|
8
|
+
eslint.configs.recommended,
|
|
9
|
+
tseslint.configs.recommended,
|
|
10
|
+
stylistic.configs.customize({
|
|
11
|
+
indent: 2,
|
|
12
|
+
semi: true,
|
|
13
|
+
arrowParens: true,
|
|
14
|
+
braceStyle: '1tbs',
|
|
15
|
+
}),
|
|
16
|
+
[
|
|
17
|
+
{
|
|
18
|
+
ignores: [
|
|
19
|
+
'node_modules/*',
|
|
20
|
+
'dist/*',
|
|
21
|
+
'eslint.config.ts',
|
|
22
|
+
'jestHelpers.ts',
|
|
23
|
+
'jest.config.ts',
|
|
24
|
+
'**/*.test.ts',
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
files: ['**/*.ts'],
|
|
29
|
+
languageOptions: {
|
|
30
|
+
parser: tsparser,
|
|
31
|
+
parserOptions: {
|
|
32
|
+
sourceType: 'module',
|
|
33
|
+
ecmaVersion: 2020,
|
|
34
|
+
project: './tsconfig.json',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
plugins: {
|
|
38
|
+
'@stylistic': stylistic,
|
|
39
|
+
},
|
|
40
|
+
rules: {
|
|
41
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
42
|
+
'no-use-before-define': 'off',
|
|
43
|
+
'no-continue': 'off',
|
|
44
|
+
'no-useless-escape': 'warn',
|
|
45
|
+
'@stylistic/space-before-function-paren': ['error', 'always'],
|
|
46
|
+
'@typescript-eslint/no-unused-vars': [
|
|
47
|
+
'warn',
|
|
48
|
+
{
|
|
49
|
+
argsIgnorePattern: '^_',
|
|
50
|
+
varsIgnorePattern: '^_',
|
|
51
|
+
caughtErrorsIgnorePattern: '^_',
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
'consistent-return': 'off',
|
|
55
|
+
'@typescript-eslint/consistent-return': ['error'],
|
|
56
|
+
'@stylistic/quotes': ['error', 'single', { 'avoidEscape': true }],
|
|
57
|
+
'@stylistic/max-statements-per-line': 'off',
|
|
58
|
+
'@stylistic/operator-linebreak': ['error', 'before', { overrides: { '=': 'after' } }],
|
|
59
|
+
},
|
|
60
|
+
settings: {
|
|
61
|
+
'import/resolver': {
|
|
62
|
+
typescript: {
|
|
63
|
+
alwaysTryTypes: true,
|
|
64
|
+
project: 'packages/*/{ts,js}config.json',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
);
|
package/jest.config.ts
CHANGED
|
@@ -2,9 +2,9 @@ module.exports = {
|
|
|
2
2
|
preset: 'ts-jest',
|
|
3
3
|
testEnvironment: 'node',
|
|
4
4
|
transform: {
|
|
5
|
-
|
|
5
|
+
'^.+\\.[tj]sx?$': 'babel-jest',
|
|
6
6
|
},
|
|
7
7
|
moduleNameMapper: {
|
|
8
|
-
|
|
8
|
+
'\\.(css|less|scss)$': 'identity-obj-proxy',
|
|
9
9
|
},
|
|
10
10
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package",
|
|
2
3
|
"name": "@dbml/connector",
|
|
3
|
-
"version": "5.
|
|
4
|
+
"version": "5.2.0",
|
|
4
5
|
"description": "This package was created to fetch the schema JSON from many kind of databases.",
|
|
5
6
|
"author": "huy.phung.sw@gmail.com",
|
|
6
7
|
"license": "MIT",
|
|
@@ -15,26 +16,34 @@
|
|
|
15
16
|
"@babel/preset-env": "^7.21.4",
|
|
16
17
|
"@babel/preset-typescript": "^7.24.7",
|
|
17
18
|
"@babel/runtime": "^7.21.0",
|
|
19
|
+
"@stylistic/eslint-plugin": "^5.5.0",
|
|
18
20
|
"@types/jest": "^29.5.12",
|
|
19
21
|
"@types/lodash": "^4.17.16",
|
|
20
22
|
"@types/mssql": "^9.1.5",
|
|
21
23
|
"@types/node": "^22.2.0",
|
|
22
24
|
"@types/pg": "^8.11.6",
|
|
25
|
+
"@typescript-eslint/eslint-plugin": "^8.46.3",
|
|
26
|
+
"@typescript-eslint/parser": "^8.46.3",
|
|
23
27
|
"babel-jest": "^29.5.0",
|
|
28
|
+
"eslint": "^9.39.1",
|
|
24
29
|
"jest": "^29.7.0",
|
|
25
30
|
"ts-jest": "^29.2.4",
|
|
26
31
|
"ts-node": "^10.9.2",
|
|
27
|
-
"typescript": "^5.
|
|
32
|
+
"typescript": "^5.9.3",
|
|
33
|
+
"typescript-eslint": "^8.46.3"
|
|
28
34
|
},
|
|
29
35
|
"scripts": {
|
|
30
36
|
"build": "tsc",
|
|
31
37
|
"start": "node dist/index.js",
|
|
32
|
-
"test": "jest"
|
|
38
|
+
"test": "jest",
|
|
39
|
+
"lint": "eslint .",
|
|
40
|
+
"lint:fix": "eslint --fix ."
|
|
33
41
|
},
|
|
34
42
|
"dependencies": {
|
|
35
43
|
"@google-cloud/bigquery": "^7.9.0",
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
37
|
-
"@typescript-eslint/parser": "^8.
|
|
44
|
+
"@typescript-eslint/eslint-plugin": "^8.46.3",
|
|
45
|
+
"@typescript-eslint/parser": "^8.46.3",
|
|
46
|
+
"eslint": "^9.39.1",
|
|
38
47
|
"lodash": "^4.17.21",
|
|
39
48
|
"mssql": "^11.0.1",
|
|
40
49
|
"mysql2": "^3.11.0",
|
|
@@ -44,5 +53,5 @@
|
|
|
44
53
|
"engines": {
|
|
45
54
|
"node": ">=18"
|
|
46
55
|
},
|
|
47
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "20d556a6e6baad8a989c730e2afd3b65dedcea89"
|
|
48
57
|
}
|