@dbml/connector 6.2.0-alpha.0 → 6.3.0-alpha.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/dist/index.js +3739 -38
- package/dist/index.mjs +10359 -0
- package/eslint.config.ts +2 -1
- package/package.json +9 -27
- package/src/connectors/mysql/index.ts +1 -1
- package/vite.config.ts +53 -0
- package/.babelrc +0 -13
- package/dist/connectors/bigquery/index.js +0 -291
- package/dist/connectors/connector.js +0 -28
- package/dist/connectors/mssql/index.js +0 -486
- package/dist/connectors/mysql/index.js +0 -454
- package/dist/connectors/oracle/constraints.js +0 -112
- package/dist/connectors/oracle/index.js +0 -68
- package/dist/connectors/oracle/indexes.js +0 -65
- package/dist/connectors/oracle/refs.js +0 -67
- package/dist/connectors/oracle/tables.js +0 -280
- package/dist/connectors/oracle/utils.js +0 -27
- package/dist/connectors/postgres/index.js +0 -517
- package/dist/connectors/snowflake/index.js +0 -311
- package/dist/connectors/types.js +0 -2
- package/dist/utils/credential-loader.js +0 -58
- package/dist/utils/helpers.js +0 -61
- package/dist/utils/parseSchema.js +0 -59
- package/jest.config.ts +0 -18
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
//
|
|
3
|
-
// Description:
|
|
4
|
-
// Snowflake info schema lacks reference direction for relationships.
|
|
5
|
-
// Constraints and uniqueness cannot be auto-generated from Snowflake info schema.
|
|
6
|
-
// Snowflake does not support ENUMs.
|
|
7
|
-
// Snowflake does not support indexes for standard tables.
|
|
8
|
-
//
|
|
9
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
-
};
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.fetchSchemaJson = void 0;
|
|
14
|
-
const snowflake_sdk_1 = __importDefault(require("snowflake-sdk"));
|
|
15
|
-
const parseSchema_1 = require("../../utils/parseSchema");
|
|
16
|
-
const parseConnectionString = (connectionString) => {
|
|
17
|
-
const params = {};
|
|
18
|
-
const regex = /([^;=]+)=([^;]*)/g;
|
|
19
|
-
let match;
|
|
20
|
-
while ((match = regex.exec(connectionString)) !== null) {
|
|
21
|
-
params[match[1].trim()] = match[2].trim();
|
|
22
|
-
}
|
|
23
|
-
return params;
|
|
24
|
-
};
|
|
25
|
-
const connect = async (connection) => {
|
|
26
|
-
return new Promise((resolve, reject) => {
|
|
27
|
-
console.log('Attempting to connect...');
|
|
28
|
-
connection.connect((err) => {
|
|
29
|
-
if (err) {
|
|
30
|
-
reject(err);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
resolve();
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
const executeQuery = (connection, sqlText) => {
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
console.log('Executing query...');
|
|
41
|
-
connection.execute({
|
|
42
|
-
sqlText,
|
|
43
|
-
complete: (err, stmt, rows) => {
|
|
44
|
-
if (err) {
|
|
45
|
-
reject(err);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
console.log('Query executed successfully.');
|
|
49
|
-
if (rows) {
|
|
50
|
-
resolve(rows);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
};
|
|
57
|
-
const isLogLevel = (value) => {
|
|
58
|
-
return ['ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE'].includes(value);
|
|
59
|
-
};
|
|
60
|
-
const connectToSnowflake = async (config) => {
|
|
61
|
-
const logLevel = isLogLevel(config.LOG_LEVEL) ? config.LOG_LEVEL : 'INFO';
|
|
62
|
-
const isDebugMode = config.IS_DEBUG_MODE === 'true';
|
|
63
|
-
snowflake_sdk_1.default.configure({
|
|
64
|
-
logLevel,
|
|
65
|
-
additionalLogToConsole: isDebugMode,
|
|
66
|
-
});
|
|
67
|
-
// https://docs.snowflake.com/en/developer-guide/node-js/nodejs-driver-options#authentication-options
|
|
68
|
-
let authConfig = {};
|
|
69
|
-
switch (config.AUTHENTICATOR) {
|
|
70
|
-
case 'SNOWFLAKE_JWT':
|
|
71
|
-
// https://docs.snowflake.com/en/developer-guide/node-js/nodejs-driver-authenticate#label-nodejs-key-pair-authentication
|
|
72
|
-
// Support private key file
|
|
73
|
-
authConfig = {
|
|
74
|
-
privateKeyPath: config.PRIVATE_KEY_PATH,
|
|
75
|
-
privateKeyPass: config.PASSPHRASE,
|
|
76
|
-
};
|
|
77
|
-
break;
|
|
78
|
-
case 'SNOWFLAKE':
|
|
79
|
-
case undefined:
|
|
80
|
-
authConfig = {
|
|
81
|
-
password: config.PWD,
|
|
82
|
-
};
|
|
83
|
-
break;
|
|
84
|
-
default:
|
|
85
|
-
throw new Error('Unsupported authenticator');
|
|
86
|
-
}
|
|
87
|
-
// "SERVER=myaccount.snowflakecomputing.com;UID=myusername;PWD=mypassword;DATABASE=mydatabase;WAREHOUSE=mywarehouse;ROLE=myrole";
|
|
88
|
-
const connectionOptions = {
|
|
89
|
-
authenticator: config.AUTHENTICATOR,
|
|
90
|
-
account: config.SERVER,
|
|
91
|
-
username: config.UID,
|
|
92
|
-
database: config.DATABASE,
|
|
93
|
-
warehouse: config.WAREHOUSE,
|
|
94
|
-
sfRetryMaxLoginRetries: 3,
|
|
95
|
-
timeout: 10000,
|
|
96
|
-
...authConfig,
|
|
97
|
-
};
|
|
98
|
-
const connection = snowflake_sdk_1.default.createConnection(connectionOptions);
|
|
99
|
-
// Connect to Snowflake
|
|
100
|
-
await connect(connection);
|
|
101
|
-
// Execute the query
|
|
102
|
-
await executeQuery(connection, 'SELECT CURRENT_VERSION();');
|
|
103
|
-
return connection;
|
|
104
|
-
};
|
|
105
|
-
const convertQueryBoolean = (val) => val === 'YES';
|
|
106
|
-
const getFieldType = (data_type, character_maximum_length, numeric_precision, numeric_scale) => {
|
|
107
|
-
if (character_maximum_length) {
|
|
108
|
-
return `${data_type}(${character_maximum_length})`;
|
|
109
|
-
}
|
|
110
|
-
if (numeric_precision && numeric_scale) {
|
|
111
|
-
return `${data_type}(${numeric_precision},${numeric_scale})`;
|
|
112
|
-
}
|
|
113
|
-
return data_type;
|
|
114
|
-
};
|
|
115
|
-
const getDbdefault = (column_default, default_type) => {
|
|
116
|
-
if (default_type === 'string') {
|
|
117
|
-
return {
|
|
118
|
-
type: default_type,
|
|
119
|
-
value: column_default.slice(1, -1),
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
return {
|
|
123
|
-
type: default_type,
|
|
124
|
-
value: column_default,
|
|
125
|
-
};
|
|
126
|
-
};
|
|
127
|
-
const generateField = (row) => {
|
|
128
|
-
const { COLUMN_NAME: column_name, DATA_TYPE: data_type, CHARACTER_MAXIMUM_LENGTH: character_maximum_length, NUMERIC_PRECISION: numeric_precision, NUMERIC_SCALE: numeric_scale, IDENTITY_INCREMENT: identity_increment, IS_NULLABLE: is_nullable, COLUMN_DEFAULT: column_default, DEFAULT_TYPE: default_type, COLUMN_COMMENT: column_comment, } = row;
|
|
129
|
-
const dbdefault = column_default ? getDbdefault(column_default, default_type) : null;
|
|
130
|
-
const fieldType = {
|
|
131
|
-
type_name: getFieldType(data_type, character_maximum_length, numeric_precision, numeric_scale),
|
|
132
|
-
schemaName: null,
|
|
133
|
-
};
|
|
134
|
-
return {
|
|
135
|
-
name: column_name,
|
|
136
|
-
type: fieldType,
|
|
137
|
-
dbdefault,
|
|
138
|
-
not_null: !convertQueryBoolean(is_nullable),
|
|
139
|
-
increment: !!identity_increment,
|
|
140
|
-
note: column_comment ? { value: column_comment } : { value: '' },
|
|
141
|
-
};
|
|
142
|
-
};
|
|
143
|
-
const generateTablesAndFields = async (conn, schemas) => {
|
|
144
|
-
const fields = {};
|
|
145
|
-
const schemaSql = schemas.length > 0 ? `AND c.table_schema IN (${schemas.map((schema) => `'${schema}'`).join(',')})` : '';
|
|
146
|
-
const tablesAndFieldsSql = `
|
|
147
|
-
SELECT
|
|
148
|
-
c.table_schema,
|
|
149
|
-
c.table_name,
|
|
150
|
-
c.column_name,
|
|
151
|
-
c.data_type,
|
|
152
|
-
c.character_maximum_length,
|
|
153
|
-
c.numeric_precision,
|
|
154
|
-
c.numeric_scale,
|
|
155
|
-
c.is_nullable,
|
|
156
|
-
c.column_default,
|
|
157
|
-
CASE
|
|
158
|
-
WHEN c.column_default IS NULL THEN NULL
|
|
159
|
-
WHEN c.column_default LIKE '''%' THEN 'string'
|
|
160
|
-
WHEN LOWER(c.column_default) = 'true' OR LOWER(c.column_default) = 'false' THEN 'boolean'
|
|
161
|
-
WHEN c.column_default REGEXP '^-?[0-9]+(\\.[0-9]+)?$' THEN 'number'
|
|
162
|
-
ELSE 'expression'
|
|
163
|
-
END AS default_type,
|
|
164
|
-
t.comment AS table_comment,
|
|
165
|
-
c.comment AS column_comment,
|
|
166
|
-
c.identity_increment
|
|
167
|
-
FROM
|
|
168
|
-
information_schema.columns c
|
|
169
|
-
JOIN information_schema.tables t
|
|
170
|
-
ON c.table_name = t.table_name
|
|
171
|
-
AND c.table_schema = t.table_schema
|
|
172
|
-
WHERE
|
|
173
|
-
t.table_type = 'BASE TABLE'
|
|
174
|
-
AND t.table_schema NOT IN ('INFORMATION_SCHEMA')
|
|
175
|
-
${schemaSql}
|
|
176
|
-
ORDER BY
|
|
177
|
-
c.table_schema,
|
|
178
|
-
t.created,
|
|
179
|
-
c.ordinal_position;
|
|
180
|
-
`;
|
|
181
|
-
const tablesAndFieldsResult = await executeQuery(conn, tablesAndFieldsSql);
|
|
182
|
-
const tables = tablesAndFieldsResult.reduce((acc, row) => {
|
|
183
|
-
const { TABLE_SCHEMA: table_schema, TABLE_NAME: table_name, TABLE_COMMENT: table_comment } = row;
|
|
184
|
-
const key = `${table_schema}.${table_name}`;
|
|
185
|
-
if (!acc[key]) {
|
|
186
|
-
acc[key] = {
|
|
187
|
-
name: table_name,
|
|
188
|
-
schemaName: table_schema,
|
|
189
|
-
note: table_comment ? { value: table_comment } : { value: '' },
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
if (!fields[key])
|
|
193
|
-
fields[key] = [];
|
|
194
|
-
const field = generateField(row);
|
|
195
|
-
fields[key].push(field);
|
|
196
|
-
return acc;
|
|
197
|
-
}, {});
|
|
198
|
-
return {
|
|
199
|
-
tables: Object.values(tables),
|
|
200
|
-
fields,
|
|
201
|
-
};
|
|
202
|
-
};
|
|
203
|
-
const createConstraintKeysMap = (keys, schemas, constraintType) => {
|
|
204
|
-
return keys.reduce((acc, row) => {
|
|
205
|
-
const { schema_name, table_name, column_name, constraint_name, } = row;
|
|
206
|
-
const selectedSchema = schemas.length > 0 ? schemas.includes(schema_name) : true;
|
|
207
|
-
if (!selectedSchema) {
|
|
208
|
-
return acc;
|
|
209
|
-
}
|
|
210
|
-
const key = `${schema_name}.${table_name}.${constraint_name}`;
|
|
211
|
-
if (acc[key]) {
|
|
212
|
-
const { columnNames } = acc[key];
|
|
213
|
-
columnNames.push(column_name);
|
|
214
|
-
return acc;
|
|
215
|
-
}
|
|
216
|
-
acc[key] = {
|
|
217
|
-
schemaName: schema_name,
|
|
218
|
-
tableName: table_name,
|
|
219
|
-
constraintName: constraint_name,
|
|
220
|
-
columnNames: [column_name],
|
|
221
|
-
type: '',
|
|
222
|
-
};
|
|
223
|
-
acc[key][constraintType] = true;
|
|
224
|
-
return acc;
|
|
225
|
-
}, {});
|
|
226
|
-
};
|
|
227
|
-
const generateIndexes = async (conn, databaseName, schemas) => {
|
|
228
|
-
const getPrimaryKeysSql = `
|
|
229
|
-
SHOW PRIMARY KEYS IN DATABASE ${databaseName};
|
|
230
|
-
`;
|
|
231
|
-
const getUniqueKeysSql = `
|
|
232
|
-
SHOW UNIQUE KEYS IN DATABASE ${databaseName};
|
|
233
|
-
`;
|
|
234
|
-
const primaryKeys = await executeQuery(conn, getPrimaryKeysSql);
|
|
235
|
-
const uniqueKeys = await executeQuery(conn, getUniqueKeysSql);
|
|
236
|
-
const primaryKeysByConstraint = createConstraintKeysMap(primaryKeys, schemas, 'primary');
|
|
237
|
-
const uniqueKeysByConstraint = createConstraintKeysMap(uniqueKeys, schemas, 'unique');
|
|
238
|
-
const allConstraints = [Object.values(primaryKeysByConstraint), Object.values(uniqueKeysByConstraint)].flat();
|
|
239
|
-
const { indexes, tableConstraints } = allConstraints.reduce((acc, row) => {
|
|
240
|
-
const { schemaName, tableName, constraintName, columnNames, type, primary, unique, } = row;
|
|
241
|
-
const key = `${schemaName}.${tableName}`;
|
|
242
|
-
if (columnNames.length < 2) {
|
|
243
|
-
acc.tableConstraints[key] = {
|
|
244
|
-
[columnNames[0]]: {
|
|
245
|
-
pk: primary,
|
|
246
|
-
unique,
|
|
247
|
-
checks: [],
|
|
248
|
-
},
|
|
249
|
-
};
|
|
250
|
-
return acc;
|
|
251
|
-
}
|
|
252
|
-
const index = {
|
|
253
|
-
name: constraintName,
|
|
254
|
-
type,
|
|
255
|
-
unique,
|
|
256
|
-
pk: primary,
|
|
257
|
-
columns: columnNames.map((columnName) => ({
|
|
258
|
-
type: 'column',
|
|
259
|
-
value: columnName,
|
|
260
|
-
})),
|
|
261
|
-
};
|
|
262
|
-
if (acc.indexes[key]) {
|
|
263
|
-
acc.indexes[key].push(index);
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
acc.indexes[key] = [index];
|
|
267
|
-
}
|
|
268
|
-
return acc;
|
|
269
|
-
}, { indexes: {}, tableConstraints: {} });
|
|
270
|
-
return {
|
|
271
|
-
indexes,
|
|
272
|
-
tableConstraints,
|
|
273
|
-
};
|
|
274
|
-
};
|
|
275
|
-
const fetchSchemaJson = async (connection) => {
|
|
276
|
-
const config = parseConnectionString(connection);
|
|
277
|
-
const conn = await connectToSnowflake(config);
|
|
278
|
-
if (conn instanceof Error) {
|
|
279
|
-
throw conn;
|
|
280
|
-
}
|
|
281
|
-
// Schemas: schema1,schema2,schema3
|
|
282
|
-
const schemas = config.SCHEMAS ? (0, parseSchema_1.parseSchema)(config.SCHEMAS) : [];
|
|
283
|
-
const databaseName = config.DATABASE;
|
|
284
|
-
const tablesAndFieldsRes = generateTablesAndFields(conn, schemas);
|
|
285
|
-
const indexesRes = generateIndexes(conn, databaseName, schemas);
|
|
286
|
-
const res = await Promise.all([
|
|
287
|
-
tablesAndFieldsRes,
|
|
288
|
-
indexesRes,
|
|
289
|
-
]);
|
|
290
|
-
conn.destroy((err) => {
|
|
291
|
-
if (err) {
|
|
292
|
-
throw err;
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
console.log('Connection destroyed successfully.');
|
|
296
|
-
}
|
|
297
|
-
});
|
|
298
|
-
const { tables, fields } = res[0];
|
|
299
|
-
const { indexes, tableConstraints } = res[1];
|
|
300
|
-
return {
|
|
301
|
-
tables,
|
|
302
|
-
fields,
|
|
303
|
-
refs: [],
|
|
304
|
-
enums: [],
|
|
305
|
-
indexes,
|
|
306
|
-
tableConstraints,
|
|
307
|
-
// Checks are not supported in snowflake
|
|
308
|
-
checks: {},
|
|
309
|
-
};
|
|
310
|
-
};
|
|
311
|
-
exports.fetchSchemaJson = fetchSchemaJson;
|
package/dist/connectors/types.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.loadCredentialFromFile = loadCredentialFromFile;
|
|
4
|
-
exports.parseBigQueryCredential = parseBigQueryCredential;
|
|
5
|
-
const promises_1 = require("fs/promises");
|
|
6
|
-
async function loadCredentialFromFile(filename) {
|
|
7
|
-
try {
|
|
8
|
-
const data = await (0, promises_1.readFile)(filename, { encoding: 'utf8' });
|
|
9
|
-
return data;
|
|
10
|
-
}
|
|
11
|
-
catch (error) {
|
|
12
|
-
if (error.name === 'TypeError' || error.name === 'Error') {
|
|
13
|
-
throw new Error(`Load credential error: ${error.message}`);
|
|
14
|
-
}
|
|
15
|
-
throw error;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function parseBigQueryCredential(credentialString) {
|
|
19
|
-
try {
|
|
20
|
-
const credentialJson = JSON.parse(credentialString);
|
|
21
|
-
const { project_id: projectId, client_email: clientEmail, private_key: privateKey, datasets, } = credentialJson;
|
|
22
|
-
// valid datasets: ['dataset_1', 'dataset_2']
|
|
23
|
-
const parsedDatasets = !Array.isArray(datasets)
|
|
24
|
-
? []
|
|
25
|
-
: datasets.filter((dataset) => typeof dataset === 'string');
|
|
26
|
-
const parsedCredentials = {
|
|
27
|
-
datasets: parsedDatasets,
|
|
28
|
-
};
|
|
29
|
-
// Validate and add projectId if provided
|
|
30
|
-
if (projectId !== undefined) {
|
|
31
|
-
if (typeof projectId !== 'string' || !projectId || !projectId.trim()) {
|
|
32
|
-
throw new Error('project_id must be a non-empty string when provided');
|
|
33
|
-
}
|
|
34
|
-
parsedCredentials.projectId = projectId;
|
|
35
|
-
}
|
|
36
|
-
// Validate and add credentials if provided
|
|
37
|
-
// Note: If one credential field is provided, both must be provided
|
|
38
|
-
if (clientEmail !== undefined || privateKey !== undefined) {
|
|
39
|
-
if (!clientEmail || typeof clientEmail !== 'string' || !clientEmail.trim()) {
|
|
40
|
-
throw new Error('client_email must be a non-empty string when credentials are provided');
|
|
41
|
-
}
|
|
42
|
-
if (!privateKey || typeof privateKey !== 'string' || !privateKey.trim()) {
|
|
43
|
-
throw new Error('private_key must be a non-empty string when credentials are provided');
|
|
44
|
-
}
|
|
45
|
-
parsedCredentials.credentials = {
|
|
46
|
-
clientEmail,
|
|
47
|
-
privateKey,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
return parsedCredentials;
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
if (error instanceof SyntaxError) {
|
|
54
|
-
throw new Error('Credentials must be in JSON format');
|
|
55
|
-
}
|
|
56
|
-
throw error;
|
|
57
|
-
}
|
|
58
|
-
}
|
package/dist/utils/helpers.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getIntersection = getIntersection;
|
|
4
|
-
exports.getTableSchemaKey = getTableSchemaKey;
|
|
5
|
-
exports.mergeTables = mergeTables;
|
|
6
|
-
exports.mergeFieldDictionary = mergeFieldDictionary;
|
|
7
|
-
exports.mergeIndexDictionary = mergeIndexDictionary;
|
|
8
|
-
exports.mergeTableConstraintDictionary = mergeTableConstraintDictionary;
|
|
9
|
-
exports.mergeCheckConstraintDictionary = mergeCheckConstraintDictionary;
|
|
10
|
-
function getIntersection(firstList, secondList) {
|
|
11
|
-
return firstList.filter((item) => secondList.includes(item));
|
|
12
|
-
}
|
|
13
|
-
function getTableSchemaKey(schemaName, tableName) {
|
|
14
|
-
if (!tableName || !tableName.trim()) {
|
|
15
|
-
throw new Error('Table name must be a non-empty string');
|
|
16
|
-
}
|
|
17
|
-
return schemaName ? `${schemaName}.${tableName}` : `${tableName}`;
|
|
18
|
-
}
|
|
19
|
-
function mergeTables(firstTableList, secondTable) {
|
|
20
|
-
return firstTableList.concat(secondTable);
|
|
21
|
-
}
|
|
22
|
-
function mergeFieldDictionary(firstDict, secondDict) {
|
|
23
|
-
const result = { ...firstDict };
|
|
24
|
-
Object.keys(secondDict).forEach((key) => {
|
|
25
|
-
if (!result[key]) {
|
|
26
|
-
result[key] = [];
|
|
27
|
-
}
|
|
28
|
-
result[key] = result[key].concat(secondDict[key]);
|
|
29
|
-
});
|
|
30
|
-
return result;
|
|
31
|
-
}
|
|
32
|
-
function mergeIndexDictionary(firstDict, secondDict) {
|
|
33
|
-
const result = { ...firstDict };
|
|
34
|
-
Object.keys(secondDict).forEach((key) => {
|
|
35
|
-
if (!result[key]) {
|
|
36
|
-
result[key] = [];
|
|
37
|
-
}
|
|
38
|
-
result[key] = result[key].concat(secondDict[key]);
|
|
39
|
-
});
|
|
40
|
-
return result;
|
|
41
|
-
}
|
|
42
|
-
function mergeTableConstraintDictionary(firstDict, secondDict) {
|
|
43
|
-
const result = { ...firstDict };
|
|
44
|
-
Object.keys(secondDict).forEach((key) => {
|
|
45
|
-
if (!result[key]) {
|
|
46
|
-
result[key] = {};
|
|
47
|
-
}
|
|
48
|
-
result[key] = secondDict[key];
|
|
49
|
-
});
|
|
50
|
-
return result;
|
|
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,59 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildSchemaQuery = exports.parseConnectionString = exports.parseJdbcSchema = exports.parseSchema = void 0;
|
|
4
|
-
// You cannot use the "=" inside database's schema name. It will be treated as a delimiter.
|
|
5
|
-
const SCHEMAS_DELIMITER = 'schemas=';
|
|
6
|
-
const haveSchemas = (str) => {
|
|
7
|
-
return str.toLowerCase().includes(SCHEMAS_DELIMITER);
|
|
8
|
-
};
|
|
9
|
-
const getSchemasPart = (str) => {
|
|
10
|
-
return str ? str.toLowerCase().split(SCHEMAS_DELIMITER)[1] : '';
|
|
11
|
-
};
|
|
12
|
-
const noSchemaResult = (connectionString) => ({
|
|
13
|
-
connectionString,
|
|
14
|
-
schemas: [],
|
|
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;
|
|
28
|
-
const parseOdbcSchema = (connectionString) => {
|
|
29
|
-
const connectionParts = connectionString.split(';');
|
|
30
|
-
const schemasPart = connectionParts.find((part) => haveSchemas(part));
|
|
31
|
-
return {
|
|
32
|
-
connectionString: connectionParts.filter((part) => !haveSchemas(part)).join(';'),
|
|
33
|
-
schemas: (0, exports.parseSchema)(getSchemasPart(schemasPart)),
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
const parseJdbcSchema = (connectionString) => {
|
|
37
|
-
const connectionParts = connectionString.split('?');
|
|
38
|
-
const connectionArgs = connectionParts[1].split('&');
|
|
39
|
-
const schemasPart = connectionArgs.find((part) => haveSchemas(part));
|
|
40
|
-
return {
|
|
41
|
-
connectionString: connectionParts[0],
|
|
42
|
-
schemas: (0, exports.parseSchema)(getSchemasPart(schemasPart)),
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
exports.parseJdbcSchema = parseJdbcSchema;
|
|
46
|
-
const parseConnectionString = (connectionString, connectionStringType) => {
|
|
47
|
-
if (!haveSchemas(connectionString))
|
|
48
|
-
return noSchemaResult(connectionString);
|
|
49
|
-
return connectionStringType === 'jdbc'
|
|
50
|
-
? (0, exports.parseJdbcSchema)(connectionString)
|
|
51
|
-
: parseOdbcSchema(connectionString);
|
|
52
|
-
};
|
|
53
|
-
exports.parseConnectionString = parseConnectionString;
|
|
54
|
-
const buildSchemaQuery = (columnName, schemas, prefix = 'AND') => {
|
|
55
|
-
if (schemas.length === 0)
|
|
56
|
-
return '';
|
|
57
|
-
return `${prefix} ${columnName} IN (${schemas.map((schema) => `'${schema}'`).join(', ')})`;
|
|
58
|
-
};
|
|
59
|
-
exports.buildSchemaQuery = buildSchemaQuery;
|
package/jest.config.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { type Config } from 'jest';
|
|
2
|
-
|
|
3
|
-
const config: Config = {
|
|
4
|
-
testMatch: ["**/?(*.)+(spec|test).?([mc])[jt]s?(x)"],
|
|
5
|
-
preset: 'ts-jest',
|
|
6
|
-
testEnvironment: 'node',
|
|
7
|
-
transform: {
|
|
8
|
-
'^.+\\.[tj]sx?$': 'babel-jest',
|
|
9
|
-
},
|
|
10
|
-
moduleNameMapper: {
|
|
11
|
-
'\\.(css|less|scss)$': 'identity-obj-proxy',
|
|
12
|
-
},
|
|
13
|
-
collectCoverage: true,
|
|
14
|
-
coverageReporters: ['json', 'json-summary', 'html', 'text'],
|
|
15
|
-
coverageDirectory: 'coverage',
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export default config;
|