@quillsql/node 0.5.9 → 0.6.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/assets/pgtypes.js +1391 -1391
- package/dist/db/BigQuery.js +1 -0
- package/dist/db/CachedConnection.d.ts +3 -1
- package/dist/db/CachedConnection.js +11 -14
- package/dist/db/Postgres.js +28 -21
- package/dist/db/Snowflake.js +2 -2
- package/dist/index.js +14 -5
- package/dist/utils/Error.d.ts +1 -0
- package/dist/utils/Error.js +12 -3
- package/dist/utils/RunQueryProcesses.d.ts +6 -0
- package/eslint.config.mjs +16 -0
- package/examples/mysql-node/app.ts +62 -0
- package/examples/node-server/app.ts +8 -9
- package/package.json +16 -3
- package/src/assets/pgtypes.ts +1392 -1392
- package/src/db/BigQuery.ts +10 -10
- package/src/db/CachedConnection.ts +11 -19
- package/src/db/DatabaseHelper.ts +29 -30
- package/src/db/Mysql.ts +0 -2
- package/src/db/Postgres.ts +38 -40
- package/src/db/Snowflake.ts +14 -15
- package/src/index.ts +20 -6
- package/src/models/Cache.ts +2 -2
- package/src/utils/Error.ts +18 -4
- package/src/utils/RunQueryProcesses.ts +3 -3
- package/src/utils/textProcessing.ts +1 -1
package/src/db/BigQuery.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Client } from "../models/Client";
|
|
2
1
|
import { BigQuery } from "@google-cloud/bigquery";
|
|
3
2
|
import { QuillQueryResults } from "./DatabaseHelper";
|
|
4
3
|
import { capitalize, depluralize } from "../utils/textProcessing";
|
|
@@ -24,7 +23,7 @@ export function formatBigQueryConfig(connectionString: string): BigQueryConfig {
|
|
|
24
23
|
// Validate if required fields are present
|
|
25
24
|
if (!serviceAccount.project_id || !serviceAccount.private_key) {
|
|
26
25
|
throw new Error(
|
|
27
|
-
"Invalid service account JSON. Required fields are missing."
|
|
26
|
+
"Invalid service account JSON. Required fields are missing.",
|
|
28
27
|
);
|
|
29
28
|
}
|
|
30
29
|
|
|
@@ -44,7 +43,7 @@ export function connectToBigQuery(config: BigQueryConfig) {
|
|
|
44
43
|
|
|
45
44
|
export async function runQueryBigQuery(
|
|
46
45
|
sql: string,
|
|
47
|
-
bigQuery: BigQuery
|
|
46
|
+
bigQuery: BigQuery,
|
|
48
47
|
): Promise<QuillQueryResults> {
|
|
49
48
|
const rows = await bigQuery.query(sql);
|
|
50
49
|
if (!rows[0] || rows[0].length === 0) return { fields: [], rows: [] };
|
|
@@ -80,7 +79,7 @@ export async function getSchemaBigQuery(bigQuery: BigQuery): Promise<string[]> {
|
|
|
80
79
|
|
|
81
80
|
export async function getTablesBySchemaBigQuery(
|
|
82
81
|
bigQuery: BigQuery,
|
|
83
|
-
schemaNames: string[]
|
|
82
|
+
schemaNames: string[],
|
|
84
83
|
): Promise<{ tableName: string; schemaName: string }[]> {
|
|
85
84
|
const allColumns = await Promise.all(
|
|
86
85
|
schemaNames.map(async (schema) => {
|
|
@@ -89,7 +88,7 @@ export async function getTablesBySchemaBigQuery(
|
|
|
89
88
|
return rows[0].map((row) => {
|
|
90
89
|
return { tableName: row.table_name, schemaName: schema };
|
|
91
90
|
});
|
|
92
|
-
})
|
|
91
|
+
}),
|
|
93
92
|
);
|
|
94
93
|
return allColumns.flat();
|
|
95
94
|
}
|
|
@@ -97,7 +96,7 @@ export async function getTablesBySchemaBigQuery(
|
|
|
97
96
|
export async function getColumnsByTableBigQuery(
|
|
98
97
|
bigQuery: BigQuery,
|
|
99
98
|
schemaName: string,
|
|
100
|
-
tableName: string
|
|
99
|
+
tableName: string,
|
|
101
100
|
): Promise<string[]> {
|
|
102
101
|
const sql = `SELECT column_name FROM ${schemaName}.INFORMATION_SCHEMA.COLUMNS WHERE table_name = '${tableName}'`;
|
|
103
102
|
const rows = await bigQuery.query(sql);
|
|
@@ -108,7 +107,7 @@ export async function getForeignKeysBigQuery(
|
|
|
108
107
|
connection: BigQuery,
|
|
109
108
|
schemaName: string,
|
|
110
109
|
tableName: string,
|
|
111
|
-
primaryKey: string
|
|
110
|
+
primaryKey: string,
|
|
112
111
|
): Promise<string[]> {
|
|
113
112
|
const depluralizedTableName = depluralize(tableName);
|
|
114
113
|
let sql = `SELECT column_name FROM ${schemaName}.INFORMATION_SCHEMA.COLUMNS
|
|
@@ -121,7 +120,7 @@ export async function getForeignKeysBigQuery(
|
|
|
121
120
|
return key.column_name;
|
|
122
121
|
});
|
|
123
122
|
foreignKeysString = foreignKeysString.filter(
|
|
124
|
-
(key) => key !== "id" && key !== "_id_"
|
|
123
|
+
(key) => key !== "id" && key !== "_id_",
|
|
125
124
|
);
|
|
126
125
|
foreignKeysString = [...new Set(foreignKeysString)];
|
|
127
126
|
if (foreignKeysString.length === 0) {
|
|
@@ -144,7 +143,7 @@ export async function getForeignKeysBigQuery(
|
|
|
144
143
|
export async function getSchemaColumnInfoBigQuery(
|
|
145
144
|
connection: BigQuery,
|
|
146
145
|
schemaName: string,
|
|
147
|
-
tableNames: { tableName: string; schemaName: string }[]
|
|
146
|
+
tableNames: { tableName: string; schemaName: string }[],
|
|
148
147
|
): Promise<
|
|
149
148
|
{ tableName: string; columns: { columnName: string; dataTypeID: number }[] }[]
|
|
150
149
|
> {
|
|
@@ -167,7 +166,7 @@ export async function getSchemaColumnInfoBigQuery(
|
|
|
167
166
|
fieldType: row.dataType,
|
|
168
167
|
})),
|
|
169
168
|
};
|
|
170
|
-
})
|
|
169
|
+
}),
|
|
171
170
|
);
|
|
172
171
|
return allColumns;
|
|
173
172
|
}
|
|
@@ -179,6 +178,7 @@ function convertBigQueryTypeToPostgresOID(type: string): number {
|
|
|
179
178
|
FLOAT: 700,
|
|
180
179
|
TIMESTAMP: 1114,
|
|
181
180
|
DATE: 1082,
|
|
181
|
+
BOOL: 16,
|
|
182
182
|
};
|
|
183
183
|
|
|
184
184
|
const postgresType = typeToOidMap[type.toUpperCase()] || "VARCHAR"; // Default to 'text' if the type is not recognized
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { Pool } from "pg";
|
|
2
1
|
import { Mapable, CacheCredentials } from "../models/Cache";
|
|
3
2
|
import { QuillConfig } from "../models/Quill";
|
|
4
3
|
import { createClient } from "redis";
|
|
5
|
-
import { isSuperset } from "../utils/Error";
|
|
4
|
+
import { isSuperset, PgError } from "../utils/Error";
|
|
6
5
|
import {
|
|
7
6
|
DatabaseConnection,
|
|
8
7
|
connectToDatabase,
|
|
@@ -10,20 +9,6 @@ import {
|
|
|
10
9
|
runQueryByDatabase,
|
|
11
10
|
} from "./DatabaseHelper";
|
|
12
11
|
|
|
13
|
-
class PgError extends Error {
|
|
14
|
-
code?: string;
|
|
15
|
-
detail?: string;
|
|
16
|
-
hint?: string;
|
|
17
|
-
position?: string;
|
|
18
|
-
// Add other properties if needed
|
|
19
|
-
constructor(detail?: string, hint?: string, position?: string) {
|
|
20
|
-
super();
|
|
21
|
-
this.detail = detail;
|
|
22
|
-
this.hint = hint;
|
|
23
|
-
this.position = position;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
12
|
/** The TTL for new cache entries (default: 1h) */
|
|
28
13
|
const DEFAULT_CACHE_TTL = 24 * 60 * 60;
|
|
29
14
|
|
|
@@ -34,6 +19,8 @@ export class CachedConnection {
|
|
|
34
19
|
public ttl: number;
|
|
35
20
|
public cache: Mapable | null;
|
|
36
21
|
private config: any;
|
|
22
|
+
private activeQueries: number = 0;
|
|
23
|
+
private readonly MAX_ACTIVE_QUERIES: number = 0;
|
|
37
24
|
|
|
38
25
|
constructor(
|
|
39
26
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
@@ -47,8 +34,9 @@ export class CachedConnection {
|
|
|
47
34
|
this.cache = this.getCache(cacheConfig);
|
|
48
35
|
}
|
|
49
36
|
|
|
50
|
-
public async query(text: string
|
|
37
|
+
public async query(text: string): Promise<any> {
|
|
51
38
|
try {
|
|
39
|
+
this.activeQueries++;
|
|
52
40
|
this.pool = this.getPool();
|
|
53
41
|
if (!this.cache) {
|
|
54
42
|
return await runQueryByDatabase(this.databaseType, this.pool, text);
|
|
@@ -70,6 +58,7 @@ export class CachedConnection {
|
|
|
70
58
|
} catch (err) {
|
|
71
59
|
if (isSuperset(err, PgError)) {
|
|
72
60
|
throw new PgError(
|
|
61
|
+
(err as any).message,
|
|
73
62
|
(err as any).detail,
|
|
74
63
|
(err as any).hint,
|
|
75
64
|
(err as any).position,
|
|
@@ -78,8 +67,11 @@ export class CachedConnection {
|
|
|
78
67
|
throw new Error(err.message);
|
|
79
68
|
}
|
|
80
69
|
} finally {
|
|
81
|
-
|
|
82
|
-
|
|
70
|
+
this.activeQueries--;
|
|
71
|
+
if (this.activeQueries <= this.MAX_ACTIVE_QUERIES) {
|
|
72
|
+
if (this.databaseType.toLowerCase() === "mysql") {
|
|
73
|
+
this.close();
|
|
74
|
+
}
|
|
83
75
|
}
|
|
84
76
|
}
|
|
85
77
|
}
|
package/src/db/DatabaseHelper.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Pool } from "pg";
|
|
2
2
|
import snowflake from "snowflake-sdk";
|
|
3
|
-
import { Client } from "../models/Client";
|
|
4
3
|
import { Pool as MysqlPool } from "mysql2";
|
|
5
4
|
import { BigQuery } from "@google-cloud/bigquery";
|
|
6
5
|
import {
|
|
@@ -65,7 +64,7 @@ export interface QuillQueryResults {
|
|
|
65
64
|
|
|
66
65
|
export function getDatabaseCredentials(
|
|
67
66
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
68
|
-
connectionString: string
|
|
67
|
+
connectionString: string,
|
|
69
68
|
):
|
|
70
69
|
| PostgresConnectionConfig
|
|
71
70
|
| SnowflakeConnectionConfig
|
|
@@ -94,7 +93,7 @@ export function connectToDatabase(
|
|
|
94
93
|
| PostgresConnectionConfig
|
|
95
94
|
| SnowflakeConnectionConfig
|
|
96
95
|
| BigQueryConfig
|
|
97
|
-
| MysqlConnectionConfig
|
|
96
|
+
| MysqlConnectionConfig,
|
|
98
97
|
): DatabaseConnection {
|
|
99
98
|
switch (databaseType.toLowerCase()) {
|
|
100
99
|
case "postgres":
|
|
@@ -115,7 +114,7 @@ export function connectToDatabase(
|
|
|
115
114
|
export function runQueryByDatabase(
|
|
116
115
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
117
116
|
connection: DatabaseConnection,
|
|
118
|
-
sql: string
|
|
117
|
+
sql: string,
|
|
119
118
|
): Promise<QuillQueryResults> | undefined {
|
|
120
119
|
switch (databaseType.toLowerCase()) {
|
|
121
120
|
case "postgres":
|
|
@@ -135,7 +134,7 @@ export function runQueryByDatabase(
|
|
|
135
134
|
|
|
136
135
|
export function disconnectFromDatabase(
|
|
137
136
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
138
|
-
database: DatabaseConnection
|
|
137
|
+
database: DatabaseConnection,
|
|
139
138
|
) {
|
|
140
139
|
switch (databaseType.toLowerCase()) {
|
|
141
140
|
case "postgres":
|
|
@@ -155,7 +154,7 @@ export function disconnectFromDatabase(
|
|
|
155
154
|
|
|
156
155
|
export async function getSchemasByDatabase(
|
|
157
156
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
158
|
-
connection: DatabaseConnection
|
|
157
|
+
connection: DatabaseConnection,
|
|
159
158
|
): Promise<string[] | undefined> {
|
|
160
159
|
switch (databaseType.toLowerCase()) {
|
|
161
160
|
case "postgres":
|
|
@@ -177,33 +176,33 @@ export async function getSchemasByDatabase(
|
|
|
177
176
|
export async function getTablesBySchemaByDatabase(
|
|
178
177
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
179
178
|
connection: DatabaseConnection,
|
|
180
|
-
schemaName: string | string[]
|
|
179
|
+
schemaName: string | string[],
|
|
181
180
|
): Promise<string[] | { tableName: string; schemaName: string }[] | undefined> {
|
|
182
181
|
switch (databaseType.toLowerCase()) {
|
|
183
182
|
case "postgres":
|
|
184
183
|
return getTablesBySchemaPostgres(
|
|
185
184
|
connection as Pool,
|
|
186
|
-
schemaName as string[]
|
|
185
|
+
schemaName as string[],
|
|
187
186
|
);
|
|
188
187
|
case "postgresql":
|
|
189
188
|
return getTablesBySchemaPostgres(
|
|
190
189
|
connection as Pool,
|
|
191
|
-
schemaName as string[]
|
|
190
|
+
schemaName as string[],
|
|
192
191
|
);
|
|
193
192
|
case "snowflake":
|
|
194
193
|
return getTablesBySchemaSnowflake(
|
|
195
194
|
connection as snowflake.Connection,
|
|
196
|
-
schemaName as string[]
|
|
195
|
+
schemaName as string[],
|
|
197
196
|
);
|
|
198
197
|
case "bigquery":
|
|
199
198
|
return getTablesBySchemaBigQuery(
|
|
200
199
|
connection as BigQuery,
|
|
201
|
-
schemaName as string[]
|
|
200
|
+
schemaName as string[],
|
|
202
201
|
);
|
|
203
202
|
case "mysql":
|
|
204
203
|
return getTablesBySchemaMysql(
|
|
205
204
|
connection as MysqlPool,
|
|
206
|
-
schemaName as string[]
|
|
205
|
+
schemaName as string[],
|
|
207
206
|
);
|
|
208
207
|
default:
|
|
209
208
|
return undefined;
|
|
@@ -215,38 +214,38 @@ export async function getColumnsByTableByDatabase(
|
|
|
215
214
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
216
215
|
connection: DatabaseConnection,
|
|
217
216
|
schemaName: string,
|
|
218
|
-
tableName: string
|
|
217
|
+
tableName: string,
|
|
219
218
|
): Promise<string[] | undefined> {
|
|
220
219
|
switch (databaseType.toLowerCase()) {
|
|
221
220
|
case "postgres":
|
|
222
221
|
return getColumnsByTablePostgres(
|
|
223
222
|
connection as Pool,
|
|
224
223
|
schemaName,
|
|
225
|
-
tableName
|
|
224
|
+
tableName,
|
|
226
225
|
);
|
|
227
226
|
case "postgresql":
|
|
228
227
|
return getColumnsByTablePostgres(
|
|
229
228
|
connection as Pool,
|
|
230
229
|
schemaName,
|
|
231
|
-
tableName
|
|
230
|
+
tableName,
|
|
232
231
|
);
|
|
233
232
|
case "snowflake":
|
|
234
233
|
return getColumnsByTableSnowflake(
|
|
235
234
|
connection as snowflake.Connection,
|
|
236
235
|
schemaName,
|
|
237
|
-
tableName
|
|
236
|
+
tableName,
|
|
238
237
|
);
|
|
239
238
|
case "bigquery":
|
|
240
239
|
return getColumnsByTableBigQuery(
|
|
241
240
|
connection as BigQuery,
|
|
242
241
|
schemaName,
|
|
243
|
-
tableName
|
|
242
|
+
tableName,
|
|
244
243
|
);
|
|
245
244
|
case "mysql":
|
|
246
245
|
return getColumnsByTableMysql(
|
|
247
246
|
connection as MysqlPool,
|
|
248
247
|
schemaName,
|
|
249
|
-
tableName
|
|
248
|
+
tableName,
|
|
250
249
|
);
|
|
251
250
|
default:
|
|
252
251
|
return undefined;
|
|
@@ -258,7 +257,7 @@ export async function getForiegnKeysByDatabase(
|
|
|
258
257
|
connection: DatabaseConnection,
|
|
259
258
|
schemaName: string,
|
|
260
259
|
tableName: string,
|
|
261
|
-
primaryKey: string
|
|
260
|
+
primaryKey: string,
|
|
262
261
|
): Promise<string[] | undefined> {
|
|
263
262
|
switch (databaseType.toLowerCase()) {
|
|
264
263
|
case "postgres":
|
|
@@ -266,35 +265,35 @@ export async function getForiegnKeysByDatabase(
|
|
|
266
265
|
connection as Pool,
|
|
267
266
|
schemaName,
|
|
268
267
|
tableName,
|
|
269
|
-
primaryKey
|
|
268
|
+
primaryKey,
|
|
270
269
|
);
|
|
271
270
|
case "postgresql":
|
|
272
271
|
return getForeignKeysPostgres(
|
|
273
272
|
connection as Pool,
|
|
274
273
|
schemaName,
|
|
275
274
|
tableName,
|
|
276
|
-
primaryKey
|
|
275
|
+
primaryKey,
|
|
277
276
|
);
|
|
278
277
|
case "snowflake":
|
|
279
278
|
return getForeignKeysSnowflake(
|
|
280
279
|
connection as snowflake.Connection,
|
|
281
280
|
schemaName,
|
|
282
281
|
tableName,
|
|
283
|
-
primaryKey
|
|
282
|
+
primaryKey,
|
|
284
283
|
);
|
|
285
284
|
case "bigquery":
|
|
286
285
|
return getForeignKeysBigQuery(
|
|
287
286
|
connection as BigQuery,
|
|
288
287
|
schemaName,
|
|
289
288
|
tableName,
|
|
290
|
-
primaryKey
|
|
289
|
+
primaryKey,
|
|
291
290
|
);
|
|
292
291
|
case "mysql":
|
|
293
292
|
return getForeignKeysMysql(
|
|
294
293
|
connection as MysqlPool,
|
|
295
294
|
schemaName,
|
|
296
295
|
tableName,
|
|
297
|
-
primaryKey
|
|
296
|
+
primaryKey,
|
|
298
297
|
);
|
|
299
298
|
default:
|
|
300
299
|
return undefined;
|
|
@@ -305,38 +304,38 @@ export function getColumnInfoBySchemaByDatabase(
|
|
|
305
304
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
306
305
|
connection: DatabaseConnection,
|
|
307
306
|
schemaName: string,
|
|
308
|
-
tables: string[] | { tableName: string; schemaName: string }[]
|
|
307
|
+
tables: string[] | { tableName: string; schemaName: string }[],
|
|
309
308
|
) {
|
|
310
309
|
switch (databaseType.toLowerCase()) {
|
|
311
310
|
case "postgres":
|
|
312
311
|
return getSchemaColumnInfoPostgress(
|
|
313
312
|
connection as Pool,
|
|
314
313
|
schemaName,
|
|
315
|
-
tables as { tableName: string; schemaName: string }[]
|
|
314
|
+
tables as { tableName: string; schemaName: string }[],
|
|
316
315
|
);
|
|
317
316
|
case "postgresql":
|
|
318
317
|
return getSchemaColumnInfoPostgress(
|
|
319
318
|
connection as Pool,
|
|
320
319
|
schemaName,
|
|
321
|
-
tables as { tableName: string; schemaName: string }[]
|
|
320
|
+
tables as { tableName: string; schemaName: string }[],
|
|
322
321
|
);
|
|
323
322
|
case "snowflake":
|
|
324
323
|
return getSchemaColumnInfoSnowflake(
|
|
325
324
|
connection as snowflake.Connection,
|
|
326
325
|
schemaName,
|
|
327
|
-
tables as { tableName: string; schemaName: string }[]
|
|
326
|
+
tables as { tableName: string; schemaName: string }[],
|
|
328
327
|
);
|
|
329
328
|
case "bigquery":
|
|
330
329
|
return getSchemaColumnInfoBigQuery(
|
|
331
330
|
connection as BigQuery,
|
|
332
331
|
schemaName,
|
|
333
|
-
tables as { tableName: string; schemaName: string }[]
|
|
332
|
+
tables as { tableName: string; schemaName: string }[],
|
|
334
333
|
);
|
|
335
334
|
case "mysql":
|
|
336
335
|
return getSchemaColumnInfoMysql(
|
|
337
336
|
connection as MysqlPool,
|
|
338
337
|
schemaName,
|
|
339
|
-
tables as { tableName: string; schemaName: string }[]
|
|
338
|
+
tables as { tableName: string; schemaName: string }[],
|
|
340
339
|
);
|
|
341
340
|
default:
|
|
342
341
|
return undefined;
|
package/src/db/Mysql.ts
CHANGED
package/src/db/Postgres.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { Pool } from "pg";
|
|
2
|
-
import { Client } from "../models/Client";
|
|
3
|
-
import { disconnect } from "process";
|
|
2
|
+
// import { Client } from "../models/Client";
|
|
4
3
|
import { QuillQueryResults } from "./DatabaseHelper";
|
|
5
4
|
import { capitalize, depluralize } from "../utils/textProcessing";
|
|
6
5
|
import { PG_TYPES } from "../assets/pgtypes";
|
|
7
|
-
import { run } from "node:test";
|
|
8
6
|
|
|
9
7
|
export type PostgresConnectionConfig = {
|
|
10
8
|
connectionString: string;
|
|
@@ -26,7 +24,7 @@ export function disconnectFromPostgres(pool: Pool) {
|
|
|
26
24
|
|
|
27
25
|
export async function runQueryPostgres(
|
|
28
26
|
sql: string,
|
|
29
|
-
pool: Pool
|
|
27
|
+
pool: Pool,
|
|
30
28
|
): Promise<QuillQueryResults> {
|
|
31
29
|
const results = await pool.query(sql);
|
|
32
30
|
return {
|
|
@@ -47,7 +45,7 @@ export async function getSchemasPostgres(pool: Pool): Promise<string[]> {
|
|
|
47
45
|
|
|
48
46
|
export async function getTablesBySchemaPostgres(
|
|
49
47
|
pool: Pool,
|
|
50
|
-
schemaNames: string[]
|
|
48
|
+
schemaNames: string[],
|
|
51
49
|
): Promise<{ tableName: string; schemaName: string }[]> {
|
|
52
50
|
const allColumns = await Promise.all(
|
|
53
51
|
schemaNames.map(async (schema) => {
|
|
@@ -56,7 +54,7 @@ export async function getTablesBySchemaPostgres(
|
|
|
56
54
|
return results.rows.map((row) => {
|
|
57
55
|
return { tableName: row.table_name, schemaName: row.table_schema };
|
|
58
56
|
});
|
|
59
|
-
})
|
|
57
|
+
}),
|
|
60
58
|
);
|
|
61
59
|
return allColumns.flat();
|
|
62
60
|
}
|
|
@@ -64,7 +62,7 @@ export async function getTablesBySchemaPostgres(
|
|
|
64
62
|
export async function getColumnsByTablePostgres(
|
|
65
63
|
pool: Pool,
|
|
66
64
|
schemaName: string,
|
|
67
|
-
tableName: string
|
|
65
|
+
tableName: string,
|
|
68
66
|
): Promise<string[]> {
|
|
69
67
|
const sql = `SELECT column_name FROM information_schema.columns WHERE table_schema = '${schemaName}' and table_name = '${tableName}'`;
|
|
70
68
|
const results = await runQueryPostgres(sql, pool);
|
|
@@ -75,7 +73,7 @@ export async function getForeignKeysPostgres(
|
|
|
75
73
|
pool: Pool,
|
|
76
74
|
schemaName: string,
|
|
77
75
|
tableName: string,
|
|
78
|
-
primaryKey: string
|
|
76
|
+
primaryKey: string,
|
|
79
77
|
): Promise<string[]> {
|
|
80
78
|
const depluralizedTableName = depluralize(tableName);
|
|
81
79
|
let sql = `SELECT column_name FROM information_schema.columns
|
|
@@ -89,7 +87,7 @@ export async function getForeignKeysPostgres(
|
|
|
89
87
|
return key.column_name;
|
|
90
88
|
});
|
|
91
89
|
foreignKeysString = foreignKeysString.filter(
|
|
92
|
-
(key) => key !== "id" && key !== "_id_"
|
|
90
|
+
(key) => key !== "id" && key !== "_id_",
|
|
93
91
|
);
|
|
94
92
|
foreignKeysString = [...new Set(foreignKeysString)];
|
|
95
93
|
if (foreignKeysString.length === 0) {
|
|
@@ -113,7 +111,7 @@ export async function getForeignKeysPostgres(
|
|
|
113
111
|
export async function getSchemaColumnInfoPostgress(
|
|
114
112
|
pool: Pool,
|
|
115
113
|
schemaName: string,
|
|
116
|
-
tableNames: { tableName: string; schemaName: string }[]
|
|
114
|
+
tableNames: { tableName: string; schemaName: string }[],
|
|
117
115
|
): Promise<
|
|
118
116
|
{ tableName: string; columns: { columnName: string; dataTypeID: number }[] }[]
|
|
119
117
|
> {
|
|
@@ -145,43 +143,43 @@ export async function getSchemaColumnInfoPostgress(
|
|
|
145
143
|
};
|
|
146
144
|
}),
|
|
147
145
|
};
|
|
148
|
-
})
|
|
146
|
+
}),
|
|
149
147
|
);
|
|
150
148
|
return allColumns;
|
|
151
149
|
}
|
|
152
150
|
|
|
153
151
|
export function formatPostgresConfig(
|
|
154
|
-
connectionString: string
|
|
152
|
+
connectionString: string,
|
|
155
153
|
): PostgresConnectionConfig {
|
|
156
154
|
return { connectionString, ssl: { rejectUnauthorized: false } };
|
|
157
155
|
}
|
|
158
156
|
|
|
159
157
|
// CURRENTLY UNUSED BUT MAYBE USEFUL IN THE FUTURE
|
|
160
|
-
function getSslConfig(client: Client):
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
158
|
+
// function getSslConfig(client: Client):
|
|
159
|
+
// | {
|
|
160
|
+
// rejectUnauthorized: false;
|
|
161
|
+
// ca?: string;
|
|
162
|
+
// key?: string;
|
|
163
|
+
// cert?: string;
|
|
164
|
+
// }
|
|
165
|
+
// | undefined {
|
|
166
|
+
// if (!client.useSsl) {
|
|
167
|
+
// return undefined;
|
|
168
|
+
// }
|
|
169
|
+
// if (client.serverCa && client.clientKey && client.clientCert) {
|
|
170
|
+
// return {
|
|
171
|
+
// rejectUnauthorized: false,
|
|
172
|
+
// ca: client.serverCa,
|
|
173
|
+
// key: client.clientKey,
|
|
174
|
+
// cert: client.clientCert,
|
|
175
|
+
// };
|
|
176
|
+
// }
|
|
177
|
+
// if (client.serverCa) {
|
|
178
|
+
// return {
|
|
179
|
+
// rejectUnauthorized: false,
|
|
180
|
+
// ca: client.serverCa,
|
|
181
|
+
// };
|
|
182
|
+
// }
|
|
183
|
+
// // if using ssl with no certificates
|
|
184
|
+
// return { rejectUnauthorized: false };
|
|
185
|
+
// }
|
package/src/db/Snowflake.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import snowflake from "snowflake-sdk";
|
|
2
|
-
import { Client } from "../models/Client";
|
|
3
2
|
import { QuillQueryResults } from "./DatabaseHelper";
|
|
4
3
|
import { capitalize, depluralize } from "../utils/textProcessing";
|
|
5
4
|
|
|
@@ -31,7 +30,7 @@ export type SnowflakeConnectionConfig = {
|
|
|
31
30
|
|
|
32
31
|
export async function runQuerySnowflake(
|
|
33
32
|
sql: string,
|
|
34
|
-
connection: snowflake.Connection
|
|
33
|
+
connection: snowflake.Connection,
|
|
35
34
|
): Promise<QuillQueryResults> {
|
|
36
35
|
const results = await new Promise((resolve, reject) => {
|
|
37
36
|
connection.execute({
|
|
@@ -56,7 +55,7 @@ export async function runQuerySnowflake(
|
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
export async function getSchemasSnowflake(
|
|
59
|
-
connection: snowflake.Connection
|
|
58
|
+
connection: snowflake.Connection,
|
|
60
59
|
): Promise<string[]> {
|
|
61
60
|
const sql = `SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
|
|
62
61
|
WHERE SCHEMA_NAME != 'INFORMATION_SCHEMA'`;
|
|
@@ -66,7 +65,7 @@ export async function getSchemasSnowflake(
|
|
|
66
65
|
|
|
67
66
|
export async function getTablesBySchemaSnowflake(
|
|
68
67
|
connection: snowflake.Connection,
|
|
69
|
-
schemaNames: string[]
|
|
68
|
+
schemaNames: string[],
|
|
70
69
|
): Promise<{ tableName: string; schemaName: string }[]> {
|
|
71
70
|
const allColumns = await Promise.all(
|
|
72
71
|
schemaNames.map(async (schema) => {
|
|
@@ -80,7 +79,7 @@ export async function getTablesBySchemaSnowflake(
|
|
|
80
79
|
return results.rows.map((row) => {
|
|
81
80
|
return { tableName: row.tableName, schemaName: row.schemaName };
|
|
82
81
|
});
|
|
83
|
-
})
|
|
82
|
+
}),
|
|
84
83
|
);
|
|
85
84
|
return allColumns.flat();
|
|
86
85
|
}
|
|
@@ -88,7 +87,7 @@ export async function getTablesBySchemaSnowflake(
|
|
|
88
87
|
export async function getColumnsByTableSnowflake(
|
|
89
88
|
connection: snowflake.Connection,
|
|
90
89
|
schemaName: string,
|
|
91
|
-
tableName: string
|
|
90
|
+
tableName: string,
|
|
92
91
|
): Promise<string[]> {
|
|
93
92
|
const sql = `SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '${schemaName}' AND TABLE_NAME = '${tableName}'`;
|
|
94
93
|
const results = await runQuerySnowflake(sql, connection);
|
|
@@ -96,7 +95,7 @@ export async function getColumnsByTableSnowflake(
|
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
export function formatSnowflakeConfig(
|
|
99
|
-
connectionString: string
|
|
98
|
+
connectionString: string,
|
|
100
99
|
): SnowflakeConnectionConfig {
|
|
101
100
|
const parsed = new URL(connectionString);
|
|
102
101
|
return {
|
|
@@ -109,7 +108,7 @@ export function formatSnowflakeConfig(
|
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
export function connectToSnowflake(
|
|
112
|
-
config: SnowflakeConnectionConfig
|
|
111
|
+
config: SnowflakeConnectionConfig,
|
|
113
112
|
): snowflake.Connection {
|
|
114
113
|
const connection = snowflake.createConnection({
|
|
115
114
|
...config,
|
|
@@ -124,9 +123,9 @@ export function connectToSnowflake(
|
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
export async function disconnectFromSnowflake(
|
|
127
|
-
connection: snowflake.Connection
|
|
126
|
+
connection: snowflake.Connection,
|
|
128
127
|
) {
|
|
129
|
-
connection.destroy((err
|
|
128
|
+
connection.destroy((err) => {
|
|
130
129
|
if (err) {
|
|
131
130
|
console.error(`Failed to disconnect from Snowflake: ${err.message}`);
|
|
132
131
|
}
|
|
@@ -137,9 +136,9 @@ export async function getForeignKeysSnowflake(
|
|
|
137
136
|
connection: snowflake.Connection,
|
|
138
137
|
schemaName: string,
|
|
139
138
|
tableName: string,
|
|
140
|
-
primaryKey: string
|
|
139
|
+
primaryKey: string,
|
|
141
140
|
): Promise<string[]> {
|
|
142
|
-
|
|
141
|
+
const depluralizedTableName = depluralize(tableName);
|
|
143
142
|
let sql = `SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
|
144
143
|
WHERE TABLE_SCHEMA = '${schemaName}'
|
|
145
144
|
AND TABLE_NAME = '${schemaName}'
|
|
@@ -152,7 +151,7 @@ export async function getForeignKeysSnowflake(
|
|
|
152
151
|
return key.COLUMN_NAME;
|
|
153
152
|
});
|
|
154
153
|
foreignKeysString = foreignKeysString.filter(
|
|
155
|
-
(key) => key !== "id" && key !== "_id_"
|
|
154
|
+
(key) => key !== "id" && key !== "_id_",
|
|
156
155
|
);
|
|
157
156
|
foreignKeysString = [...new Set(foreignKeysString)];
|
|
158
157
|
if (foreignKeysString.length === 0) {
|
|
@@ -177,7 +176,7 @@ export async function getForeignKeysSnowflake(
|
|
|
177
176
|
export async function getSchemaColumnInfoSnowflake(
|
|
178
177
|
connection: snowflake.Connection,
|
|
179
178
|
schemaName: string,
|
|
180
|
-
tableNames: { tableName: string; schemaName: string }[]
|
|
179
|
+
tableNames: { tableName: string; schemaName: string }[],
|
|
181
180
|
) {
|
|
182
181
|
const allColumns = await Promise.all(
|
|
183
182
|
tableNames.map(async (tableName) => {
|
|
@@ -200,7 +199,7 @@ export async function getSchemaColumnInfoSnowflake(
|
|
|
200
199
|
};
|
|
201
200
|
}),
|
|
202
201
|
};
|
|
203
|
-
})
|
|
202
|
+
}),
|
|
204
203
|
);
|
|
205
204
|
return allColumns;
|
|
206
205
|
}
|