@dbml/connector 5.2.0 → 5.3.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__/connector.test.ts +1 -1
- package/__tests__/connectors/mssql/out-files/schema.json +97 -6
- package/__tests__/connectors/mysql/expect-out-files/schema.json +1 -1
- package/__tests__/connectors/mysql/out-files/schema.json +92 -2
- package/__tests__/connectors/oracle/connection.json +4 -0
- package/__tests__/connectors/oracle/expect-out-files/schema.json +3866 -0
- package/__tests__/connectors/oracle/out-files/schema.json +3866 -0
- package/__tests__/connectors/postgres/out-files/schema.json +119 -8
- package/dist/connectors/{bigqueryConnector.d.ts → bigquery/index.d.ts} +1 -1
- package/dist/connectors/{bigqueryConnector.js → bigquery/index.js} +2 -2
- package/dist/connectors/connector.js +13 -10
- package/dist/connectors/{snowflakeConnector.d.ts → mssql/index.d.ts} +1 -1
- package/dist/connectors/{mssqlConnector.js → mssql/index.js} +1 -1
- package/dist/connectors/{mysqlConnector.d.ts → mysql/index.d.ts} +1 -1
- package/dist/connectors/oracle/constraints.d.ts +7 -0
- package/dist/connectors/oracle/constraints.js +112 -0
- package/dist/connectors/oracle/index.d.ts +3 -0
- package/dist/connectors/oracle/index.js +68 -0
- package/dist/connectors/oracle/indexes.d.ts +3 -0
- package/dist/connectors/oracle/indexes.js +65 -0
- package/dist/connectors/oracle/refs.d.ts +3 -0
- package/dist/connectors/oracle/refs.js +67 -0
- package/dist/connectors/oracle/tables.d.ts +7 -0
- package/dist/connectors/oracle/tables.js +280 -0
- package/dist/connectors/oracle/utils.d.ts +9 -0
- package/dist/connectors/oracle/utils.js +27 -0
- package/dist/connectors/{mssqlConnector.d.ts → postgres/index.d.ts} +1 -1
- package/dist/connectors/{postgresConnector.js → postgres/index.js} +1 -1
- package/dist/connectors/{postgresConnector.d.ts → snowflake/index.d.ts} +1 -1
- package/dist/connectors/{snowflakeConnector.js → snowflake/index.js} +1 -1
- package/dist/connectors/types.d.ts +1 -1
- package/package.json +4 -2
- package/src/connectors/{bigqueryConnector.ts → bigquery/index.ts} +3 -3
- package/src/connectors/connector.ts +8 -5
- package/src/connectors/{mssqlConnector.ts → mssql/index.ts} +2 -2
- package/src/connectors/{mysqlConnector.ts → mysql/index.ts} +1 -1
- package/src/connectors/oracle/constraints.ts +113 -0
- package/src/connectors/oracle/index.ts +76 -0
- package/src/connectors/oracle/indexes.ts +71 -0
- package/src/connectors/oracle/refs.ts +73 -0
- package/src/connectors/oracle/tables.ts +305 -0
- package/src/connectors/oracle/utils.ts +23 -0
- package/src/connectors/{postgresConnector.ts → postgres/index.ts} +2 -2
- package/src/connectors/{snowflakeConnector.ts → snowflake/index.ts} +2 -2
- package/src/connectors/types.ts +1 -0
- package/test-output.log +0 -18
- /package/dist/connectors/{mysqlConnector.js → mysql/index.js} +0 -0
|
@@ -97,6 +97,13 @@
|
|
|
97
97
|
"note": {
|
|
98
98
|
"value": ""
|
|
99
99
|
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "table_with_composite_primary_and_unique_indexes",
|
|
103
|
+
"schemaName": "public",
|
|
104
|
+
"note": {
|
|
105
|
+
"value": ""
|
|
106
|
+
}
|
|
100
107
|
}
|
|
101
108
|
],
|
|
102
109
|
"fields": {
|
|
@@ -1270,6 +1277,60 @@
|
|
|
1270
1277
|
"value": ""
|
|
1271
1278
|
}
|
|
1272
1279
|
}
|
|
1280
|
+
],
|
|
1281
|
+
"public.table_with_composite_primary_and_unique_indexes": [
|
|
1282
|
+
{
|
|
1283
|
+
"name": "col1",
|
|
1284
|
+
"type": {
|
|
1285
|
+
"type_name": "int4",
|
|
1286
|
+
"schemaName": null
|
|
1287
|
+
},
|
|
1288
|
+
"dbdefault": null,
|
|
1289
|
+
"not_null": true,
|
|
1290
|
+
"increment": false,
|
|
1291
|
+
"note": {
|
|
1292
|
+
"value": ""
|
|
1293
|
+
}
|
|
1294
|
+
},
|
|
1295
|
+
{
|
|
1296
|
+
"name": "col2",
|
|
1297
|
+
"type": {
|
|
1298
|
+
"type_name": "int4",
|
|
1299
|
+
"schemaName": null
|
|
1300
|
+
},
|
|
1301
|
+
"dbdefault": null,
|
|
1302
|
+
"not_null": true,
|
|
1303
|
+
"increment": false,
|
|
1304
|
+
"note": {
|
|
1305
|
+
"value": ""
|
|
1306
|
+
}
|
|
1307
|
+
},
|
|
1308
|
+
{
|
|
1309
|
+
"name": "col3",
|
|
1310
|
+
"type": {
|
|
1311
|
+
"type_name": "int4",
|
|
1312
|
+
"schemaName": null
|
|
1313
|
+
},
|
|
1314
|
+
"dbdefault": null,
|
|
1315
|
+
"not_null": false,
|
|
1316
|
+
"increment": false,
|
|
1317
|
+
"note": {
|
|
1318
|
+
"value": ""
|
|
1319
|
+
}
|
|
1320
|
+
},
|
|
1321
|
+
{
|
|
1322
|
+
"name": "col4",
|
|
1323
|
+
"type": {
|
|
1324
|
+
"type_name": "int4",
|
|
1325
|
+
"schemaName": null
|
|
1326
|
+
},
|
|
1327
|
+
"dbdefault": null,
|
|
1328
|
+
"not_null": false,
|
|
1329
|
+
"increment": false,
|
|
1330
|
+
"note": {
|
|
1331
|
+
"value": ""
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1273
1334
|
]
|
|
1274
1335
|
},
|
|
1275
1336
|
"refs": [
|
|
@@ -1447,7 +1508,9 @@
|
|
|
1447
1508
|
"type": "column",
|
|
1448
1509
|
"value": "nationalityid"
|
|
1449
1510
|
}
|
|
1450
|
-
]
|
|
1511
|
+
],
|
|
1512
|
+
"pk": true,
|
|
1513
|
+
"unique": false
|
|
1451
1514
|
}
|
|
1452
1515
|
],
|
|
1453
1516
|
"public.order_items": [
|
|
@@ -1463,7 +1526,9 @@
|
|
|
1463
1526
|
"type": "column",
|
|
1464
1527
|
"value": "product_id"
|
|
1465
1528
|
}
|
|
1466
|
-
]
|
|
1529
|
+
],
|
|
1530
|
+
"pk": false,
|
|
1531
|
+
"unique": true
|
|
1467
1532
|
},
|
|
1468
1533
|
{
|
|
1469
1534
|
"name": "idx_order_items_order_product",
|
|
@@ -1477,7 +1542,9 @@
|
|
|
1477
1542
|
"type": "column",
|
|
1478
1543
|
"value": "product_id"
|
|
1479
1544
|
}
|
|
1480
|
-
]
|
|
1545
|
+
],
|
|
1546
|
+
"pk": false,
|
|
1547
|
+
"unique": false
|
|
1481
1548
|
}
|
|
1482
1549
|
],
|
|
1483
1550
|
"public.orders": [
|
|
@@ -1493,7 +1560,9 @@
|
|
|
1493
1560
|
"type": "column",
|
|
1494
1561
|
"value": "order_date"
|
|
1495
1562
|
}
|
|
1496
|
-
]
|
|
1563
|
+
],
|
|
1564
|
+
"pk": false,
|
|
1565
|
+
"unique": false
|
|
1497
1566
|
}
|
|
1498
1567
|
],
|
|
1499
1568
|
"public.products": [
|
|
@@ -1505,7 +1574,43 @@
|
|
|
1505
1574
|
"type": "column",
|
|
1506
1575
|
"value": "category"
|
|
1507
1576
|
}
|
|
1508
|
-
]
|
|
1577
|
+
],
|
|
1578
|
+
"pk": false,
|
|
1579
|
+
"unique": false
|
|
1580
|
+
}
|
|
1581
|
+
],
|
|
1582
|
+
"public.table_with_composite_primary_and_unique_indexes": [
|
|
1583
|
+
{
|
|
1584
|
+
"name": "table_with_composite_primary_and_unique_indexes_pkey",
|
|
1585
|
+
"type": "btree",
|
|
1586
|
+
"columns": [
|
|
1587
|
+
{
|
|
1588
|
+
"type": "column",
|
|
1589
|
+
"value": "col1"
|
|
1590
|
+
},
|
|
1591
|
+
{
|
|
1592
|
+
"type": "column",
|
|
1593
|
+
"value": "col2"
|
|
1594
|
+
}
|
|
1595
|
+
],
|
|
1596
|
+
"pk": true,
|
|
1597
|
+
"unique": false
|
|
1598
|
+
},
|
|
1599
|
+
{
|
|
1600
|
+
"name": "table_with_composite_primary_and_unique_indexes_col3_col4_key",
|
|
1601
|
+
"type": "btree",
|
|
1602
|
+
"columns": [
|
|
1603
|
+
{
|
|
1604
|
+
"type": "column",
|
|
1605
|
+
"value": "col3"
|
|
1606
|
+
},
|
|
1607
|
+
{
|
|
1608
|
+
"type": "column",
|
|
1609
|
+
"value": "col4"
|
|
1610
|
+
}
|
|
1611
|
+
],
|
|
1612
|
+
"pk": false,
|
|
1613
|
+
"unique": true
|
|
1509
1614
|
}
|
|
1510
1615
|
],
|
|
1511
1616
|
"public.users": [
|
|
@@ -1517,7 +1622,9 @@
|
|
|
1517
1622
|
"type": "column",
|
|
1518
1623
|
"value": "full_name"
|
|
1519
1624
|
}
|
|
1520
|
-
]
|
|
1625
|
+
],
|
|
1626
|
+
"pk": false,
|
|
1627
|
+
"unique": false
|
|
1521
1628
|
},
|
|
1522
1629
|
{
|
|
1523
1630
|
"name": "idx_users_email",
|
|
@@ -1527,7 +1634,9 @@
|
|
|
1527
1634
|
"type": "column",
|
|
1528
1635
|
"value": "email"
|
|
1529
1636
|
}
|
|
1530
|
-
]
|
|
1637
|
+
],
|
|
1638
|
+
"pk": false,
|
|
1639
|
+
"unique": false
|
|
1531
1640
|
},
|
|
1532
1641
|
{
|
|
1533
1642
|
"name": "users_is_active_lower_idx",
|
|
@@ -1541,7 +1650,9 @@
|
|
|
1541
1650
|
"type": "expression",
|
|
1542
1651
|
"value": "lower((full_name)::text)"
|
|
1543
1652
|
}
|
|
1544
|
-
]
|
|
1653
|
+
],
|
|
1654
|
+
"pk": false,
|
|
1655
|
+
"unique": false
|
|
1545
1656
|
}
|
|
1546
1657
|
]
|
|
1547
1658
|
},
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.fetchSchemaJson = fetchSchemaJson;
|
|
4
4
|
const bigquery_1 = require("@google-cloud/bigquery");
|
|
5
|
-
const credential_loader_1 = require("
|
|
6
|
-
const helpers_1 = require("
|
|
5
|
+
const credential_loader_1 = require("../../utils/credential-loader");
|
|
6
|
+
const helpers_1 = require("../../utils/helpers");
|
|
7
7
|
// BigQuery client authentication strategy:
|
|
8
8
|
// 1. Start with environment/default authentication:
|
|
9
9
|
// - GOOGLE_APPLICATION_CREDENTIALS env variable (service account key file)
|
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.fetchSchemaJson = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
4
|
+
const postgres_1 = require("./postgres");
|
|
5
|
+
const mssql_1 = require("./mssql");
|
|
6
|
+
const mysql_1 = require("./mysql");
|
|
7
|
+
const snowflake_1 = require("./snowflake");
|
|
8
|
+
const bigquery_1 = require("./bigquery");
|
|
9
|
+
const oracle_1 = require("./oracle");
|
|
9
10
|
const fetchSchemaJson = async (connection, databaseType) => {
|
|
10
11
|
switch (databaseType) {
|
|
11
12
|
case 'postgres':
|
|
12
|
-
return (0,
|
|
13
|
+
return (0, postgres_1.fetchSchemaJson)(connection);
|
|
13
14
|
case 'mssql':
|
|
14
|
-
return (0,
|
|
15
|
+
return (0, mssql_1.fetchSchemaJson)(connection);
|
|
15
16
|
case 'mysql':
|
|
16
|
-
return (0,
|
|
17
|
+
return (0, mysql_1.fetchSchemaJson)(connection);
|
|
17
18
|
case 'snowflake':
|
|
18
|
-
return (0,
|
|
19
|
+
return (0, snowflake_1.fetchSchemaJson)(connection);
|
|
19
20
|
case 'bigquery':
|
|
20
|
-
return (0,
|
|
21
|
+
return (0, bigquery_1.fetchSchemaJson)(connection);
|
|
22
|
+
case 'oracle':
|
|
23
|
+
return (0, oracle_1.fetchSchemaJson)(connection);
|
|
21
24
|
default:
|
|
22
25
|
throw new Error(`Unsupported database type: ${databaseType}`);
|
|
23
26
|
}
|
|
@@ -10,7 +10,7 @@ exports.fetchSchemaJson = void 0;
|
|
|
10
10
|
* - Since DBML 4.0.0, we have supported CHECK constraints, so we no longer extract ENUMS out from CHECK constraints but rather keep them as CHECK constraints.
|
|
11
11
|
* */
|
|
12
12
|
const mssql_1 = __importDefault(require("mssql"));
|
|
13
|
-
const parseSchema_1 = require("
|
|
13
|
+
const parseSchema_1 = require("../../utils/parseSchema");
|
|
14
14
|
// https://learn.microsoft.com/en-us/sql/t-sql/data-types/date-and-time-types?view=sql-server-ver15
|
|
15
15
|
const MSSQL_DATE_TYPES = [
|
|
16
16
|
'date',
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Connection } from 'oracledb';
|
|
2
|
+
import { CheckConstraintDictionary, IndexesDictionary, TableConstraintsDictionary } from '../types';
|
|
3
|
+
export declare function generateConstraints(client: Connection): Promise<{
|
|
4
|
+
indexes: IndexesDictionary;
|
|
5
|
+
tableConstraints: TableConstraintsDictionary;
|
|
6
|
+
checks: CheckConstraintDictionary;
|
|
7
|
+
}>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateConstraints = generateConstraints;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
async function generateConstraints(client) {
|
|
6
|
+
const query = `
|
|
7
|
+
WITH all_constraints AS (
|
|
8
|
+
SELECT
|
|
9
|
+
c.CONSTRAINT_NAME,
|
|
10
|
+
c.TABLE_NAME,
|
|
11
|
+
c.CONSTRAINT_TYPE,
|
|
12
|
+
c.SEARCH_CONDITION_VC AS CHECK_EXPRESSION
|
|
13
|
+
FROM USER_CONSTRAINTS c
|
|
14
|
+
WHERE c.CONSTRAINT_TYPE IN ('P', 'U', 'C') -- P stands for primary key, U stands for unique and C stands for check
|
|
15
|
+
AND (c.CONSTRAINT_TYPE != 'C' OR UPPER(c.SEARCH_CONDITION_VC) NOT LIKE '%IS NOT NULL')
|
|
16
|
+
),
|
|
17
|
+
constraint_columns AS (
|
|
18
|
+
SELECT
|
|
19
|
+
cc.CONSTRAINT_NAME,
|
|
20
|
+
LISTAGG(cc.COLUMN_NAME, '${utils_1.LIST_SEPARATOR}') WITHIN GROUP (ORDER BY cc.POSITION) AS COLUMNS,
|
|
21
|
+
COUNT(cc.COLUMN_NAME) AS COLUMN_COUNT
|
|
22
|
+
FROM USER_CONS_COLUMNS cc
|
|
23
|
+
GROUP BY cc.CONSTRAINT_NAME
|
|
24
|
+
)
|
|
25
|
+
SELECT
|
|
26
|
+
ac.CONSTRAINT_NAME AS "constraint_name",
|
|
27
|
+
ac.TABLE_NAME AS "table_name",
|
|
28
|
+
cc.COLUMNS AS "columns",
|
|
29
|
+
cc.COLUMN_COUNT AS "column_count",
|
|
30
|
+
ac.CHECK_EXPRESSION AS "check_expression",
|
|
31
|
+
ac.CONSTRAINT_TYPE AS "constraint_type"
|
|
32
|
+
FROM all_constraints ac
|
|
33
|
+
LEFT JOIN constraint_columns cc
|
|
34
|
+
ON ac.CONSTRAINT_NAME = cc.CONSTRAINT_NAME
|
|
35
|
+
LEFT JOIN USER_OBJECTS obj
|
|
36
|
+
ON obj.OBJECT_NAME = ac.TABLE_NAME
|
|
37
|
+
AND obj.OBJECT_TYPE = 'TABLE'
|
|
38
|
+
ORDER BY
|
|
39
|
+
obj.CREATED,
|
|
40
|
+
obj.OBJECT_ID,
|
|
41
|
+
ac.CONSTRAINT_NAME
|
|
42
|
+
`;
|
|
43
|
+
const indexes = {};
|
|
44
|
+
const tableConstraints = {};
|
|
45
|
+
const checks = {};
|
|
46
|
+
const res = await client.execute(query, [], utils_1.EXECUTE_OPTIONS);
|
|
47
|
+
res.rows?.forEach((row) => {
|
|
48
|
+
const { constraint_name, table_name, columns: columnsStr, column_count, check_expression, constraint_type } = row;
|
|
49
|
+
const tableName = table_name;
|
|
50
|
+
const constraintName = constraint_name || '';
|
|
51
|
+
const columns = (columnsStr || '').split(utils_1.LIST_SEPARATOR);
|
|
52
|
+
const columnCount = column_count || 1;
|
|
53
|
+
const constraintType = constraint_type;
|
|
54
|
+
const checkExpression = (check_expression || null);
|
|
55
|
+
// Table-level check constraints
|
|
56
|
+
if (constraintType === 'C' && checkExpression && columnCount > 1) {
|
|
57
|
+
if (!checks[tableName])
|
|
58
|
+
checks[tableName] = [];
|
|
59
|
+
const check = {
|
|
60
|
+
name: constraintName,
|
|
61
|
+
expression: checkExpression,
|
|
62
|
+
};
|
|
63
|
+
checks[tableName].push(check);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// Column-level check constraints
|
|
67
|
+
if (constraintType === 'C' && checkExpression && columnCount === 1 && columns.length === 1) {
|
|
68
|
+
if (!tableConstraints[tableName])
|
|
69
|
+
tableConstraints[tableName] = {};
|
|
70
|
+
const column = columns[0];
|
|
71
|
+
if (!tableConstraints[tableName][column])
|
|
72
|
+
tableConstraints[tableName][column] = { checks: [] };
|
|
73
|
+
tableConstraints[tableName][column].checks.push({
|
|
74
|
+
name: constraintName,
|
|
75
|
+
expression: checkExpression,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// Column-level unique or primary indexes
|
|
79
|
+
if (['P', 'U'].includes(constraintType) && columnCount === 1 && columns.length === 1) {
|
|
80
|
+
if (!tableConstraints[tableName])
|
|
81
|
+
tableConstraints[tableName] = {};
|
|
82
|
+
const column = columns[0];
|
|
83
|
+
if (!tableConstraints[tableName][column])
|
|
84
|
+
tableConstraints[tableName][column] = { checks: [] };
|
|
85
|
+
tableConstraints[tableName][column].pk ||= constraintType === 'P';
|
|
86
|
+
tableConstraints[tableName][column].unique ||= constraintType === 'U';
|
|
87
|
+
}
|
|
88
|
+
// Table-level unique or primary indexes
|
|
89
|
+
if (['P', 'U'].includes(constraintType) && columnCount > 1) {
|
|
90
|
+
if (!tableConstraints[tableName])
|
|
91
|
+
tableConstraints[tableName] = {};
|
|
92
|
+
if (!indexes[tableName])
|
|
93
|
+
indexes[tableName] = [];
|
|
94
|
+
const index = {
|
|
95
|
+
name: constraintName,
|
|
96
|
+
type: '',
|
|
97
|
+
unique: true,
|
|
98
|
+
pk: constraintType === 'P',
|
|
99
|
+
columns: columns.map((c) => ({
|
|
100
|
+
type: 'column',
|
|
101
|
+
value: c,
|
|
102
|
+
})),
|
|
103
|
+
};
|
|
104
|
+
indexes[tableName].push(index);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
indexes,
|
|
109
|
+
tableConstraints,
|
|
110
|
+
checks,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchSchemaJson = fetchSchemaJson;
|
|
4
|
+
const oracledb_1 = require("oracledb");
|
|
5
|
+
const tables_1 = require("./tables");
|
|
6
|
+
const refs_1 = require("./refs");
|
|
7
|
+
const constraints_1 = require("./constraints");
|
|
8
|
+
const indexes_1 = require("./indexes");
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
const getValidatedClient = async (username, password, dbidentifier) => {
|
|
11
|
+
const client = await (0, oracledb_1.getConnection)({
|
|
12
|
+
username,
|
|
13
|
+
password,
|
|
14
|
+
connectionString: dbidentifier,
|
|
15
|
+
});
|
|
16
|
+
try {
|
|
17
|
+
await client.execute('SELECT 1 FROM DUAL');
|
|
18
|
+
return client;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
await client.close();
|
|
22
|
+
if (error instanceof Error) {
|
|
23
|
+
throw new Error(`OracleSQL connection error: ${error.message}`);
|
|
24
|
+
}
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
// Expect an Easy Connect string format: username/password@[//]host[:port][/database]
|
|
29
|
+
// `username` and `password` are mandatory
|
|
30
|
+
// `port` and `database` (and the parts enclosed in `[]`) are optional
|
|
31
|
+
// Explanation of the format: https://www.orafaq.com/wiki/EZCONNECT
|
|
32
|
+
async function fetchSchemaJson(connection) {
|
|
33
|
+
const { username, password, dbidentifier } = (0, utils_1.processEasyConnectString)(connection);
|
|
34
|
+
const client = await getValidatedClient(username, password, dbidentifier);
|
|
35
|
+
const tablesAndFieldsRes = (0, tables_1.generateTablesAndFields)(client);
|
|
36
|
+
const constraintsRes = (0, constraints_1.generateConstraints)(client);
|
|
37
|
+
const refsRes = (0, refs_1.generateRawRefs)(client);
|
|
38
|
+
const indexesRes = (0, indexes_1.generateIndexes)(client);
|
|
39
|
+
const res = await Promise.all([
|
|
40
|
+
tablesAndFieldsRes,
|
|
41
|
+
constraintsRes,
|
|
42
|
+
refsRes,
|
|
43
|
+
indexesRes,
|
|
44
|
+
]);
|
|
45
|
+
const { tables, fields } = res[0];
|
|
46
|
+
const { indexes: uniqueIndexes, tableConstraints, checks } = res[1];
|
|
47
|
+
const refs = res[2];
|
|
48
|
+
const indexes = res[3];
|
|
49
|
+
Object.keys(uniqueIndexes).forEach((key) => {
|
|
50
|
+
if (!indexes[key])
|
|
51
|
+
indexes[key] = uniqueIndexes[key];
|
|
52
|
+
else
|
|
53
|
+
indexes[key].push(...uniqueIndexes[key]);
|
|
54
|
+
});
|
|
55
|
+
await client.close();
|
|
56
|
+
return {
|
|
57
|
+
tables,
|
|
58
|
+
fields,
|
|
59
|
+
refs,
|
|
60
|
+
// As of oracle 19c, there's no native ENUM data type
|
|
61
|
+
// ENUM is introduced in oracle 23ai
|
|
62
|
+
enums: [],
|
|
63
|
+
indexes,
|
|
64
|
+
tableConstraints,
|
|
65
|
+
checks,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateIndexes = generateIndexes;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
async function generateIndexes(client) {
|
|
6
|
+
const query = `
|
|
7
|
+
SELECT
|
|
8
|
+
i.INDEX_NAME AS "index_name",
|
|
9
|
+
i.TABLE_NAME AS "table_name",
|
|
10
|
+
CASE
|
|
11
|
+
WHEN i.INDEX_TYPE LIKE '%NORMAL' THEN 'btree'
|
|
12
|
+
ELSE LOWER(REGEXP_REPLACE(i.INDEX_TYPE, '^FUNCTION-BASED ', ''))
|
|
13
|
+
END AS "index_type",
|
|
14
|
+
CASE WHEN i.UNIQUENESS = 'UNIQUE' THEN 1 ELSE 0 END AS "is_unique",
|
|
15
|
+
ic.COLUMN_NAME AS "column_name",
|
|
16
|
+
ic.COLUMN_POSITION AS "column_position",
|
|
17
|
+
ie.COLUMN_EXPRESSION AS "column_expression"
|
|
18
|
+
FROM USER_INDEXES i
|
|
19
|
+
LEFT JOIN USER_IND_COLUMNS ic
|
|
20
|
+
ON i.INDEX_NAME = ic.INDEX_NAME
|
|
21
|
+
LEFT JOIN USER_IND_EXPRESSIONS ie
|
|
22
|
+
ON i.INDEX_NAME = ie.INDEX_NAME
|
|
23
|
+
AND ic.COLUMN_POSITION = ie.COLUMN_POSITION
|
|
24
|
+
LEFT JOIN USER_OBJECTS obj
|
|
25
|
+
ON obj.OBJECT_NAME = i.TABLE_NAME
|
|
26
|
+
AND obj.OBJECT_TYPE = 'TABLE'
|
|
27
|
+
WHERE NOT EXISTS (
|
|
28
|
+
SELECT 1
|
|
29
|
+
FROM USER_CONSTRAINTS c
|
|
30
|
+
WHERE c.INDEX_NAME = i.INDEX_NAME
|
|
31
|
+
)
|
|
32
|
+
ORDER BY obj.CREATED, obj.OBJECT_ID, i.INDEX_NAME, ic.COLUMN_POSITION
|
|
33
|
+
`;
|
|
34
|
+
const res = await client.execute(query, [], utils_1.EXECUTE_OPTIONS);
|
|
35
|
+
const indexes = {};
|
|
36
|
+
const indexMap = {};
|
|
37
|
+
res.rows?.forEach((row) => {
|
|
38
|
+
const { index_name, table_name, index_type, is_unique, column_name, column_expression } = row;
|
|
39
|
+
const name = index_name;
|
|
40
|
+
const table = table_name;
|
|
41
|
+
const type = index_type;
|
|
42
|
+
const unique = !!is_unique;
|
|
43
|
+
if (column_expression) {
|
|
44
|
+
if (!indexMap[name]) {
|
|
45
|
+
indexMap[name] = { table, type, unique, columns: [] };
|
|
46
|
+
}
|
|
47
|
+
indexMap[name].columns.push({ type: 'expression', value: column_expression });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (column_name) {
|
|
51
|
+
if (!indexMap[name]) {
|
|
52
|
+
indexMap[name] = { table, type, unique, columns: [] };
|
|
53
|
+
}
|
|
54
|
+
indexMap[name].columns.push({ type: 'column', value: column_name });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
Object.entries(indexMap).forEach(([name, { table, type, unique, columns }]) => {
|
|
59
|
+
const index = { name, type, unique, columns };
|
|
60
|
+
if (!indexes[table])
|
|
61
|
+
indexes[table] = [];
|
|
62
|
+
indexes[table].push(index);
|
|
63
|
+
});
|
|
64
|
+
return indexes;
|
|
65
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateRawRefs = generateRawRefs;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
async function generateRawRefs(client) {
|
|
6
|
+
const refs = [];
|
|
7
|
+
const refsListSql = `
|
|
8
|
+
SELECT
|
|
9
|
+
c.CONSTRAINT_NAME AS "fk_name",
|
|
10
|
+
c.TABLE_NAME AS "child_table",
|
|
11
|
+
LISTAGG(cc.COLUMN_NAME, '${utils_1.LIST_SEPARATOR}') WITHIN GROUP (ORDER BY cc.POSITION) AS "child_columns",
|
|
12
|
+
p.TABLE_NAME AS "parent_table",
|
|
13
|
+
LISTAGG(pc.COLUMN_NAME, '${utils_1.LIST_SEPARATOR}') WITHIN GROUP (ORDER BY pc.POSITION) AS "parent_columns",
|
|
14
|
+
c.DELETE_RULE AS "delete_rule"
|
|
15
|
+
FROM USER_CONSTRAINTS c
|
|
16
|
+
JOIN USER_CONSTRAINTS p
|
|
17
|
+
ON c.R_CONSTRAINT_NAME = p.CONSTRAINT_NAME
|
|
18
|
+
JOIN USER_CONS_COLUMNS cc
|
|
19
|
+
ON c.CONSTRAINT_NAME = cc.CONSTRAINT_NAME
|
|
20
|
+
JOIN USER_CONS_COLUMNS pc
|
|
21
|
+
ON p.CONSTRAINT_NAME = pc.CONSTRAINT_NAME
|
|
22
|
+
AND cc.POSITION = pc.POSITION
|
|
23
|
+
LEFT JOIN USER_OBJECTS obj_child
|
|
24
|
+
ON obj_child.OBJECT_NAME = c.TABLE_NAME
|
|
25
|
+
AND obj_child.OBJECT_TYPE = 'TABLE'
|
|
26
|
+
LEFT JOIN USER_OBJECTS obj_parent
|
|
27
|
+
ON obj_parent.OBJECT_NAME = p.TABLE_NAME
|
|
28
|
+
AND obj_parent.OBJECT_TYPE = 'TABLE'
|
|
29
|
+
WHERE c.CONSTRAINT_TYPE = 'R'
|
|
30
|
+
GROUP BY
|
|
31
|
+
c.CONSTRAINT_NAME,
|
|
32
|
+
c.TABLE_NAME,
|
|
33
|
+
p.TABLE_NAME,
|
|
34
|
+
c.DELETE_RULE,
|
|
35
|
+
obj_child.CREATED,
|
|
36
|
+
obj_child.OBJECT_ID,
|
|
37
|
+
obj_parent.CREATED,
|
|
38
|
+
obj_parent.OBJECT_ID
|
|
39
|
+
ORDER BY
|
|
40
|
+
obj_child.CREATED,
|
|
41
|
+
obj_child.OBJECT_ID,
|
|
42
|
+
c.CONSTRAINT_NAME
|
|
43
|
+
`;
|
|
44
|
+
const refsQueryResult = await client.execute(refsListSql, [], utils_1.EXECUTE_OPTIONS);
|
|
45
|
+
refsQueryResult.rows?.forEach((refRow) => {
|
|
46
|
+
const { fk_name, child_table, child_columns, parent_table, parent_columns, delete_rule } = refRow;
|
|
47
|
+
const ep1 = {
|
|
48
|
+
tableName: child_table,
|
|
49
|
+
schemaName: '',
|
|
50
|
+
fieldNames: child_columns.split(utils_1.LIST_SEPARATOR),
|
|
51
|
+
relation: '*',
|
|
52
|
+
};
|
|
53
|
+
const ep2 = {
|
|
54
|
+
tableName: parent_table,
|
|
55
|
+
schemaName: '',
|
|
56
|
+
fieldNames: parent_columns.split(utils_1.LIST_SEPARATOR),
|
|
57
|
+
relation: '1',
|
|
58
|
+
};
|
|
59
|
+
refs.push({
|
|
60
|
+
name: fk_name,
|
|
61
|
+
endpoints: [ep1, ep2],
|
|
62
|
+
onDelete: delete_rule === 'NO ACTION' ? null : delete_rule,
|
|
63
|
+
onUpdate: null,
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
return refs;
|
|
67
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Connection } from 'oracledb';
|
|
2
|
+
import { FieldsDictionary, Table } from '../types';
|
|
3
|
+
export declare function generateTablesAndFields(client: Connection): Promise<{
|
|
4
|
+
tables: Table[];
|
|
5
|
+
fields: FieldsDictionary;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function getFieldType(dataType: string, characterMaximumLength: number, numericPrecision: number | null, numericScale: number | null): string;
|