@quillsql/node 0.3.8 → 0.4.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/db/BigQuery.js +46 -34
- package/dist/db/DatabaseHelper.js +49 -49
- package/dist/db/Mysql.js +14 -9
- package/dist/db/Postgres.js +14 -9
- package/dist/db/Snowflake.js +18 -8
- package/dist/index.js +62 -35
- package/dist/index.uspec.js +1 -1
- package/dist/utils/RunQueryProcesses.js +2 -17
- package/dist/utils/schemaConversion.js +15 -0
- package/examples/node-server/app.ts +36 -3
- package/package.json +2 -2
- package/src/db/BigQuery.ts +60 -41
- package/src/db/DatabaseHelper.ts +74 -62
- package/src/db/Mysql.ts +19 -12
- package/src/db/Postgres.ts +22 -13
- package/src/db/Snowflake.ts +22 -10
- package/src/index.ts +102 -44
- package/src/index.uspec.ts +1 -1
- package/src/models/Quill.ts +12 -0
- package/src/utils/RunQueryProcesses.ts +0 -23
- package/src/utils/schemaConversion.ts +11 -0
package/dist/db/BigQuery.js
CHANGED
|
@@ -9,9 +9,33 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.getSchemaColumnInfoBigQuery = exports.getForeignKeysBigQuery = exports.
|
|
12
|
+
exports.getSchemaColumnInfoBigQuery = exports.getForeignKeysBigQuery = exports.getColumnsByTableBigQuery = exports.getTablesBySchemaBigQuery = exports.getSchemaBigQuery = exports.runQueryBigQuery = exports.connectToBigQuery = exports.formatBigQueryConfig = void 0;
|
|
13
13
|
const bigquery_1 = require("@google-cloud/bigquery");
|
|
14
14
|
const textProcessing_1 = require("../utils/textProcessing");
|
|
15
|
+
function formatBigQueryConfig(connectionString) {
|
|
16
|
+
const jsonStartIndex = connectionString.indexOf("{");
|
|
17
|
+
if (jsonStartIndex === -1) {
|
|
18
|
+
throw new Error("Invalid input string. No JSON data found.");
|
|
19
|
+
}
|
|
20
|
+
const datasetName = connectionString.substring(0, jsonStartIndex).trim();
|
|
21
|
+
const jsonString = connectionString.substring(jsonStartIndex);
|
|
22
|
+
try {
|
|
23
|
+
const serviceAccount = JSON.parse(jsonString);
|
|
24
|
+
// Validate if required fields are present
|
|
25
|
+
if (!serviceAccount.project_id || !serviceAccount.private_key) {
|
|
26
|
+
throw new Error("Invalid service account JSON. Required fields are missing.");
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
datasetName,
|
|
30
|
+
projectId: serviceAccount.project_id,
|
|
31
|
+
credentials: serviceAccount,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
throw new Error("Failed to parse JSON string: " + error);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.formatBigQueryConfig = formatBigQueryConfig;
|
|
15
39
|
function connectToBigQuery(config) {
|
|
16
40
|
return new bigquery_1.BigQuery(config);
|
|
17
41
|
}
|
|
@@ -55,11 +79,16 @@ function getSchemaBigQuery(bigQuery) {
|
|
|
55
79
|
});
|
|
56
80
|
}
|
|
57
81
|
exports.getSchemaBigQuery = getSchemaBigQuery;
|
|
58
|
-
function getTablesBySchemaBigQuery(bigQuery,
|
|
82
|
+
function getTablesBySchemaBigQuery(bigQuery, schemaNames) {
|
|
59
83
|
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
84
|
+
const allColumns = yield Promise.all(schemaNames.map((schema) => __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
const sql = `SELECT table_name FROM ${schema}.INFORMATION_SCHEMA.TABLES WHERE table_type = 'BASE TABLE'`;
|
|
86
|
+
const rows = yield bigQuery.query(sql);
|
|
87
|
+
return rows[0].map((row) => {
|
|
88
|
+
return { tableName: row.table_name, schemaName: schema };
|
|
89
|
+
});
|
|
90
|
+
})));
|
|
91
|
+
return allColumns.flat();
|
|
63
92
|
});
|
|
64
93
|
}
|
|
65
94
|
exports.getTablesBySchemaBigQuery = getTablesBySchemaBigQuery;
|
|
@@ -71,30 +100,6 @@ function getColumnsByTableBigQuery(bigQuery, schemaName, tableName) {
|
|
|
71
100
|
});
|
|
72
101
|
}
|
|
73
102
|
exports.getColumnsByTableBigQuery = getColumnsByTableBigQuery;
|
|
74
|
-
function formatBigQueryConfig(connectionString) {
|
|
75
|
-
const jsonStartIndex = connectionString.indexOf("{");
|
|
76
|
-
if (jsonStartIndex === -1) {
|
|
77
|
-
throw new Error("Invalid input string. No JSON data found.");
|
|
78
|
-
}
|
|
79
|
-
const datasetName = connectionString.substring(0, jsonStartIndex).trim();
|
|
80
|
-
const jsonString = connectionString.substring(jsonStartIndex);
|
|
81
|
-
try {
|
|
82
|
-
const serviceAccount = JSON.parse(jsonString);
|
|
83
|
-
// Validate if required fields are present
|
|
84
|
-
if (!serviceAccount.project_id || !serviceAccount.private_key) {
|
|
85
|
-
throw new Error("Invalid service account JSON. Required fields are missing.");
|
|
86
|
-
}
|
|
87
|
-
return {
|
|
88
|
-
datasetName,
|
|
89
|
-
projectId: serviceAccount.project_id,
|
|
90
|
-
credentials: serviceAccount,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
catch (error) {
|
|
94
|
-
throw new Error("Failed to parse JSON string: " + error);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
exports.formatBigQueryConfig = formatBigQueryConfig;
|
|
98
103
|
function getForeignKeysBigQuery(connection, schemaName, tableName, primaryKey) {
|
|
99
104
|
return __awaiter(this, void 0, void 0, function* () {
|
|
100
105
|
const depluralizedTableName = (0, textProcessing_1.depluralize)(tableName);
|
|
@@ -132,18 +137,18 @@ function getSchemaColumnInfoBigQuery(connection, schemaName, tableNames) {
|
|
|
132
137
|
const allColumns = yield Promise.all(tableNames.map((tableName) => __awaiter(this, void 0, void 0, function* () {
|
|
133
138
|
const query = `
|
|
134
139
|
SELECT column_name as columnName, data_type as dataType
|
|
135
|
-
FROM ${schemaName}.INFORMATION_SCHEMA.COLUMNS
|
|
136
|
-
WHERE table_name = '${tableName}'
|
|
140
|
+
FROM ${tableName.schemaName}.INFORMATION_SCHEMA.COLUMNS
|
|
141
|
+
WHERE table_name = '${tableName.tableName}'
|
|
137
142
|
ORDER BY ordinal_position;
|
|
138
143
|
`;
|
|
139
144
|
const results = yield runQueryBigQuery(query, connection);
|
|
140
145
|
return {
|
|
141
|
-
tableName
|
|
142
|
-
displayName: tableName
|
|
146
|
+
tableName: `${tableName.schemaName}.${tableName.tableName}`,
|
|
147
|
+
displayName: `${tableName.schemaName}.${tableName.tableName}`,
|
|
143
148
|
columns: results.rows.map((row) => ({
|
|
144
149
|
columnName: row.columnName,
|
|
145
150
|
displayName: row.columnName,
|
|
146
|
-
|
|
151
|
+
dataTypeID: convertBigQueryTypeToPostgresOID(row.dataType),
|
|
147
152
|
fieldType: row.dataType,
|
|
148
153
|
})),
|
|
149
154
|
};
|
|
@@ -168,11 +173,18 @@ function inferType(elem) {
|
|
|
168
173
|
// Check if the number is a float or an integer
|
|
169
174
|
return Number.isInteger(elem) ? 23 : 700; // 23: integer, 700: real
|
|
170
175
|
}
|
|
176
|
+
if (typeof elem === "object") {
|
|
177
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(elem.value))
|
|
178
|
+
return 1082; // date
|
|
179
|
+
}
|
|
171
180
|
if (typeof elem === "string") {
|
|
172
181
|
// Attempt to infer date, time, and timestamp formats
|
|
173
182
|
// Date in YYYY-MM-DD format
|
|
174
183
|
if (/^\d{4}-\d{2}-\d{2}$/.test(elem))
|
|
175
184
|
return 1082; // date
|
|
185
|
+
// Date in MM\DD\YYYY or MM\DD\YY format
|
|
186
|
+
if (/^\d{2}\/\d{2}\/\d{2,4}$/.test(elem))
|
|
187
|
+
return 1082; // date
|
|
176
188
|
// Timestamp in YYYY-MM-DDTHH:MM:SS[.fraction] format
|
|
177
189
|
if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?$/.test(elem))
|
|
178
190
|
return 1114; // timestamp without timezone
|
|
@@ -17,22 +17,22 @@ const Mysql_1 = require("./Mysql");
|
|
|
17
17
|
var DatabaseType;
|
|
18
18
|
(function (DatabaseType) {
|
|
19
19
|
DatabaseType["postgres"] = "postgres";
|
|
20
|
-
DatabaseType["postgresql"] = "
|
|
21
|
-
DatabaseType["snowflake"] = "
|
|
22
|
-
DatabaseType["bigquery"] = "
|
|
23
|
-
DatabaseType["mysql"] = "
|
|
20
|
+
DatabaseType["postgresql"] = "postgresql";
|
|
21
|
+
DatabaseType["snowflake"] = "snowflake";
|
|
22
|
+
DatabaseType["bigquery"] = "bigquery";
|
|
23
|
+
DatabaseType["mysql"] = "mysql";
|
|
24
24
|
})(DatabaseType || (exports.DatabaseType = DatabaseType = {}));
|
|
25
25
|
function getDatabaseCredentials(databaseType, connectionString) {
|
|
26
|
-
switch (databaseType) {
|
|
26
|
+
switch (databaseType.toLowerCase()) {
|
|
27
27
|
case "postgres":
|
|
28
28
|
return (0, Postgres_1.formatPostgresConfig)(connectionString);
|
|
29
|
-
case "
|
|
29
|
+
case "postgresql":
|
|
30
30
|
return (0, Postgres_1.formatPostgresConfig)(connectionString);
|
|
31
|
-
case "
|
|
31
|
+
case "snowflake":
|
|
32
32
|
return (0, Snowflake_1.formatSnowflakeConfig)(connectionString);
|
|
33
|
-
case "
|
|
33
|
+
case "bigquery":
|
|
34
34
|
return (0, BigQuery_1.formatBigQueryConfig)(connectionString);
|
|
35
|
-
case "
|
|
35
|
+
case "mysql":
|
|
36
36
|
return (0, Mysql_1.formatMysqlConfig)(connectionString);
|
|
37
37
|
default:
|
|
38
38
|
return undefined;
|
|
@@ -40,16 +40,16 @@ function getDatabaseCredentials(databaseType, connectionString) {
|
|
|
40
40
|
}
|
|
41
41
|
exports.getDatabaseCredentials = getDatabaseCredentials;
|
|
42
42
|
function connectToDatabase(databaseType, config) {
|
|
43
|
-
switch (databaseType) {
|
|
43
|
+
switch (databaseType.toLowerCase()) {
|
|
44
44
|
case "postgres":
|
|
45
45
|
return (0, Postgres_1.connectToPostgres)(config);
|
|
46
|
-
case "
|
|
46
|
+
case "postgresql":
|
|
47
47
|
return (0, Postgres_1.connectToPostgres)(config);
|
|
48
|
-
case "
|
|
48
|
+
case "snowflake":
|
|
49
49
|
return (0, Snowflake_1.connectToSnowflake)(config);
|
|
50
|
-
case "
|
|
50
|
+
case "bigquery":
|
|
51
51
|
return (0, BigQuery_1.connectToBigQuery)(config);
|
|
52
|
-
case "
|
|
52
|
+
case "mysql":
|
|
53
53
|
return (0, Mysql_1.connectToMysql)(config);
|
|
54
54
|
default:
|
|
55
55
|
return (0, Postgres_1.connectToPostgres)(config);
|
|
@@ -57,16 +57,16 @@ function connectToDatabase(databaseType, config) {
|
|
|
57
57
|
}
|
|
58
58
|
exports.connectToDatabase = connectToDatabase;
|
|
59
59
|
function runQueryByDatabase(databaseType, connection, sql) {
|
|
60
|
-
switch (databaseType) {
|
|
60
|
+
switch (databaseType.toLowerCase()) {
|
|
61
61
|
case "postgres":
|
|
62
62
|
return (0, Postgres_1.runQueryPostgres)(sql, connection);
|
|
63
|
-
case "
|
|
63
|
+
case "postgresql":
|
|
64
64
|
return (0, Postgres_1.runQueryPostgres)(sql, connection);
|
|
65
|
-
case "
|
|
65
|
+
case "snowflake":
|
|
66
66
|
return (0, Snowflake_1.runQuerySnowflake)(sql, connection);
|
|
67
|
-
case "
|
|
67
|
+
case "bigquery":
|
|
68
68
|
return (0, BigQuery_1.runQueryBigQuery)(sql, connection);
|
|
69
|
-
case "
|
|
69
|
+
case "mysql":
|
|
70
70
|
return (0, Mysql_1.runQueryMysql)(sql, connection);
|
|
71
71
|
default:
|
|
72
72
|
return undefined;
|
|
@@ -74,16 +74,16 @@ function runQueryByDatabase(databaseType, connection, sql) {
|
|
|
74
74
|
}
|
|
75
75
|
exports.runQueryByDatabase = runQueryByDatabase;
|
|
76
76
|
function disconnectFromDatabase(databaseType, database) {
|
|
77
|
-
switch (databaseType) {
|
|
77
|
+
switch (databaseType.toLowerCase()) {
|
|
78
78
|
case "postgres":
|
|
79
79
|
return (0, Postgres_1.disconnectFromPostgres)(database);
|
|
80
|
-
case "
|
|
80
|
+
case "postgresql":
|
|
81
81
|
return (0, Postgres_1.disconnectFromPostgres)(database);
|
|
82
|
-
case "
|
|
82
|
+
case "snowflake":
|
|
83
83
|
return (0, Snowflake_1.disconnectFromSnowflake)(database);
|
|
84
|
-
case "
|
|
84
|
+
case "bigquery":
|
|
85
85
|
return; // BigQuery does not need to be disconnected
|
|
86
|
-
case "
|
|
86
|
+
case "mysql":
|
|
87
87
|
return (0, Mysql_1.disconnectFromMysql)(database);
|
|
88
88
|
default:
|
|
89
89
|
return undefined;
|
|
@@ -92,16 +92,16 @@ function disconnectFromDatabase(databaseType, database) {
|
|
|
92
92
|
exports.disconnectFromDatabase = disconnectFromDatabase;
|
|
93
93
|
function getSchemasByDatabase(databaseType, connection) {
|
|
94
94
|
return __awaiter(this, void 0, void 0, function* () {
|
|
95
|
-
switch (databaseType) {
|
|
95
|
+
switch (databaseType.toLowerCase()) {
|
|
96
96
|
case "postgres":
|
|
97
97
|
return (0, Postgres_1.getSchemasPostgres)(connection);
|
|
98
|
-
case "
|
|
98
|
+
case "postgresql":
|
|
99
99
|
return (0, Postgres_1.getSchemasPostgres)(connection);
|
|
100
|
-
case "
|
|
100
|
+
case "snowflake":
|
|
101
101
|
return (0, Snowflake_1.getSchemasSnowflake)(connection);
|
|
102
|
-
case "
|
|
102
|
+
case "bigquery":
|
|
103
103
|
return (0, BigQuery_1.getSchemaBigQuery)(connection);
|
|
104
|
-
case "
|
|
104
|
+
case "mysql":
|
|
105
105
|
return (0, Mysql_1.getSchemasMysql)(connection);
|
|
106
106
|
default:
|
|
107
107
|
return undefined;
|
|
@@ -112,16 +112,16 @@ exports.getSchemasByDatabase = getSchemasByDatabase;
|
|
|
112
112
|
// INFORMATION SCHEMA SELECTS
|
|
113
113
|
function getTablesBySchemaByDatabase(databaseType, connection, schemaName) {
|
|
114
114
|
return __awaiter(this, void 0, void 0, function* () {
|
|
115
|
-
switch (databaseType) {
|
|
115
|
+
switch (databaseType.toLowerCase()) {
|
|
116
116
|
case "postgres":
|
|
117
117
|
return (0, Postgres_1.getTablesBySchemaPostgres)(connection, schemaName);
|
|
118
|
-
case "
|
|
118
|
+
case "postgresql":
|
|
119
119
|
return (0, Postgres_1.getTablesBySchemaPostgres)(connection, schemaName);
|
|
120
|
-
case "
|
|
120
|
+
case "snowflake":
|
|
121
121
|
return (0, Snowflake_1.getTablesBySchemaSnowflake)(connection, schemaName);
|
|
122
|
-
case "
|
|
122
|
+
case "bigquery":
|
|
123
123
|
return (0, BigQuery_1.getTablesBySchemaBigQuery)(connection, schemaName);
|
|
124
|
-
case "
|
|
124
|
+
case "mysql":
|
|
125
125
|
return (0, Mysql_1.getTablesBySchemaMysql)(connection, schemaName);
|
|
126
126
|
default:
|
|
127
127
|
return undefined;
|
|
@@ -132,16 +132,16 @@ exports.getTablesBySchemaByDatabase = getTablesBySchemaByDatabase;
|
|
|
132
132
|
// INFORMATION SCHEMA SELECTS
|
|
133
133
|
function getColumnsByTableByDatabase(databaseType, connection, schemaName, tableName) {
|
|
134
134
|
return __awaiter(this, void 0, void 0, function* () {
|
|
135
|
-
switch (databaseType) {
|
|
135
|
+
switch (databaseType.toLowerCase()) {
|
|
136
136
|
case "postgres":
|
|
137
137
|
return (0, Postgres_1.getColumnsByTablePostgres)(connection, schemaName, tableName);
|
|
138
|
-
case "
|
|
138
|
+
case "postgresql":
|
|
139
139
|
return (0, Postgres_1.getColumnsByTablePostgres)(connection, schemaName, tableName);
|
|
140
|
-
case "
|
|
140
|
+
case "snowflake":
|
|
141
141
|
return (0, Snowflake_1.getColumnsByTableSnowflake)(connection, schemaName, tableName);
|
|
142
|
-
case "
|
|
142
|
+
case "bigquery":
|
|
143
143
|
return (0, BigQuery_1.getColumnsByTableBigQuery)(connection, schemaName, tableName);
|
|
144
|
-
case "
|
|
144
|
+
case "mysql":
|
|
145
145
|
return (0, Mysql_1.getColumnsByTableMysql)(connection, schemaName, tableName);
|
|
146
146
|
default:
|
|
147
147
|
return undefined;
|
|
@@ -151,16 +151,16 @@ function getColumnsByTableByDatabase(databaseType, connection, schemaName, table
|
|
|
151
151
|
exports.getColumnsByTableByDatabase = getColumnsByTableByDatabase;
|
|
152
152
|
function getForiegnKeysByDatabase(databaseType, connection, schemaName, tableName, primaryKey) {
|
|
153
153
|
return __awaiter(this, void 0, void 0, function* () {
|
|
154
|
-
switch (databaseType) {
|
|
154
|
+
switch (databaseType.toLowerCase()) {
|
|
155
155
|
case "postgres":
|
|
156
156
|
return (0, Postgres_1.getForeignKeysPostgres)(connection, schemaName, tableName, primaryKey);
|
|
157
|
-
case "
|
|
157
|
+
case "postgresql":
|
|
158
158
|
return (0, Postgres_1.getForeignKeysPostgres)(connection, schemaName, tableName, primaryKey);
|
|
159
|
-
case "
|
|
159
|
+
case "snowflake":
|
|
160
160
|
return (0, Snowflake_1.getForeignKeysSnowflake)(connection, schemaName, tableName, primaryKey);
|
|
161
|
-
case "
|
|
161
|
+
case "bigquery":
|
|
162
162
|
return (0, BigQuery_1.getForeignKeysBigQuery)(connection, schemaName, tableName, primaryKey);
|
|
163
|
-
case "
|
|
163
|
+
case "mysql":
|
|
164
164
|
return (0, Mysql_1.getForeignKeysMysql)(connection, schemaName, tableName, primaryKey);
|
|
165
165
|
default:
|
|
166
166
|
return undefined;
|
|
@@ -169,16 +169,16 @@ function getForiegnKeysByDatabase(databaseType, connection, schemaName, tableNam
|
|
|
169
169
|
}
|
|
170
170
|
exports.getForiegnKeysByDatabase = getForiegnKeysByDatabase;
|
|
171
171
|
function getColumnInfoBySchemaByDatabase(databaseType, connection, schemaName, tables) {
|
|
172
|
-
switch (databaseType) {
|
|
172
|
+
switch (databaseType.toLowerCase()) {
|
|
173
173
|
case "postgres":
|
|
174
174
|
return (0, Postgres_1.getSchemaColumnInfoPostgress)(connection, schemaName, tables);
|
|
175
|
-
case "
|
|
175
|
+
case "postgresql":
|
|
176
176
|
return (0, Postgres_1.getSchemaColumnInfoPostgress)(connection, schemaName, tables);
|
|
177
|
-
case "
|
|
177
|
+
case "snowflake":
|
|
178
178
|
return (0, Snowflake_1.getSchemaColumnInfoSnowflake)(connection, schemaName, tables);
|
|
179
|
-
case "
|
|
179
|
+
case "bigquery":
|
|
180
180
|
return (0, BigQuery_1.getSchemaColumnInfoBigQuery)(connection, schemaName, tables);
|
|
181
|
-
case "
|
|
181
|
+
case "mysql":
|
|
182
182
|
return (0, Mysql_1.getSchemaColumnInfoMysql)(connection, schemaName, tables);
|
|
183
183
|
default:
|
|
184
184
|
return undefined;
|
package/dist/db/Mysql.js
CHANGED
|
@@ -73,11 +73,16 @@ function getSchemasMysql(connection) {
|
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
exports.getSchemasMysql = getSchemasMysql;
|
|
76
|
-
function getTablesBySchemaMysql(connection,
|
|
76
|
+
function getTablesBySchemaMysql(connection, schemaNames) {
|
|
77
77
|
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
const allColumns = yield Promise.all(schemaNames.map((schema) => __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
const sql = `SELECT TABLE_NAME, TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '${schema}'`;
|
|
80
|
+
const results = yield runQueryMysql(sql, connection);
|
|
81
|
+
return results.rows.map((row) => {
|
|
82
|
+
return { tableName: row.TABLE_NAME, schemaName: row.TABLE_SCHEMA };
|
|
83
|
+
});
|
|
84
|
+
})));
|
|
85
|
+
return allColumns.flat();
|
|
81
86
|
});
|
|
82
87
|
}
|
|
83
88
|
exports.getTablesBySchemaMysql = getTablesBySchemaMysql;
|
|
@@ -130,17 +135,17 @@ function getSchemaColumnInfoMysql(connection, schemaName, tableNames) {
|
|
|
130
135
|
const query = `
|
|
131
136
|
SELECT COLUMN_NAME as columnName,
|
|
132
137
|
DATA_TYPE as dataType FROM INFORMATION_SCHEMA.COLUMNS
|
|
133
|
-
WHERE TABLE_SCHEMA = '${schemaName}'
|
|
134
|
-
AND TABLE_NAME = '${tableName}'
|
|
138
|
+
WHERE TABLE_SCHEMA = '${tableName.schemaName}'
|
|
139
|
+
AND TABLE_NAME = '${tableName.tableName}'
|
|
135
140
|
`;
|
|
136
141
|
const results = yield runQueryMysql(query, connection);
|
|
137
142
|
return {
|
|
138
|
-
tableName
|
|
139
|
-
displayName: tableName
|
|
143
|
+
tableName: `${tableName.schemaName}.${tableName.tableName}`,
|
|
144
|
+
displayName: `${tableName.schemaName}.${tableName.tableName}`,
|
|
140
145
|
columns: results.rows.map((row) => ({
|
|
141
146
|
columnName: row.columnName,
|
|
142
147
|
displayName: row.columnName,
|
|
143
|
-
|
|
148
|
+
dataTypeID: mysqlTextDataTypeToPostgresOID(row.dataType),
|
|
144
149
|
fieldType: row.dataType,
|
|
145
150
|
})),
|
|
146
151
|
};
|
package/dist/db/Postgres.js
CHANGED
|
@@ -43,11 +43,16 @@ function getSchemasPostgres(pool) {
|
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
exports.getSchemasPostgres = getSchemasPostgres;
|
|
46
|
-
function getTablesBySchemaPostgres(pool,
|
|
46
|
+
function getTablesBySchemaPostgres(pool, schemaNames) {
|
|
47
47
|
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
const allColumns = yield Promise.all(schemaNames.map((schema) => __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
const sql = `SELECT table_name, table_schema FROM information_schema.tables WHERE table_schema = '${schema}'`;
|
|
50
|
+
const results = yield runQueryPostgres(sql, pool);
|
|
51
|
+
return results.rows.map((row) => {
|
|
52
|
+
return { tableName: row.table_name, schemaName: row.table_schema };
|
|
53
|
+
});
|
|
54
|
+
})));
|
|
55
|
+
return allColumns.flat();
|
|
51
56
|
});
|
|
52
57
|
}
|
|
53
58
|
exports.getTablesBySchemaPostgres = getTablesBySchemaPostgres;
|
|
@@ -99,14 +104,14 @@ function getSchemaColumnInfoPostgress(pool, schemaName, tableNames) {
|
|
|
99
104
|
const query = `
|
|
100
105
|
SELECT column_name as "columnName", udt_name as "fieldType"
|
|
101
106
|
FROM information_schema.columns
|
|
102
|
-
WHERE table_schema = '${schemaName}'
|
|
103
|
-
AND table_name = '${tableName}'
|
|
107
|
+
WHERE table_schema = '${tableName.schemaName}'
|
|
108
|
+
AND table_name = '${tableName.tableName}'
|
|
104
109
|
ORDER BY ordinal_position;
|
|
105
110
|
`;
|
|
106
111
|
const results = yield runQueryPostgres(query, pool);
|
|
107
112
|
return {
|
|
108
|
-
tableName
|
|
109
|
-
displayName: tableName
|
|
113
|
+
tableName: `${tableName.schemaName}.${tableName.tableName}`,
|
|
114
|
+
displayName: `${tableName.schemaName}.${tableName.tableName}`,
|
|
110
115
|
columns: results.rows.map((row) => {
|
|
111
116
|
var _a;
|
|
112
117
|
let pgType = (_a = pgtypes_1.PG_TYPES.find((pgType) => {
|
|
@@ -118,7 +123,7 @@ function getSchemaColumnInfoPostgress(pool, schemaName, tableNames) {
|
|
|
118
123
|
return {
|
|
119
124
|
columnName: row.columnName,
|
|
120
125
|
displayName: row.columnName,
|
|
121
|
-
|
|
126
|
+
dataTypeID: pgType,
|
|
122
127
|
fieldType: row.fieldType,
|
|
123
128
|
};
|
|
124
129
|
}),
|
package/dist/db/Snowflake.js
CHANGED
|
@@ -67,11 +67,21 @@ function getSchemasSnowflake(connection) {
|
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
exports.getSchemasSnowflake = getSchemasSnowflake;
|
|
70
|
-
function getTablesBySchemaSnowflake(connection,
|
|
70
|
+
function getTablesBySchemaSnowflake(connection, schemaNames) {
|
|
71
71
|
return __awaiter(this, void 0, void 0, function* () {
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
const allColumns = yield Promise.all(schemaNames.map((schema) => __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
const query = `SELECT
|
|
74
|
+
TABLE_NAME as "tableName",
|
|
75
|
+
TABLE_SCHEMA as "schemaName"
|
|
76
|
+
FROM INFORMATION_SCHEMA.TABLES
|
|
77
|
+
WHERE TABLE_SCHEMA = '${schema}';
|
|
78
|
+
`;
|
|
79
|
+
const results = yield runQuerySnowflake(query, connection);
|
|
80
|
+
return results.rows.map((row) => {
|
|
81
|
+
return { tableName: row.tableName, schemaName: row.schemaName };
|
|
82
|
+
});
|
|
83
|
+
})));
|
|
84
|
+
return allColumns.flat();
|
|
75
85
|
});
|
|
76
86
|
}
|
|
77
87
|
exports.getTablesBySchemaSnowflake = getTablesBySchemaSnowflake;
|
|
@@ -156,18 +166,18 @@ function getSchemaColumnInfoSnowflake(connection, schemaName, tableNames) {
|
|
|
156
166
|
const query = `SELECT
|
|
157
167
|
COLUMN_NAME as "columnName", DATA_TYPE as "dataType"
|
|
158
168
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
159
|
-
WHERE TABLE_SCHEMA = '${schemaName}' AND TABLE_NAME = '${tableName}';
|
|
169
|
+
WHERE TABLE_SCHEMA = '${tableName.schemaName}' AND TABLE_NAME = '${tableName.tableName}';
|
|
160
170
|
`;
|
|
161
171
|
const results = yield runQuerySnowflake(query, connection);
|
|
162
172
|
return {
|
|
163
|
-
tableName
|
|
164
|
-
displayName: tableName
|
|
173
|
+
tableName: `${tableName.schemaName}.${tableName.tableName}`,
|
|
174
|
+
displayName: `${tableName.schemaName}.${tableName.tableName}`,
|
|
165
175
|
columns: results.rows.map((row) => {
|
|
166
176
|
const postgresType = POSTGRES_SNOWFLAKE_MAP[row.dataType];
|
|
167
177
|
return {
|
|
168
178
|
columnName: row.columnName,
|
|
169
179
|
displayName: row.columnName,
|
|
170
|
-
|
|
180
|
+
dataTypeID: postgresType,
|
|
171
181
|
fieldType: row.dataType,
|
|
172
182
|
};
|
|
173
183
|
}),
|
package/dist/index.js
CHANGED
|
@@ -16,8 +16,8 @@ const CachedConnection_1 = require("./db/CachedConnection");
|
|
|
16
16
|
const axios_1 = __importDefault(require("axios"));
|
|
17
17
|
require("dotenv/config");
|
|
18
18
|
const RunQueryProcesses_1 = require("./utils/RunQueryProcesses");
|
|
19
|
-
const pgtypes_1 = require("./assets/pgtypes");
|
|
20
19
|
const DatabaseHelper_1 = require("./db/DatabaseHelper");
|
|
20
|
+
const schemaConversion_1 = require("./utils/schemaConversion");
|
|
21
21
|
const HOST = process.env.ENV === "development"
|
|
22
22
|
? "http://localhost:8080"
|
|
23
23
|
: "https://quill-344421.uc.r.appspot.com";
|
|
@@ -25,44 +25,35 @@ const HOST = process.env.ENV === "development"
|
|
|
25
25
|
* Quill - Fullstack API Platform for Dashboards and Reporting.
|
|
26
26
|
*/
|
|
27
27
|
class QuillClass {
|
|
28
|
-
constructor(privateKey, databaseConnectionString, cache = {},
|
|
28
|
+
constructor(privateKey, databaseType, databaseConnectionString, databaseCredentials, cache = {}, metadataServerURL) {
|
|
29
29
|
this.baseUrl = metadataServerURL ? metadataServerURL : HOST;
|
|
30
30
|
this.config = { headers: { Authorization: `Bearer ${privateKey}` } };
|
|
31
|
-
|
|
31
|
+
let credentials = databaseCredentials;
|
|
32
|
+
if (databaseConnectionString) {
|
|
33
|
+
credentials = (0, DatabaseHelper_1.getDatabaseCredentials)(databaseType, databaseConnectionString);
|
|
34
|
+
}
|
|
35
|
+
this.targetConnection = new CachedConnection_1.CachedConnection(databaseType, credentials, cache);
|
|
32
36
|
}
|
|
33
37
|
query({ orgId, metadata }) {
|
|
34
38
|
var _a, _b, _c;
|
|
35
39
|
return __awaiter(this, void 0, void 0, function* () {
|
|
36
40
|
this.targetConnection.orgId = orgId;
|
|
37
41
|
try {
|
|
38
|
-
// Initial Query Request
|
|
39
|
-
const limitedQueries = metadata.preQueries
|
|
40
|
-
? (_a = metadata.preQueries) === null || _a === void 0 ? void 0 : _a.map((query) => query + " limit 1")
|
|
41
|
-
: [];
|
|
42
42
|
const preQueryResults = metadata.preQueries
|
|
43
|
-
? yield this.runQueries(
|
|
44
|
-
:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
name: field.name,
|
|
53
|
-
displayName: field.name,
|
|
54
|
-
isVisible: true,
|
|
55
|
-
field: field.name,
|
|
56
|
-
};
|
|
57
|
-
})
|
|
58
|
-
: metadata.columns;
|
|
59
|
-
const response = yield this.postQuill(metadata.task, Object.assign(Object.assign({}, metadata), { orgId,
|
|
60
|
-
columns, viewQuery: metadata.preQueries ? metadata.preQueries[0] : undefined }));
|
|
43
|
+
? yield this.runQueries(metadata.preQueries, this.targetConnection.databaseType, metadata.databaseType, metadata.runQueryConfig)
|
|
44
|
+
: {};
|
|
45
|
+
if ((_a = metadata.runQueryConfig) === null || _a === void 0 ? void 0 : _a.overridePost) {
|
|
46
|
+
return {
|
|
47
|
+
data: { queryResults: preQueryResults },
|
|
48
|
+
status: "success",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const response = yield this.postQuill(metadata.task, Object.assign(Object.assign(Object.assign({}, metadata), preQueryResults), { orgId, viewQuery: metadata.preQueries ? metadata.preQueries[0] : undefined }));
|
|
61
52
|
// if there is no metadata object in the response, create one
|
|
62
53
|
if (!response.metadata) {
|
|
63
54
|
response.metadata = {};
|
|
64
55
|
}
|
|
65
|
-
const results = yield this.runQueries(response.queries, response.metadata.runQueryConfig);
|
|
56
|
+
const results = yield this.runQueries(response.queries, this.targetConnection.databaseType, metadata.databaseType, response.metadata.runQueryConfig);
|
|
66
57
|
// QUICK JANKY FIX TO UPDATE METADATA AFTER GETTING MAPPED ARRAYS
|
|
67
58
|
if (results.mappedArray &&
|
|
68
59
|
((_c = (_b = response.metadata) === null || _b === void 0 ? void 0 : _b.runQueryConfig) === null || _c === void 0 ? void 0 : _c.arrayToMap)) {
|
|
@@ -94,28 +85,64 @@ class QuillClass {
|
|
|
94
85
|
}
|
|
95
86
|
});
|
|
96
87
|
}
|
|
97
|
-
runQueries(queries, runQueryConfig) {
|
|
88
|
+
runQueries(queries, pkDatabaseType, databaseType, runQueryConfig) {
|
|
98
89
|
return __awaiter(this, void 0, void 0, function* () {
|
|
99
90
|
let results;
|
|
100
91
|
if (!queries)
|
|
101
92
|
return Object.assign(Object.assign({}, results), { queryResults: [] });
|
|
102
|
-
if (
|
|
103
|
-
|
|
93
|
+
if (databaseType &&
|
|
94
|
+
databaseType.toLowerCase() !== pkDatabaseType.toLowerCase()) {
|
|
95
|
+
return {
|
|
96
|
+
dbMismatched: true,
|
|
97
|
+
backendDatbaseType: pkDatabaseType,
|
|
98
|
+
queryResults: [],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
104
101
|
if (runQueryConfig === null || runQueryConfig === void 0 ? void 0 : runQueryConfig.arrayToMap) {
|
|
105
|
-
const mappedArray = yield (0, RunQueryProcesses_1.mapQueries)(queries,
|
|
102
|
+
const mappedArray = yield (0, RunQueryProcesses_1.mapQueries)(queries, this.targetConnection);
|
|
106
103
|
return Object.assign(Object.assign({}, results), { queryResults: [], mappedArray });
|
|
107
104
|
}
|
|
105
|
+
else if (runQueryConfig === null || runQueryConfig === void 0 ? void 0 : runQueryConfig.getColumns) {
|
|
106
|
+
const queryResult = yield this.targetConnection.query(`${queries[0]} limit 1`);
|
|
107
|
+
const columns = queryResult.fields.map((field) => {
|
|
108
|
+
return {
|
|
109
|
+
fieldType: (0, schemaConversion_1.convertTypeToPostgres)(field.dataTypeID),
|
|
110
|
+
name: field.name,
|
|
111
|
+
displayName: field.name,
|
|
112
|
+
isVisible: true,
|
|
113
|
+
field: field.name,
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
return { columns };
|
|
117
|
+
}
|
|
118
|
+
else if (runQueryConfig === null || runQueryConfig === void 0 ? void 0 : runQueryConfig.getTables) {
|
|
119
|
+
const queryResult = yield (0, DatabaseHelper_1.getTablesBySchemaByDatabase)(this.targetConnection.databaseType, this.targetConnection.pool, runQueryConfig.schemaNames || runQueryConfig.schema);
|
|
120
|
+
const schemaInfo = yield (0, DatabaseHelper_1.getColumnInfoBySchemaByDatabase)(this.targetConnection.databaseType, this.targetConnection.pool, runQueryConfig.schema, queryResult);
|
|
121
|
+
return schemaInfo;
|
|
122
|
+
}
|
|
108
123
|
else {
|
|
124
|
+
if (runQueryConfig === null || runQueryConfig === void 0 ? void 0 : runQueryConfig.limitThousand) {
|
|
125
|
+
queries = queries.map((query) => {
|
|
126
|
+
return query.replace(/;/, "") + " limit 1000;";
|
|
127
|
+
});
|
|
128
|
+
}
|
|
109
129
|
const queryResults = yield Promise.all(queries.map((query) => __awaiter(this, void 0, void 0, function* () {
|
|
110
130
|
return yield this.targetConnection.query(query);
|
|
111
131
|
})));
|
|
112
132
|
results = Object.assign(Object.assign({}, results), { queryResults });
|
|
113
|
-
if (runQueryConfig === null || runQueryConfig === void 0 ? void 0 : runQueryConfig.getSchema) {
|
|
114
|
-
results = Object.assign(Object.assign({}, results), { columns: yield (0, RunQueryProcesses_1.getTableSchema)(queryResults[0], this.targetConnection) });
|
|
115
|
-
}
|
|
116
133
|
if (runQueryConfig === null || runQueryConfig === void 0 ? void 0 : runQueryConfig.removeFields) {
|
|
117
134
|
results = Object.assign(Object.assign({}, results), { queryResults: (0, RunQueryProcesses_1.removeFields)(queryResults, runQueryConfig.removeFields) });
|
|
118
135
|
}
|
|
136
|
+
if (runQueryConfig === null || runQueryConfig === void 0 ? void 0 : runQueryConfig.convertDatatypes) {
|
|
137
|
+
results = queryResults.map((result) => {
|
|
138
|
+
return {
|
|
139
|
+
fields: result.fields.map((field) => {
|
|
140
|
+
return Object.assign(Object.assign({}, field), { fieldType: (0, schemaConversion_1.convertTypeToPostgres)(field.dataTypeID), isVisible: true, field: field.name, displayName: field.name, name: field.name });
|
|
141
|
+
}),
|
|
142
|
+
rows: result.rows,
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
}
|
|
119
146
|
}
|
|
120
147
|
return results;
|
|
121
148
|
});
|
|
@@ -133,8 +160,8 @@ class QuillClass {
|
|
|
133
160
|
}
|
|
134
161
|
}
|
|
135
162
|
exports.default = QuillClass;
|
|
136
|
-
const Quill = ({ privateKey, databaseConnectionString, cache, databaseType, metadataServerURL, }) => {
|
|
137
|
-
return new QuillClass(privateKey, databaseConnectionString,
|
|
163
|
+
const Quill = ({ privateKey, databaseConnectionString, databaseConfig, cache, databaseType, metadataServerURL, }) => {
|
|
164
|
+
return new QuillClass(privateKey, databaseType, databaseConnectionString, databaseConfig, cache, metadataServerURL);
|
|
138
165
|
};
|
|
139
166
|
module.exports = Quill;
|
|
140
167
|
module.exports.Quill = Quill;
|
package/dist/index.uspec.js
CHANGED
|
@@ -9,7 +9,7 @@ jest.mock(".");
|
|
|
9
9
|
describe("Quill", () => {
|
|
10
10
|
let quill;
|
|
11
11
|
beforeEach(() => {
|
|
12
|
-
quill = new _1.default("dummy_private_key", "dummy_db_url", {},
|
|
12
|
+
quill = new _1.default("dummy_private_key", DatabaseHelper_1.DatabaseType.postgres, "dummy_db_url", {}, undefined);
|
|
13
13
|
quill.targetConnection.query = jest.fn().mockResolvedValue([]);
|
|
14
14
|
});
|
|
15
15
|
describe("query", () => {
|