@quillsql/node 0.5.9 → 0.6.1
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 +11 -6
- package/dist/db/CachedConnection.js +12 -26
- package/dist/db/DatabaseHelper.d.ts +3 -1
- package/dist/db/DatabaseHelper.js +21 -2
- package/dist/db/Postgres.js +28 -21
- package/dist/db/Snowflake.js +2 -2
- package/dist/index.d.ts +4 -3
- package/dist/index.ispec.js +3 -0
- package/dist/index.js +21 -7
- package/dist/index.uspec.js +3 -0
- package/dist/models/Cache.d.ts +1 -1
- 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 +27 -37
- package/src/db/DatabaseHelper.ts +58 -33
- package/src/db/Mysql.ts +0 -2
- package/src/db/Postgres.ts +38 -40
- package/src/db/Snowflake.ts +14 -15
- package/src/index.ispec.ts +4 -0
- package/src/index.ts +30 -11
- package/src/index.uspec.ts +4 -0
- package/src/models/Cache.ts +3 -3
- 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,55 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Mapable, CacheCredentials } from "../models/Cache";
|
|
1
|
+
import { Mappable, 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,
|
|
9
8
|
disconnectFromDatabase,
|
|
10
9
|
runQueryByDatabase,
|
|
11
10
|
} from "./DatabaseHelper";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
}
|
|
11
|
+
import { PostgresConnectionConfig } from "./Postgres";
|
|
12
|
+
import { SnowflakeConnectionConfig } from "./Snowflake";
|
|
13
|
+
import { BigQueryConfig } from "./BigQuery";
|
|
14
|
+
import { MysqlConnectionConfig } from "./Mysql";
|
|
26
15
|
|
|
27
16
|
/** The TTL for new cache entries (default: 1h) */
|
|
28
17
|
const DEFAULT_CACHE_TTL = 24 * 60 * 60;
|
|
29
18
|
|
|
30
19
|
export class CachedConnection {
|
|
31
20
|
public databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql";
|
|
32
|
-
public pool: DatabaseConnection
|
|
21
|
+
public readonly pool: DatabaseConnection;
|
|
33
22
|
public orgId: any;
|
|
34
23
|
public ttl: number;
|
|
35
|
-
public cache:
|
|
36
|
-
|
|
24
|
+
public cache: Mappable | null;
|
|
25
|
+
|
|
26
|
+
private _isClosed: boolean = false;
|
|
27
|
+
public get isClosed(): boolean {
|
|
28
|
+
return this._isClosed;
|
|
29
|
+
}
|
|
37
30
|
|
|
38
31
|
constructor(
|
|
39
32
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
40
|
-
config:
|
|
33
|
+
config:
|
|
34
|
+
| PostgresConnectionConfig
|
|
35
|
+
| SnowflakeConnectionConfig
|
|
36
|
+
| BigQueryConfig
|
|
37
|
+
| MysqlConnectionConfig,
|
|
41
38
|
cacheConfig: Partial<CacheCredentials> = {},
|
|
42
39
|
) {
|
|
43
40
|
this.databaseType = databaseType;
|
|
44
41
|
this.pool = connectToDatabase(databaseType, config);
|
|
45
|
-
this.config = config;
|
|
46
42
|
this.ttl = cacheConfig?.ttl ?? DEFAULT_CACHE_TTL;
|
|
47
43
|
this.cache = this.getCache(cacheConfig);
|
|
48
44
|
}
|
|
49
45
|
|
|
50
|
-
public async query(text: string
|
|
46
|
+
public async query(text: string): Promise<any> {
|
|
51
47
|
try {
|
|
52
|
-
|
|
48
|
+
if (this.isClosed) {
|
|
49
|
+
throw new Error("Connection is closed");
|
|
50
|
+
}
|
|
53
51
|
if (!this.cache) {
|
|
54
52
|
return await runQueryByDatabase(this.databaseType, this.pool, text);
|
|
55
53
|
}
|
|
@@ -70,6 +68,7 @@ export class CachedConnection {
|
|
|
70
68
|
} catch (err) {
|
|
71
69
|
if (isSuperset(err, PgError)) {
|
|
72
70
|
throw new PgError(
|
|
71
|
+
(err as any).message,
|
|
73
72
|
(err as any).detail,
|
|
74
73
|
(err as any).hint,
|
|
75
74
|
(err as any).position,
|
|
@@ -77,10 +76,6 @@ export class CachedConnection {
|
|
|
77
76
|
} else if (err instanceof Error) {
|
|
78
77
|
throw new Error(err.message);
|
|
79
78
|
}
|
|
80
|
-
} finally {
|
|
81
|
-
if (this.databaseType.toLowerCase() === "mysql") {
|
|
82
|
-
this.close();
|
|
83
|
-
}
|
|
84
79
|
}
|
|
85
80
|
}
|
|
86
81
|
|
|
@@ -93,27 +88,22 @@ export class CachedConnection {
|
|
|
93
88
|
host,
|
|
94
89
|
port,
|
|
95
90
|
cacheType,
|
|
96
|
-
}: QuillConfig["cache"]):
|
|
91
|
+
}: QuillConfig["cache"]): Mappable | null {
|
|
97
92
|
if (cacheType === "redis" || cacheType === "rediss") {
|
|
98
93
|
const redisURL = `${cacheType}://${username}:${password}@${host}:${port}`;
|
|
99
94
|
const client = createClient({ url: redisURL });
|
|
100
95
|
client.connect();
|
|
101
|
-
return client as
|
|
96
|
+
return client as Mappable;
|
|
102
97
|
}
|
|
103
98
|
return null;
|
|
104
99
|
}
|
|
105
100
|
|
|
106
101
|
public getPool() {
|
|
107
|
-
if (!this.pool) {
|
|
108
|
-
this.pool = connectToDatabase(this.databaseType, this.config);
|
|
109
|
-
}
|
|
110
102
|
return this.pool;
|
|
111
103
|
}
|
|
112
104
|
|
|
113
105
|
async close() {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
this.pool = null;
|
|
117
|
-
}
|
|
106
|
+
disconnectFromDatabase(this.databaseType, this.pool);
|
|
107
|
+
this._isClosed = true;
|
|
118
108
|
}
|
|
119
109
|
}
|
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,13 +64,12 @@ 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
|
|
72
71
|
| BigQueryConfig
|
|
73
|
-
| MysqlConnectionConfig
|
|
74
|
-
| undefined {
|
|
72
|
+
| MysqlConnectionConfig {
|
|
75
73
|
switch (databaseType.toLowerCase()) {
|
|
76
74
|
case "postgres":
|
|
77
75
|
return formatPostgresConfig(connectionString);
|
|
@@ -84,7 +82,7 @@ export function getDatabaseCredentials(
|
|
|
84
82
|
case "mysql":
|
|
85
83
|
return formatMysqlConfig(connectionString);
|
|
86
84
|
default:
|
|
87
|
-
|
|
85
|
+
throw new Error("Invalid database type");
|
|
88
86
|
}
|
|
89
87
|
}
|
|
90
88
|
|
|
@@ -94,7 +92,7 @@ export function connectToDatabase(
|
|
|
94
92
|
| PostgresConnectionConfig
|
|
95
93
|
| SnowflakeConnectionConfig
|
|
96
94
|
| BigQueryConfig
|
|
97
|
-
| MysqlConnectionConfig
|
|
95
|
+
| MysqlConnectionConfig,
|
|
98
96
|
): DatabaseConnection {
|
|
99
97
|
switch (databaseType.toLowerCase()) {
|
|
100
98
|
case "postgres":
|
|
@@ -112,10 +110,24 @@ export function connectToDatabase(
|
|
|
112
110
|
}
|
|
113
111
|
}
|
|
114
112
|
|
|
113
|
+
export async function withConnection<T>(
|
|
114
|
+
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
115
|
+
connectionString: string,
|
|
116
|
+
callback: (connection: DatabaseConnection) => T,
|
|
117
|
+
): Promise<T> {
|
|
118
|
+
const config = getDatabaseCredentials(databaseType, connectionString);
|
|
119
|
+
const connection = connectToDatabase(databaseType, config);
|
|
120
|
+
try {
|
|
121
|
+
return await callback(connection);
|
|
122
|
+
} finally {
|
|
123
|
+
await disconnectFromDatabase(databaseType, connection);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
115
127
|
export function runQueryByDatabase(
|
|
116
128
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
117
129
|
connection: DatabaseConnection,
|
|
118
|
-
sql: string
|
|
130
|
+
sql: string,
|
|
119
131
|
): Promise<QuillQueryResults> | undefined {
|
|
120
132
|
switch (databaseType.toLowerCase()) {
|
|
121
133
|
case "postgres":
|
|
@@ -133,9 +145,22 @@ export function runQueryByDatabase(
|
|
|
133
145
|
}
|
|
134
146
|
}
|
|
135
147
|
|
|
148
|
+
export async function connectAndRunQuery(
|
|
149
|
+
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
150
|
+
connectionString: string,
|
|
151
|
+
sql: string,
|
|
152
|
+
): Promise<QuillQueryResults | undefined> {
|
|
153
|
+
return withConnection(
|
|
154
|
+
databaseType,
|
|
155
|
+
connectionString,
|
|
156
|
+
async (connection) =>
|
|
157
|
+
await runQueryByDatabase(databaseType, connection, sql),
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
136
161
|
export function disconnectFromDatabase(
|
|
137
162
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
138
|
-
database: DatabaseConnection
|
|
163
|
+
database: DatabaseConnection,
|
|
139
164
|
) {
|
|
140
165
|
switch (databaseType.toLowerCase()) {
|
|
141
166
|
case "postgres":
|
|
@@ -155,7 +180,7 @@ export function disconnectFromDatabase(
|
|
|
155
180
|
|
|
156
181
|
export async function getSchemasByDatabase(
|
|
157
182
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
158
|
-
connection: DatabaseConnection
|
|
183
|
+
connection: DatabaseConnection,
|
|
159
184
|
): Promise<string[] | undefined> {
|
|
160
185
|
switch (databaseType.toLowerCase()) {
|
|
161
186
|
case "postgres":
|
|
@@ -177,33 +202,33 @@ export async function getSchemasByDatabase(
|
|
|
177
202
|
export async function getTablesBySchemaByDatabase(
|
|
178
203
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
179
204
|
connection: DatabaseConnection,
|
|
180
|
-
schemaName: string | string[]
|
|
205
|
+
schemaName: string | string[],
|
|
181
206
|
): Promise<string[] | { tableName: string; schemaName: string }[] | undefined> {
|
|
182
207
|
switch (databaseType.toLowerCase()) {
|
|
183
208
|
case "postgres":
|
|
184
209
|
return getTablesBySchemaPostgres(
|
|
185
210
|
connection as Pool,
|
|
186
|
-
schemaName as string[]
|
|
211
|
+
schemaName as string[],
|
|
187
212
|
);
|
|
188
213
|
case "postgresql":
|
|
189
214
|
return getTablesBySchemaPostgres(
|
|
190
215
|
connection as Pool,
|
|
191
|
-
schemaName as string[]
|
|
216
|
+
schemaName as string[],
|
|
192
217
|
);
|
|
193
218
|
case "snowflake":
|
|
194
219
|
return getTablesBySchemaSnowflake(
|
|
195
220
|
connection as snowflake.Connection,
|
|
196
|
-
schemaName as string[]
|
|
221
|
+
schemaName as string[],
|
|
197
222
|
);
|
|
198
223
|
case "bigquery":
|
|
199
224
|
return getTablesBySchemaBigQuery(
|
|
200
225
|
connection as BigQuery,
|
|
201
|
-
schemaName as string[]
|
|
226
|
+
schemaName as string[],
|
|
202
227
|
);
|
|
203
228
|
case "mysql":
|
|
204
229
|
return getTablesBySchemaMysql(
|
|
205
230
|
connection as MysqlPool,
|
|
206
|
-
schemaName as string[]
|
|
231
|
+
schemaName as string[],
|
|
207
232
|
);
|
|
208
233
|
default:
|
|
209
234
|
return undefined;
|
|
@@ -215,38 +240,38 @@ export async function getColumnsByTableByDatabase(
|
|
|
215
240
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
216
241
|
connection: DatabaseConnection,
|
|
217
242
|
schemaName: string,
|
|
218
|
-
tableName: string
|
|
243
|
+
tableName: string,
|
|
219
244
|
): Promise<string[] | undefined> {
|
|
220
245
|
switch (databaseType.toLowerCase()) {
|
|
221
246
|
case "postgres":
|
|
222
247
|
return getColumnsByTablePostgres(
|
|
223
248
|
connection as Pool,
|
|
224
249
|
schemaName,
|
|
225
|
-
tableName
|
|
250
|
+
tableName,
|
|
226
251
|
);
|
|
227
252
|
case "postgresql":
|
|
228
253
|
return getColumnsByTablePostgres(
|
|
229
254
|
connection as Pool,
|
|
230
255
|
schemaName,
|
|
231
|
-
tableName
|
|
256
|
+
tableName,
|
|
232
257
|
);
|
|
233
258
|
case "snowflake":
|
|
234
259
|
return getColumnsByTableSnowflake(
|
|
235
260
|
connection as snowflake.Connection,
|
|
236
261
|
schemaName,
|
|
237
|
-
tableName
|
|
262
|
+
tableName,
|
|
238
263
|
);
|
|
239
264
|
case "bigquery":
|
|
240
265
|
return getColumnsByTableBigQuery(
|
|
241
266
|
connection as BigQuery,
|
|
242
267
|
schemaName,
|
|
243
|
-
tableName
|
|
268
|
+
tableName,
|
|
244
269
|
);
|
|
245
270
|
case "mysql":
|
|
246
271
|
return getColumnsByTableMysql(
|
|
247
272
|
connection as MysqlPool,
|
|
248
273
|
schemaName,
|
|
249
|
-
tableName
|
|
274
|
+
tableName,
|
|
250
275
|
);
|
|
251
276
|
default:
|
|
252
277
|
return undefined;
|
|
@@ -258,7 +283,7 @@ export async function getForiegnKeysByDatabase(
|
|
|
258
283
|
connection: DatabaseConnection,
|
|
259
284
|
schemaName: string,
|
|
260
285
|
tableName: string,
|
|
261
|
-
primaryKey: string
|
|
286
|
+
primaryKey: string,
|
|
262
287
|
): Promise<string[] | undefined> {
|
|
263
288
|
switch (databaseType.toLowerCase()) {
|
|
264
289
|
case "postgres":
|
|
@@ -266,35 +291,35 @@ export async function getForiegnKeysByDatabase(
|
|
|
266
291
|
connection as Pool,
|
|
267
292
|
schemaName,
|
|
268
293
|
tableName,
|
|
269
|
-
primaryKey
|
|
294
|
+
primaryKey,
|
|
270
295
|
);
|
|
271
296
|
case "postgresql":
|
|
272
297
|
return getForeignKeysPostgres(
|
|
273
298
|
connection as Pool,
|
|
274
299
|
schemaName,
|
|
275
300
|
tableName,
|
|
276
|
-
primaryKey
|
|
301
|
+
primaryKey,
|
|
277
302
|
);
|
|
278
303
|
case "snowflake":
|
|
279
304
|
return getForeignKeysSnowflake(
|
|
280
305
|
connection as snowflake.Connection,
|
|
281
306
|
schemaName,
|
|
282
307
|
tableName,
|
|
283
|
-
primaryKey
|
|
308
|
+
primaryKey,
|
|
284
309
|
);
|
|
285
310
|
case "bigquery":
|
|
286
311
|
return getForeignKeysBigQuery(
|
|
287
312
|
connection as BigQuery,
|
|
288
313
|
schemaName,
|
|
289
314
|
tableName,
|
|
290
|
-
primaryKey
|
|
315
|
+
primaryKey,
|
|
291
316
|
);
|
|
292
317
|
case "mysql":
|
|
293
318
|
return getForeignKeysMysql(
|
|
294
319
|
connection as MysqlPool,
|
|
295
320
|
schemaName,
|
|
296
321
|
tableName,
|
|
297
|
-
primaryKey
|
|
322
|
+
primaryKey,
|
|
298
323
|
);
|
|
299
324
|
default:
|
|
300
325
|
return undefined;
|
|
@@ -305,38 +330,38 @@ export function getColumnInfoBySchemaByDatabase(
|
|
|
305
330
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
306
331
|
connection: DatabaseConnection,
|
|
307
332
|
schemaName: string,
|
|
308
|
-
tables: string[] | { tableName: string; schemaName: string }[]
|
|
333
|
+
tables: string[] | { tableName: string; schemaName: string }[],
|
|
309
334
|
) {
|
|
310
335
|
switch (databaseType.toLowerCase()) {
|
|
311
336
|
case "postgres":
|
|
312
337
|
return getSchemaColumnInfoPostgress(
|
|
313
338
|
connection as Pool,
|
|
314
339
|
schemaName,
|
|
315
|
-
tables as { tableName: string; schemaName: string }[]
|
|
340
|
+
tables as { tableName: string; schemaName: string }[],
|
|
316
341
|
);
|
|
317
342
|
case "postgresql":
|
|
318
343
|
return getSchemaColumnInfoPostgress(
|
|
319
344
|
connection as Pool,
|
|
320
345
|
schemaName,
|
|
321
|
-
tables as { tableName: string; schemaName: string }[]
|
|
346
|
+
tables as { tableName: string; schemaName: string }[],
|
|
322
347
|
);
|
|
323
348
|
case "snowflake":
|
|
324
349
|
return getSchemaColumnInfoSnowflake(
|
|
325
350
|
connection as snowflake.Connection,
|
|
326
351
|
schemaName,
|
|
327
|
-
tables as { tableName: string; schemaName: string }[]
|
|
352
|
+
tables as { tableName: string; schemaName: string }[],
|
|
328
353
|
);
|
|
329
354
|
case "bigquery":
|
|
330
355
|
return getSchemaColumnInfoBigQuery(
|
|
331
356
|
connection as BigQuery,
|
|
332
357
|
schemaName,
|
|
333
|
-
tables as { tableName: string; schemaName: string }[]
|
|
358
|
+
tables as { tableName: string; schemaName: string }[],
|
|
334
359
|
);
|
|
335
360
|
case "mysql":
|
|
336
361
|
return getSchemaColumnInfoMysql(
|
|
337
362
|
connection as MysqlPool,
|
|
338
363
|
schemaName,
|
|
339
|
-
tables as { tableName: string; schemaName: string }[]
|
|
364
|
+
tables as { tableName: string; schemaName: string }[],
|
|
340
365
|
);
|
|
341
366
|
default:
|
|
342
367
|
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
|
+
// }
|