@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.
@@ -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, conn) => {
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
- let depluralizedTableName = depluralize(tableName);
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
  }
@@ -16,6 +16,10 @@
16
16
  // );
17
17
  // });
18
18
 
19
+ // afterEach(async () => {
20
+ // await quill.close();
21
+ // });
22
+
19
23
  // afterAll(() => {
20
24
  // jest.restoreAllMocks();
21
25
  // });
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- import QuillServerClient from "./clients/QuillServerClient";
2
1
  import { CacheCredentials } from "./models/Cache";
3
2
  import {
4
3
  AdditionalProcessing,
@@ -10,7 +9,7 @@ import axios from "axios";
10
9
  import "dotenv/config";
11
10
  import { mapQueries, removeFields } from "./utils/RunQueryProcesses";
12
11
  import {
13
- connectToDatabase,
12
+ connectAndRunQuery,
14
13
  getColumnInfoBySchemaByDatabase,
15
14
  getColumnsByTableByDatabase,
16
15
  getDatabaseCredentials,
@@ -18,6 +17,7 @@ import {
18
17
  getSchemasByDatabase,
19
18
  getTablesBySchemaByDatabase,
20
19
  runQueryByDatabase,
20
+ withConnection,
21
21
  } from "./db/DatabaseHelper";
22
22
  import { convertTypeToPostgres } from "./utils/schemaConversion";
23
23
 
@@ -44,9 +44,9 @@ export enum DatabaseType {
44
44
  mysql = "mysql",
45
45
  }
46
46
 
47
- export class Quill {
47
+ export class Quill implements AsyncDisposable {
48
48
  // Configure cached connection pools with the given config.
49
- public targetConnection;
49
+ private targetConnection;
50
50
  private baseUrl: string;
51
51
  private config: {
52
52
  headers: {
@@ -92,6 +92,11 @@ export class Quill {
92
92
  }: QuillQueryParams): Promise<QuillQueryResult> {
93
93
  this.targetConnection.orgId = orgId;
94
94
  let responseMetadata: any = {};
95
+
96
+ if (!metadata.task) {
97
+ return { error: "Missing task.", status: "error", data: {} };
98
+ }
99
+
95
100
  try {
96
101
  const preQueryResults = metadata.preQueries
97
102
  ? await this.runQueries(
@@ -114,7 +119,11 @@ export class Quill {
114
119
  viewQuery: metadata.preQueries ? metadata.preQueries[0] : undefined,
115
120
  });
116
121
  if (response.error) {
117
- return { status: "error", error: response.error };
122
+ return {
123
+ status: "error",
124
+ error: response.error,
125
+ data: response.metadata || {},
126
+ };
118
127
  }
119
128
  // if there is no metadata object in the response, create one
120
129
  if (response.metadata) {
@@ -153,8 +162,8 @@ export class Quill {
153
162
  } catch (err) {
154
163
  return {
155
164
  status: "error",
156
- error: (err as any).message,
157
- data: responseMetadata,
165
+ error: (err as any).response?.data?.error ?? (err as any).message,
166
+ data: responseMetadata || {},
158
167
  };
159
168
  }
160
169
  }
@@ -177,6 +186,7 @@ export class Quill {
177
186
  queryResults: [],
178
187
  };
179
188
  }
189
+
180
190
  if (runQueryConfig?.arrayToMap) {
181
191
  const mappedArray = await mapQueries(queries, this.targetConnection);
182
192
  return { ...results, queryResults: [], mappedArray };
@@ -221,8 +231,13 @@ export class Quill {
221
231
  };
222
232
  });
223
233
  return { ...table, columns: columns, rows: queryResult.rows };
224
- } catch (err) {
225
- return { ...table, error: "Error fetching columns" };
234
+ } catch (err: any) {
235
+ return {
236
+ ...table,
237
+ error: err.message
238
+ ? `Error fetching columns: ${err.message}`
239
+ : "Error fetching columns",
240
+ };
226
241
  }
227
242
  }),
228
243
  );
@@ -250,7 +265,6 @@ export class Quill {
250
265
  runQueryConfig.schema!,
251
266
  queryResult!,
252
267
  );
253
- this.targetConnection.close();
254
268
  return schemaInfo;
255
269
  } else {
256
270
  if (runQueryConfig?.limitThousand) {
@@ -309,6 +323,10 @@ export class Quill {
309
323
  return response.data;
310
324
  }
311
325
 
326
+ public async [Symbol.asyncDispose](): Promise<void> {
327
+ await this.close();
328
+ }
329
+
312
330
  public async close() {
313
331
  await this.targetConnection.close();
314
332
  }
@@ -341,6 +359,8 @@ const requireQuill = ({
341
359
 
342
360
  module.exports = requireQuill;
343
361
  module.exports.default = requireQuill;
362
+ module.exports.withConnection = withConnection;
363
+ module.exports.connectAndRunQuery = connectAndRunQuery;
344
364
  module.exports.Quill = Quill;
345
365
  module.exports.getTablesBySchemaByDatabase = getTablesBySchemaByDatabase;
346
366
  module.exports.getDatabaseCredentials = getDatabaseCredentials;
@@ -349,7 +369,6 @@ module.exports.getForiegnKeysByDatabase = getForiegnKeysByDatabase;
349
369
  module.exports.getSchemasByDatabase = getSchemasByDatabase;
350
370
  module.exports.getColumnInfoBySchemaByDatabase =
351
371
  getColumnInfoBySchemaByDatabase;
352
- module.exports.connectToDatabase = connectToDatabase;
353
372
  module.exports.runQueryByDatabase = runQueryByDatabase;
354
373
  module.exports.DatabaseType = DatabaseType;
355
374
 
@@ -17,6 +17,10 @@
17
17
  // quill.targetConnection.query = jest.fn().mockResolvedValue([]);
18
18
  // });
19
19
 
20
+ // afterEach(async () => {
21
+ // await quill.close();
22
+ // });
23
+
20
24
  // describe("query", () => {
21
25
  // it("return nothing when suppling no queries", () => {
22
26
  // const metadata = {
@@ -1,10 +1,10 @@
1
- export interface Mapable {
1
+ export interface Mappable {
2
2
  get(key: string): Promise<string | null>;
3
3
  set(
4
4
  key: string,
5
5
  value: string,
6
6
  type?: string,
7
- ttl?: number
7
+ ttl?: number,
8
8
  ): Promise<string | null>;
9
9
  }
10
10
 
@@ -15,4 +15,4 @@ export interface CacheCredentials {
15
15
  port: string;
16
16
  cacheType: string;
17
17
  ttl?: number;
18
- }
18
+ }
@@ -4,18 +4,32 @@ export class PgError extends Error {
4
4
  hint?: string;
5
5
  position?: string;
6
6
  // Add other properties if needed
7
+ constructor(
8
+ message: string,
9
+ detail?: string,
10
+ hint?: string,
11
+ position?: string,
12
+ code?: string,
13
+ ) {
14
+ super(message);
15
+ this.code = code;
16
+ this.detail = detail;
17
+ this.hint = hint;
18
+ this.position = position;
19
+ }
7
20
  }
8
21
 
9
22
  export function isSuperset(obj: any, baseClass: any): boolean {
10
- // Get the property names of the base class
11
- const baseProps = Object.getOwnPropertyNames(baseClass.prototype);
23
+ // Get the property names of the base class instance
24
+ const baseInstance = new baseClass();
25
+ const baseProps = Object.keys(baseInstance);
12
26
 
13
27
  // Check if the object has all the properties of the base class
14
28
  for (const prop of baseProps) {
15
- if (!obj.hasOwnProperty(prop)) {
29
+ if (!Object.prototype.hasOwnProperty.call(obj, prop)) {
16
30
  return false;
17
31
  }
18
32
  }
19
33
 
20
34
  return true;
21
- }
35
+ }
@@ -1,6 +1,6 @@
1
1
  import { CachedConnection } from "../db/CachedConnection";
2
2
 
3
- interface TableSchemaInfo {
3
+ export interface TableSchemaInfo {
4
4
  fieldType: string;
5
5
  name: string;
6
6
  displayName: string;
@@ -9,7 +9,7 @@ interface TableSchemaInfo {
9
9
 
10
10
  export function removeFields(queryResults: any, fieldsToRemove: string[]): any {
11
11
  const fields = queryResults.fields.filter(
12
- (field: { name: any }) => !fieldsToRemove.includes(field.name)
12
+ (field: { name: any }) => !fieldsToRemove.includes(field.name),
13
13
  );
14
14
  const rows = queryResults.rows.map((row: any) => {
15
15
  fieldsToRemove.forEach((field) => {
@@ -22,7 +22,7 @@ export function removeFields(queryResults: any, fieldsToRemove: string[]): any {
22
22
 
23
23
  export async function mapQueries(
24
24
  queries: string[],
25
- targetConnection: CachedConnection
25
+ targetConnection: CachedConnection,
26
26
  ): Promise<any[]> {
27
27
  const mappedArray = [];
28
28
  for (let i = 0; i < queries.length; i++) {
@@ -10,4 +10,4 @@ export function depluralize(text: string): string {
10
10
  return text.slice(0, -1);
11
11
  }
12
12
  return text;
13
- }
13
+ }