@restura/core 0.1.0-alpha.11 → 0.1.0-alpha.13
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/index.js +288 -91
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +288 -91
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -1246,6 +1246,10 @@ function convertTable(table) {
|
|
|
1246
1246
|
// src/restura/sql/PsqlEngine.ts
|
|
1247
1247
|
var import_core_utils5 = require("@redskytech/core-utils");
|
|
1248
1248
|
|
|
1249
|
+
// src/restura/sql/PsqlPool.ts
|
|
1250
|
+
var import_pg = __toESM(require("pg"));
|
|
1251
|
+
var import_pg_format2 = __toESM(require("pg-format"));
|
|
1252
|
+
|
|
1249
1253
|
// src/restura/sql/PsqlUtils.ts
|
|
1250
1254
|
var import_pg_format = __toESM(require("pg-format"));
|
|
1251
1255
|
function escapeColumnName(columnName) {
|
|
@@ -1281,7 +1285,9 @@ function isValueNumber2(value) {
|
|
|
1281
1285
|
function SQL(strings, ...values) {
|
|
1282
1286
|
let query = strings[0];
|
|
1283
1287
|
values.forEach((value, index) => {
|
|
1284
|
-
if (
|
|
1288
|
+
if (typeof value === "boolean") {
|
|
1289
|
+
query += value;
|
|
1290
|
+
} else if (typeof value === "number") {
|
|
1285
1291
|
query += value;
|
|
1286
1292
|
} else {
|
|
1287
1293
|
query += import_pg_format.default.literal(value);
|
|
@@ -1291,6 +1297,76 @@ function SQL(strings, ...values) {
|
|
|
1291
1297
|
return query;
|
|
1292
1298
|
}
|
|
1293
1299
|
|
|
1300
|
+
// src/restura/sql/PsqlPool.ts
|
|
1301
|
+
var { Pool } = import_pg.default;
|
|
1302
|
+
var PsqlPool = class {
|
|
1303
|
+
constructor(poolConfig) {
|
|
1304
|
+
this.poolConfig = poolConfig;
|
|
1305
|
+
this.pool = new Pool(poolConfig);
|
|
1306
|
+
this.queryOne("SELECT NOW();", [], { isSystemUser: true, role: "", host: "localhost", ipAddress: "" }).then(() => {
|
|
1307
|
+
logger.info("Connected to PostgreSQL database");
|
|
1308
|
+
}).catch((error) => {
|
|
1309
|
+
logger.error("Error connecting to database", error);
|
|
1310
|
+
process.exit(1);
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1314
|
+
async queryOne(query, options, requesterDetails) {
|
|
1315
|
+
const formattedQuery = questionMarksToOrderedParams(query);
|
|
1316
|
+
this.logSqlStatement(formattedQuery, options, requesterDetails);
|
|
1317
|
+
try {
|
|
1318
|
+
const response = await this.pool.query(formattedQuery, options);
|
|
1319
|
+
if (response.rows.length === 0) throw new RsError("NOT_FOUND", "No results found");
|
|
1320
|
+
else if (response.rows.length > 1) throw new RsError("DUPLICATE", "More than one result found");
|
|
1321
|
+
return response.rows[0];
|
|
1322
|
+
} catch (error) {
|
|
1323
|
+
console.error(error, query, options);
|
|
1324
|
+
if (RsError.isRsError(error)) throw error;
|
|
1325
|
+
if ((error == null ? void 0 : error.routine) === "_bt_check_unique") {
|
|
1326
|
+
throw new RsError("DUPLICATE", error.message);
|
|
1327
|
+
}
|
|
1328
|
+
throw new RsError("DATABASE_ERROR", `${error.message}`);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1332
|
+
async runQuery(query, options, requesterDetails) {
|
|
1333
|
+
const formattedQuery = questionMarksToOrderedParams(query);
|
|
1334
|
+
this.logSqlStatement(formattedQuery, options, requesterDetails);
|
|
1335
|
+
const queryUpdated = query.replace(/[\t\n]/g, " ");
|
|
1336
|
+
console.log(queryUpdated, options);
|
|
1337
|
+
try {
|
|
1338
|
+
const response = await this.pool.query(formattedQuery, options);
|
|
1339
|
+
return response.rows;
|
|
1340
|
+
} catch (error) {
|
|
1341
|
+
console.error(error, query, options);
|
|
1342
|
+
if ((error == null ? void 0 : error.routine) === "_bt_check_unique") {
|
|
1343
|
+
throw new RsError("DUPLICATE", error.message);
|
|
1344
|
+
}
|
|
1345
|
+
throw new RsError("DATABASE_ERROR", `${error.message}`);
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
logSqlStatement(query, options, requesterDetails, prefix = "") {
|
|
1349
|
+
if (logger.level !== "silly") return;
|
|
1350
|
+
let sqlStatement = "";
|
|
1351
|
+
if (options.length === 0) {
|
|
1352
|
+
sqlStatement = query;
|
|
1353
|
+
} else {
|
|
1354
|
+
let stringIndex = 0;
|
|
1355
|
+
sqlStatement = query.replace(/\$\d+/g, () => {
|
|
1356
|
+
const value = options[stringIndex++];
|
|
1357
|
+
if (typeof value === "number") return value.toString();
|
|
1358
|
+
return import_pg_format2.default.literal(value);
|
|
1359
|
+
});
|
|
1360
|
+
}
|
|
1361
|
+
let initiator = "Anonymous";
|
|
1362
|
+
if ("userId" in requesterDetails && requesterDetails.userId)
|
|
1363
|
+
initiator = `User Id (${requesterDetails.userId.toString()})`;
|
|
1364
|
+
if ("isSystemUser" in requesterDetails && requesterDetails.isSystemUser) initiator = "SYSTEM";
|
|
1365
|
+
logger.silly(`${prefix}query by ${initiator}, Query ->
|
|
1366
|
+
${sqlStatement}`);
|
|
1367
|
+
}
|
|
1368
|
+
};
|
|
1369
|
+
|
|
1294
1370
|
// src/restura/sql/SqlEngine.ts
|
|
1295
1371
|
var import_core_utils4 = require("@redskytech/core-utils");
|
|
1296
1372
|
var SqlEngine = class {
|
|
@@ -1395,6 +1471,57 @@ var SqlEngine = class {
|
|
|
1395
1471
|
// src/restura/sql/filterPsqlParser.ts
|
|
1396
1472
|
var import_pegjs = __toESM(require("pegjs"));
|
|
1397
1473
|
var filterSqlGrammar = `
|
|
1474
|
+
{
|
|
1475
|
+
// ported from pg-format but intentionally will add double quotes to every column
|
|
1476
|
+
function quoteSqlIdentity(value) {
|
|
1477
|
+
if (value === undefined || value === null) {
|
|
1478
|
+
throw new Error('SQL identifier cannot be null or undefined');
|
|
1479
|
+
} else if (value === false) {
|
|
1480
|
+
return '"f"';
|
|
1481
|
+
} else if (value === true) {
|
|
1482
|
+
return '"t"';
|
|
1483
|
+
} else if (value instanceof Date) {
|
|
1484
|
+
// return '"' + formatDate(value.toISOString()) + '"';
|
|
1485
|
+
} else if (value instanceof Buffer) {
|
|
1486
|
+
throw new Error('SQL identifier cannot be a buffer');
|
|
1487
|
+
} else if (Array.isArray(value) === true) {
|
|
1488
|
+
var temp = [];
|
|
1489
|
+
for (var i = 0; i < value.length; i++) {
|
|
1490
|
+
if (Array.isArray(value[i]) === true) {
|
|
1491
|
+
throw new Error('Nested array to grouped list conversion is not supported for SQL identifier');
|
|
1492
|
+
} else {
|
|
1493
|
+
// temp.push(quoteIdent(value[i]));
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
return temp.toString();
|
|
1497
|
+
} else if (value === Object(value)) {
|
|
1498
|
+
throw new Error('SQL identifier cannot be an object');
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
var ident = value.toString().slice(0); // create copy
|
|
1502
|
+
|
|
1503
|
+
// do not quote a valid, unquoted identifier
|
|
1504
|
+
// if (/^[a-z_][a-z0-9_$]*$/.test(ident) === true && isReserved(ident) === false) {
|
|
1505
|
+
// return ident;
|
|
1506
|
+
// }
|
|
1507
|
+
|
|
1508
|
+
var quoted = '"';
|
|
1509
|
+
|
|
1510
|
+
for (var i = 0; i < ident.length; i++) {
|
|
1511
|
+
var c = ident[i];
|
|
1512
|
+
if (c === '"') {
|
|
1513
|
+
quoted += c + c;
|
|
1514
|
+
} else {
|
|
1515
|
+
quoted += c;
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
quoted += '"';
|
|
1520
|
+
|
|
1521
|
+
return quoted;
|
|
1522
|
+
};
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1398
1525
|
start = expressionList
|
|
1399
1526
|
|
|
1400
1527
|
expressionList =
|
|
@@ -1413,9 +1540,9 @@ negate = "!"
|
|
|
1413
1540
|
operator = "and"i / "or"i
|
|
1414
1541
|
|
|
1415
1542
|
|
|
1416
|
-
column = left:text "." right:text { return \`\${
|
|
1543
|
+
column = left:text "." right:text { return \`\${quoteSqlIdentity(left)}.\${quoteSqlIdentity(right)}\`; }
|
|
1417
1544
|
/
|
|
1418
|
-
text:text { return
|
|
1545
|
+
text:text { return quoteSqlIdentity(text); }
|
|
1419
1546
|
|
|
1420
1547
|
|
|
1421
1548
|
text = text:[a-z0-9-_:@]i+ { return text.join("");}
|
|
@@ -1441,18 +1568,155 @@ var filterPsqlParser = import_pegjs.default.generate(filterSqlGrammar, {
|
|
|
1441
1568
|
var filterPsqlParser_default = filterPsqlParser;
|
|
1442
1569
|
|
|
1443
1570
|
// src/restura/sql/PsqlEngine.ts
|
|
1571
|
+
var import_pg_diff_sync = __toESM(require("@wmfs/pg-diff-sync"));
|
|
1572
|
+
var import_pg_info = __toESM(require("@wmfs/pg-info"));
|
|
1573
|
+
var { Client } = "pg";
|
|
1574
|
+
var systemUser = {
|
|
1575
|
+
role: "",
|
|
1576
|
+
host: "",
|
|
1577
|
+
ipAddress: "",
|
|
1578
|
+
isSystemUser: true
|
|
1579
|
+
};
|
|
1444
1580
|
var PsqlEngine = class extends SqlEngine {
|
|
1445
1581
|
constructor(psqlConnectionPool) {
|
|
1446
1582
|
super();
|
|
1447
1583
|
this.psqlConnectionPool = psqlConnectionPool;
|
|
1448
1584
|
}
|
|
1449
|
-
async
|
|
1450
|
-
|
|
1451
|
-
|
|
1585
|
+
async createDatabaseFromSchema(schema, connection) {
|
|
1586
|
+
const sqlFullStatement = this.generateDatabaseSchemaFromSchema(schema);
|
|
1587
|
+
await connection.runQuery(sqlFullStatement, [], systemUser);
|
|
1588
|
+
return sqlFullStatement;
|
|
1452
1589
|
}
|
|
1453
1590
|
generateDatabaseSchemaFromSchema(schema) {
|
|
1454
|
-
|
|
1455
|
-
|
|
1591
|
+
const sqlStatements = [];
|
|
1592
|
+
const enums = [];
|
|
1593
|
+
const indexes = [];
|
|
1594
|
+
for (const table of schema.database) {
|
|
1595
|
+
let sql = `CREATE TABLE "${table.name}"
|
|
1596
|
+
( `;
|
|
1597
|
+
const tableColumns = [];
|
|
1598
|
+
for (const column of table.columns) {
|
|
1599
|
+
let columnSql = "";
|
|
1600
|
+
if (column.type === "ENUM") {
|
|
1601
|
+
enums.push(`CREATE TYPE ${schemaToPsqlType(column, table.name)} AS ENUM (${column.value});`);
|
|
1602
|
+
}
|
|
1603
|
+
columnSql += ` "${column.name}" ${schemaToPsqlType(column, table.name)}`;
|
|
1604
|
+
let value = column.value;
|
|
1605
|
+
if (column.type === "JSON") value = "";
|
|
1606
|
+
if (column.type === "JSONB") value = "";
|
|
1607
|
+
if (column.type === "DECIMAL" && value) {
|
|
1608
|
+
value = value.replace("-", ",").replace(/['"]/g, "");
|
|
1609
|
+
}
|
|
1610
|
+
if (value && column.type !== "ENUM") {
|
|
1611
|
+
columnSql += `(${value})`;
|
|
1612
|
+
} else if (column.length) columnSql += `(${column.length})`;
|
|
1613
|
+
if (column.isPrimary) {
|
|
1614
|
+
columnSql += " PRIMARY KEY ";
|
|
1615
|
+
}
|
|
1616
|
+
if (column.isUnique) {
|
|
1617
|
+
columnSql += ` CONSTRAINT "${table.name}_${column.name}_unique_index" UNIQUE `;
|
|
1618
|
+
}
|
|
1619
|
+
if (column.isNullable) columnSql += " NULL";
|
|
1620
|
+
else columnSql += " NOT NULL";
|
|
1621
|
+
if (column.default) columnSql += ` DEFAULT '${column.default}'`;
|
|
1622
|
+
tableColumns.push(columnSql);
|
|
1623
|
+
}
|
|
1624
|
+
sql += tableColumns.join(", \n");
|
|
1625
|
+
for (const index of table.indexes) {
|
|
1626
|
+
if (!index.isPrimaryKey) {
|
|
1627
|
+
let unique = " ";
|
|
1628
|
+
if (index.isUnique) unique = "UNIQUE ";
|
|
1629
|
+
indexes.push(
|
|
1630
|
+
` CREATE ${unique}INDEX "${index.name}" ON "${table.name}" (${index.columns.map((item) => {
|
|
1631
|
+
return `"${item}" ${index.order}`;
|
|
1632
|
+
}).join(", ")})`
|
|
1633
|
+
);
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
sql += "\n);";
|
|
1637
|
+
sqlStatements.push(sql);
|
|
1638
|
+
}
|
|
1639
|
+
for (const table of schema.database) {
|
|
1640
|
+
if (!table.foreignKeys.length) continue;
|
|
1641
|
+
const sql = `ALTER TABLE "${table.name}" `;
|
|
1642
|
+
const constraints = [];
|
|
1643
|
+
for (const foreignKey of table.foreignKeys) {
|
|
1644
|
+
let constraint = ` ADD CONSTRAINT "${foreignKey.name}"
|
|
1645
|
+
FOREIGN KEY ("${foreignKey.column}") REFERENCES "${foreignKey.refTable}" ("${foreignKey.refColumn}")`;
|
|
1646
|
+
constraint += ` ON DELETE ${foreignKey.onDelete}`;
|
|
1647
|
+
constraint += ` ON UPDATE ${foreignKey.onUpdate}`;
|
|
1648
|
+
constraints.push(constraint);
|
|
1649
|
+
}
|
|
1650
|
+
sqlStatements.push(sql + constraints.join(",\n") + ";");
|
|
1651
|
+
}
|
|
1652
|
+
for (const table of schema.database) {
|
|
1653
|
+
if (!table.checkConstraints.length) continue;
|
|
1654
|
+
const sql = `ALTER TABLE "${table.name}" `;
|
|
1655
|
+
const constraints = [];
|
|
1656
|
+
for (const check of table.checkConstraints) {
|
|
1657
|
+
const constraint = `ADD CONSTRAINT "${check.name}" CHECK (${check.check})`;
|
|
1658
|
+
constraints.push(constraint);
|
|
1659
|
+
}
|
|
1660
|
+
sqlStatements.push(sql + constraints.join(",\n") + ";");
|
|
1661
|
+
}
|
|
1662
|
+
sqlStatements.push(indexes.join(";\n"));
|
|
1663
|
+
return enums.join("\n") + "\n" + sqlStatements.join("\n\n");
|
|
1664
|
+
}
|
|
1665
|
+
async getScratchPool() {
|
|
1666
|
+
await this.psqlConnectionPool.runQuery(
|
|
1667
|
+
`DROP DATABASE IF EXISTS ${this.psqlConnectionPool.poolConfig.database}_scratch`,
|
|
1668
|
+
[],
|
|
1669
|
+
systemUser
|
|
1670
|
+
);
|
|
1671
|
+
await this.psqlConnectionPool.runQuery(
|
|
1672
|
+
`CREATE DATABASE ${this.psqlConnectionPool.poolConfig.database}_scratch;`,
|
|
1673
|
+
[],
|
|
1674
|
+
systemUser
|
|
1675
|
+
);
|
|
1676
|
+
const scratchPool = new PsqlPool({
|
|
1677
|
+
host: this.psqlConnectionPool.poolConfig.host,
|
|
1678
|
+
port: this.psqlConnectionPool.poolConfig.port,
|
|
1679
|
+
user: this.psqlConnectionPool.poolConfig.user,
|
|
1680
|
+
database: this.psqlConnectionPool.poolConfig.database + "_scratch",
|
|
1681
|
+
password: this.psqlConnectionPool.poolConfig.password,
|
|
1682
|
+
max: this.psqlConnectionPool.poolConfig.max,
|
|
1683
|
+
idleTimeoutMillis: this.psqlConnectionPool.poolConfig.idleTimeoutMillis,
|
|
1684
|
+
connectionTimeoutMillis: this.psqlConnectionPool.poolConfig.connectionTimeoutMillis
|
|
1685
|
+
});
|
|
1686
|
+
return scratchPool;
|
|
1687
|
+
}
|
|
1688
|
+
async diffDatabaseToSchema(schema) {
|
|
1689
|
+
const scratchPool = await this.getScratchPool();
|
|
1690
|
+
await this.createDatabaseFromSchema(schema, scratchPool);
|
|
1691
|
+
const originalClient = new Client({
|
|
1692
|
+
database: this.psqlConnectionPool.poolConfig.database,
|
|
1693
|
+
user: this.psqlConnectionPool.poolConfig.user,
|
|
1694
|
+
password: this.psqlConnectionPool.poolConfig.password,
|
|
1695
|
+
host: this.psqlConnectionPool.poolConfig.host,
|
|
1696
|
+
port: this.psqlConnectionPool.poolConfig.port
|
|
1697
|
+
});
|
|
1698
|
+
const scratchClient = new Client({
|
|
1699
|
+
database: this.psqlConnectionPool.poolConfig.database + "_scratch",
|
|
1700
|
+
user: this.psqlConnectionPool.poolConfig.user,
|
|
1701
|
+
password: this.psqlConnectionPool.poolConfig.password,
|
|
1702
|
+
host: this.psqlConnectionPool.poolConfig.host,
|
|
1703
|
+
port: this.psqlConnectionPool.poolConfig.port
|
|
1704
|
+
});
|
|
1705
|
+
await originalClient.connect();
|
|
1706
|
+
await scratchClient.connect();
|
|
1707
|
+
const info1 = await (0, import_pg_info.default)({
|
|
1708
|
+
client: originalClient,
|
|
1709
|
+
schema: "public"
|
|
1710
|
+
});
|
|
1711
|
+
const info2 = await (0, import_pg_info.default)({
|
|
1712
|
+
client: scratchClient,
|
|
1713
|
+
schema: "public"
|
|
1714
|
+
});
|
|
1715
|
+
const diff = (0, import_pg_diff_sync.default)(info1, info2);
|
|
1716
|
+
console.log("Schema differences:", diff);
|
|
1717
|
+
await originalClient.end();
|
|
1718
|
+
await scratchClient.end();
|
|
1719
|
+
return diff.join("\n");
|
|
1456
1720
|
}
|
|
1457
1721
|
createNestedSelect(req, schema, item, routeData, userRole, sqlParams) {
|
|
1458
1722
|
if (!item.subquery) return "";
|
|
@@ -1563,22 +1827,20 @@ var PsqlEngine = class extends SqlEngine {
|
|
|
1563
1827
|
);
|
|
1564
1828
|
} else if (routeData.type === "PAGED") {
|
|
1565
1829
|
const data = req.data;
|
|
1566
|
-
const
|
|
1567
|
-
`${selectStatement}${sqlStatement}${groupByOrderByStatement} LIMIT
|
|
1568
|
-
|
|
1569
|
-
[
|
|
1570
|
-
...sqlParams,
|
|
1571
|
-
data.perPage || DEFAULT_PAGED_PER_PAGE_NUMBER,
|
|
1572
|
-
(data.page - 1) * data.perPage || DEFAULT_PAGED_PAGE_NUMBER,
|
|
1573
|
-
...sqlParams
|
|
1574
|
-
],
|
|
1830
|
+
const pagePromise = this.psqlConnectionPool.runQuery(
|
|
1831
|
+
`${selectStatement}${sqlStatement}${groupByOrderByStatement}` + SQL`LIMIT ${data.perPage || DEFAULT_PAGED_PER_PAGE_NUMBER} OFFSET ${(data.page - 1) * data.perPage || DEFAULT_PAGED_PAGE_NUMBER};`,
|
|
1832
|
+
sqlParams,
|
|
1575
1833
|
req.requesterDetails
|
|
1576
1834
|
);
|
|
1835
|
+
const totalQuery = `SELECT COUNT(${routeData.groupBy ? `DISTINCT ${routeData.groupBy.tableName}.${routeData.groupBy.columnName}` : "*"}) AS total
|
|
1836
|
+
${sqlStatement};`;
|
|
1837
|
+
const totalPromise = await this.psqlConnectionPool.runQuery(totalQuery, sqlParams, req.requesterDetails);
|
|
1838
|
+
const [pageResults, totalResponse] = await Promise.all([pagePromise, totalPromise]);
|
|
1577
1839
|
let total = 0;
|
|
1578
|
-
if (import_core_utils5.ObjectUtils.isArrayWithData(
|
|
1579
|
-
total =
|
|
1840
|
+
if (import_core_utils5.ObjectUtils.isArrayWithData(totalResponse)) {
|
|
1841
|
+
total = totalResponse[0].total;
|
|
1580
1842
|
}
|
|
1581
|
-
return { data: pageResults
|
|
1843
|
+
return { data: pageResults, total };
|
|
1582
1844
|
} else {
|
|
1583
1845
|
throw new RsError("UNKNOWN_ERROR", "Unknown route type.");
|
|
1584
1846
|
}
|
|
@@ -1728,77 +1990,12 @@ ${sqlStatement};`,
|
|
|
1728
1990
|
return whereClause;
|
|
1729
1991
|
}
|
|
1730
1992
|
};
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
constructor(poolConfig) {
|
|
1738
|
-
this.poolConfig = poolConfig;
|
|
1739
|
-
this.pool = new Pool(poolConfig);
|
|
1740
|
-
this.queryOne("SELECT NOW();", [], { isSystemUser: true, role: "", host: "localhost", ipAddress: "" }).then(() => {
|
|
1741
|
-
logger.info("Connected to PostgreSQL database");
|
|
1742
|
-
}).catch((error) => {
|
|
1743
|
-
logger.error("Error connecting to database", error);
|
|
1744
|
-
process.exit(1);
|
|
1745
|
-
});
|
|
1746
|
-
}
|
|
1747
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1748
|
-
async queryOne(query, options, requesterDetails) {
|
|
1749
|
-
const formattedQuery = questionMarksToOrderedParams(query);
|
|
1750
|
-
this.logSqlStatement(formattedQuery, options, requesterDetails);
|
|
1751
|
-
try {
|
|
1752
|
-
const response = await this.pool.query(formattedQuery, options);
|
|
1753
|
-
if (response.rows.length === 0) throw new RsError("NOT_FOUND", "No results found");
|
|
1754
|
-
else if (response.rows.length > 1) throw new RsError("DUPLICATE", "More than one result found");
|
|
1755
|
-
return response.rows[0];
|
|
1756
|
-
} catch (error) {
|
|
1757
|
-
console.error(error, query, options);
|
|
1758
|
-
if (RsError.isRsError(error)) throw error;
|
|
1759
|
-
if ((error == null ? void 0 : error.routine) === "_bt_check_unique") {
|
|
1760
|
-
throw new RsError("DUPLICATE", error.message);
|
|
1761
|
-
}
|
|
1762
|
-
throw new RsError("DATABASE_ERROR", `${error.message}`);
|
|
1763
|
-
}
|
|
1764
|
-
}
|
|
1765
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1766
|
-
async runQuery(query, options, requesterDetails) {
|
|
1767
|
-
const formattedQuery = questionMarksToOrderedParams(query);
|
|
1768
|
-
this.logSqlStatement(formattedQuery, options, requesterDetails);
|
|
1769
|
-
const queryUpdated = query.replace(/[\t\n]/g, " ");
|
|
1770
|
-
console.log(queryUpdated, options);
|
|
1771
|
-
try {
|
|
1772
|
-
const response = await this.pool.query(formattedQuery, options);
|
|
1773
|
-
return response.rows;
|
|
1774
|
-
} catch (error) {
|
|
1775
|
-
console.error(error, query, options);
|
|
1776
|
-
if ((error == null ? void 0 : error.routine) === "_bt_check_unique") {
|
|
1777
|
-
throw new RsError("DUPLICATE", error.message);
|
|
1778
|
-
}
|
|
1779
|
-
throw new RsError("DATABASE_ERROR", `${error.message}`);
|
|
1780
|
-
}
|
|
1781
|
-
}
|
|
1782
|
-
logSqlStatement(query, options, requesterDetails, prefix = "") {
|
|
1783
|
-
if (logger.level !== "silly") return;
|
|
1784
|
-
let sqlStatement = "";
|
|
1785
|
-
if (options.length === 0) {
|
|
1786
|
-
sqlStatement = query;
|
|
1787
|
-
} else {
|
|
1788
|
-
let stringIndex = 0;
|
|
1789
|
-
sqlStatement = query.replace(/\$\d+/g, () => {
|
|
1790
|
-
const value = options[stringIndex++];
|
|
1791
|
-
if (typeof value === "number") return value.toString();
|
|
1792
|
-
return import_pg_format2.default.literal(value);
|
|
1793
|
-
});
|
|
1794
|
-
}
|
|
1795
|
-
let initiator = "Anonymous";
|
|
1796
|
-
if ("userId" in requesterDetails && requesterDetails.userId)
|
|
1797
|
-
initiator = `User Id (${requesterDetails.userId.toString()})`;
|
|
1798
|
-
if ("isSystemUser" in requesterDetails && requesterDetails.isSystemUser) initiator = "SYSTEM";
|
|
1799
|
-
logger.silly(`${prefix}query by ${initiator}, Query ->
|
|
1800
|
-
${sqlStatement}`);
|
|
1801
|
-
}
|
|
1993
|
+
var schemaToPsqlType = (column, tableName) => {
|
|
1994
|
+
if (column.hasAutoIncrement) return "BIGSERIAL";
|
|
1995
|
+
if (column.type === "ENUM") return `"${tableName}_${column.name}_enum"`;
|
|
1996
|
+
if (column.type === "DATETIME") return "TIMESTAMPTZ";
|
|
1997
|
+
if (column.type === "MEDIUMINT") return "INT";
|
|
1998
|
+
return column.type;
|
|
1802
1999
|
};
|
|
1803
2000
|
|
|
1804
2001
|
// src/restura/restura.ts
|