@quillsql/node 0.5.8 → 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 +6 -2
- package/dist/db/CachedConnection.js +26 -13
- package/dist/db/Mysql.js +8 -2
- package/dist/db/Postgres.js +28 -21
- package/dist/db/Snowflake.js +2 -2
- package/dist/index.js +17 -7
- 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 +32 -23
- package/src/db/DatabaseHelper.ts +29 -30
- package/src/db/Mysql.ts +18 -14
- package/src/db/Postgres.ts +38 -40
- package/src/db/Snowflake.ts +14 -15
- package/src/index.ts +36 -21
- 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,43 +9,35 @@ 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
|
|
|
30
15
|
export class CachedConnection {
|
|
31
16
|
public databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql";
|
|
32
|
-
public pool: DatabaseConnection;
|
|
17
|
+
public pool: DatabaseConnection | null;
|
|
33
18
|
public orgId: any;
|
|
34
19
|
public ttl: number;
|
|
35
20
|
public cache: Mapable | null;
|
|
21
|
+
private config: any;
|
|
22
|
+
private activeQueries: number = 0;
|
|
23
|
+
private readonly MAX_ACTIVE_QUERIES: number = 0;
|
|
36
24
|
|
|
37
25
|
constructor(
|
|
38
26
|
databaseType: "postgresql" | "snowflake" | "bigquery" | "mysql",
|
|
39
27
|
config: any,
|
|
40
|
-
cacheConfig: Partial<CacheCredentials> = {}
|
|
28
|
+
cacheConfig: Partial<CacheCredentials> = {},
|
|
41
29
|
) {
|
|
42
30
|
this.databaseType = databaseType;
|
|
43
31
|
this.pool = connectToDatabase(databaseType, config);
|
|
32
|
+
this.config = config;
|
|
44
33
|
this.ttl = cacheConfig?.ttl ?? DEFAULT_CACHE_TTL;
|
|
45
34
|
this.cache = this.getCache(cacheConfig);
|
|
46
35
|
}
|
|
47
36
|
|
|
48
|
-
public async query(text: string
|
|
37
|
+
public async query(text: string): Promise<any> {
|
|
49
38
|
try {
|
|
39
|
+
this.activeQueries++;
|
|
40
|
+
this.pool = this.getPool();
|
|
50
41
|
if (!this.cache) {
|
|
51
42
|
return await runQueryByDatabase(this.databaseType, this.pool, text);
|
|
52
43
|
}
|
|
@@ -58,7 +49,7 @@ export class CachedConnection {
|
|
|
58
49
|
const newResult = await runQueryByDatabase(
|
|
59
50
|
this.databaseType,
|
|
60
51
|
this.pool,
|
|
61
|
-
text
|
|
52
|
+
text,
|
|
62
53
|
);
|
|
63
54
|
const newResultString: string = JSON.stringify(newResult);
|
|
64
55
|
await this.cache.set(key, newResultString, "EX", DEFAULT_CACHE_TTL);
|
|
@@ -67,13 +58,21 @@ export class CachedConnection {
|
|
|
67
58
|
} catch (err) {
|
|
68
59
|
if (isSuperset(err, PgError)) {
|
|
69
60
|
throw new PgError(
|
|
61
|
+
(err as any).message,
|
|
70
62
|
(err as any).detail,
|
|
71
63
|
(err as any).hint,
|
|
72
|
-
(err as any).position
|
|
64
|
+
(err as any).position,
|
|
73
65
|
);
|
|
74
66
|
} else if (err instanceof Error) {
|
|
75
67
|
throw new Error(err.message);
|
|
76
68
|
}
|
|
69
|
+
} finally {
|
|
70
|
+
this.activeQueries--;
|
|
71
|
+
if (this.activeQueries <= this.MAX_ACTIVE_QUERIES) {
|
|
72
|
+
if (this.databaseType.toLowerCase() === "mysql") {
|
|
73
|
+
this.close();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
77
76
|
}
|
|
78
77
|
}
|
|
79
78
|
|
|
@@ -89,14 +88,24 @@ export class CachedConnection {
|
|
|
89
88
|
}: QuillConfig["cache"]): Mapable | null {
|
|
90
89
|
if (cacheType === "redis" || cacheType === "rediss") {
|
|
91
90
|
const redisURL = `${cacheType}://${username}:${password}@${host}:${port}`;
|
|
92
|
-
const client =
|
|
91
|
+
const client = createClient({ url: redisURL });
|
|
93
92
|
client.connect();
|
|
94
93
|
return client as Mapable;
|
|
95
94
|
}
|
|
96
95
|
return null;
|
|
97
96
|
}
|
|
98
97
|
|
|
98
|
+
public getPool() {
|
|
99
|
+
if (!this.pool) {
|
|
100
|
+
this.pool = connectToDatabase(this.databaseType, this.config);
|
|
101
|
+
}
|
|
102
|
+
return this.pool;
|
|
103
|
+
}
|
|
104
|
+
|
|
99
105
|
async close() {
|
|
100
|
-
|
|
106
|
+
if (this.pool) {
|
|
107
|
+
disconnectFromDatabase(this.databaseType, this.pool);
|
|
108
|
+
this.pool = null;
|
|
109
|
+
}
|
|
101
110
|
}
|
|
102
111
|
}
|
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
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { connect } from "http2";
|
|
2
|
-
import { Client } from "../models/Client";
|
|
3
1
|
import mysql, { Pool as MysqlPool } from "mysql2";
|
|
4
2
|
import { QuillQueryResults } from "./DatabaseHelper";
|
|
5
3
|
import url from "url";
|
|
@@ -14,7 +12,7 @@ export interface MysqlConnectionConfig {
|
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
export function formatMysqlConfig(
|
|
17
|
-
connectionString: string
|
|
15
|
+
connectionString: string,
|
|
18
16
|
): MysqlConnectionConfig {
|
|
19
17
|
const parsedUrl = url.parse(connectionString);
|
|
20
18
|
const [user, password] = (parsedUrl.auth || "").split(":");
|
|
@@ -31,7 +29,7 @@ export function connectToMysql(config: MysqlConnectionConfig): MysqlPool {
|
|
|
31
29
|
const pool = mysql.createPool({
|
|
32
30
|
...config,
|
|
33
31
|
waitForConnections: true,
|
|
34
|
-
connectionLimit:
|
|
32
|
+
connectionLimit: 128,
|
|
35
33
|
queueLimit: 0,
|
|
36
34
|
});
|
|
37
35
|
return pool;
|
|
@@ -43,7 +41,7 @@ export function disconnectFromMysql(connection: MysqlPool) {
|
|
|
43
41
|
|
|
44
42
|
export async function runQueryMysql(
|
|
45
43
|
sql: string,
|
|
46
|
-
connection: MysqlPool
|
|
44
|
+
connection: MysqlPool,
|
|
47
45
|
): Promise<QuillQueryResults> {
|
|
48
46
|
const result: QuillQueryResults = await new Promise((resolve, reject) => {
|
|
49
47
|
connection.query(sql, (error, results, fields) => {
|
|
@@ -72,7 +70,7 @@ export async function runQueryMysql(
|
|
|
72
70
|
}
|
|
73
71
|
|
|
74
72
|
export async function getSchemasMysql(
|
|
75
|
-
connection: MysqlPool
|
|
73
|
+
connection: MysqlPool,
|
|
76
74
|
): Promise<string[]> {
|
|
77
75
|
const sql = `SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
|
|
78
76
|
WHERE schema_name != 'information_schema'
|
|
@@ -84,7 +82,7 @@ export async function getSchemasMysql(
|
|
|
84
82
|
|
|
85
83
|
export async function getTablesBySchemaMysql(
|
|
86
84
|
connection: MysqlPool,
|
|
87
|
-
schemaNames: string[]
|
|
85
|
+
schemaNames: string[],
|
|
88
86
|
): Promise<{ tableName: string; schemaName: string }[]> {
|
|
89
87
|
const allColumns = await Promise.all(
|
|
90
88
|
schemaNames.map(async (schema) => {
|
|
@@ -93,7 +91,7 @@ export async function getTablesBySchemaMysql(
|
|
|
93
91
|
return results.rows.map((row) => {
|
|
94
92
|
return { tableName: row.TABLE_NAME, schemaName: row.TABLE_SCHEMA };
|
|
95
93
|
});
|
|
96
|
-
})
|
|
94
|
+
}),
|
|
97
95
|
);
|
|
98
96
|
return allColumns.flat();
|
|
99
97
|
}
|
|
@@ -101,7 +99,7 @@ export async function getTablesBySchemaMysql(
|
|
|
101
99
|
export async function getColumnsByTableMysql(
|
|
102
100
|
connection: MysqlPool,
|
|
103
101
|
schemaName: string,
|
|
104
|
-
tableName: string
|
|
102
|
+
tableName: string,
|
|
105
103
|
): Promise<string[]> {
|
|
106
104
|
const sql = `SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '${schemaName}' AND TABLE_NAME = '${tableName}'`;
|
|
107
105
|
const results = await runQueryMysql(sql, connection);
|
|
@@ -112,7 +110,7 @@ export async function getForeignKeysMysql(
|
|
|
112
110
|
connection: MysqlPool,
|
|
113
111
|
schemaName: string,
|
|
114
112
|
tableName: string,
|
|
115
|
-
primaryKey: string
|
|
113
|
+
primaryKey: string,
|
|
116
114
|
): Promise<string[]> {
|
|
117
115
|
const depluralizedTableName = depluralize(tableName);
|
|
118
116
|
let sql = `SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
|
|
@@ -127,7 +125,7 @@ export async function getForeignKeysMysql(
|
|
|
127
125
|
});
|
|
128
126
|
// remove any foreignKeyStrings that are just 'id'
|
|
129
127
|
foreignKeysString = foreignKeysString.filter(
|
|
130
|
-
(key) => key !== "id" && key !== "_id_"
|
|
128
|
+
(key) => key !== "id" && key !== "_id_",
|
|
131
129
|
);
|
|
132
130
|
foreignKeysString = [...new Set(foreignKeysString)];
|
|
133
131
|
if (foreignKeysString.length === 0) {
|
|
@@ -151,7 +149,7 @@ export async function getForeignKeysMysql(
|
|
|
151
149
|
export async function getSchemaColumnInfoMysql(
|
|
152
150
|
connection: MysqlPool,
|
|
153
151
|
schemaName: string,
|
|
154
|
-
tableNames: { tableName: string; schemaName: string }[]
|
|
152
|
+
tableNames: { tableName: string; schemaName: string }[],
|
|
155
153
|
): Promise<
|
|
156
154
|
{ tableName: string; columns: { columnName: string; dataTypeID: number }[] }[]
|
|
157
155
|
> {
|
|
@@ -174,7 +172,7 @@ export async function getSchemaColumnInfoMysql(
|
|
|
174
172
|
fieldType: row.dataType,
|
|
175
173
|
})),
|
|
176
174
|
};
|
|
177
|
-
})
|
|
175
|
+
}),
|
|
178
176
|
);
|
|
179
177
|
return allColumns;
|
|
180
178
|
}
|
|
@@ -191,6 +189,10 @@ function mysqlTextDataTypeToPostgresOID(type: string): number {
|
|
|
191
189
|
return 1043;
|
|
192
190
|
case "timestamp": // date
|
|
193
191
|
return 1082;
|
|
192
|
+
case "date": // date
|
|
193
|
+
return 1082;
|
|
194
|
+
case "datetime": // date
|
|
195
|
+
return 1082;
|
|
194
196
|
default: // varchar
|
|
195
197
|
return 1043;
|
|
196
198
|
}
|
|
@@ -210,7 +212,9 @@ function mysqlDataTypeIdToPostgresType(type: number): number {
|
|
|
210
212
|
return 1043;
|
|
211
213
|
case 7: // date
|
|
212
214
|
return 1082;
|
|
213
|
-
case
|
|
215
|
+
case 10: // date
|
|
216
|
+
return 1082;
|
|
217
|
+
case 12: // date
|
|
214
218
|
return 1082;
|
|
215
219
|
default: // varchar
|
|
216
220
|
return 1043;
|