linkgress-orm 0.1.16 → 0.1.18
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/README.md +12 -0
- package/dist/entity/db-context.d.ts +146 -45
- package/dist/entity/db-context.d.ts.map +1 -1
- package/dist/entity/db-context.js +170 -160
- package/dist/entity/db-context.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/query/conditions.d.ts +108 -0
- package/dist/query/conditions.d.ts.map +1 -1
- package/dist/query/conditions.js +131 -0
- package/dist/query/conditions.js.map +1 -1
- package/dist/query/cte-builder.d.ts +1 -1
- package/dist/query/cte-builder.js +8 -8
- package/dist/query/cte-builder.js.map +1 -1
- package/dist/query/grouped-query.d.ts +8 -0
- package/dist/query/grouped-query.d.ts.map +1 -1
- package/dist/query/grouped-query.js +12 -0
- package/dist/query/grouped-query.js.map +1 -1
- package/dist/query/query-builder.d.ts +62 -3
- package/dist/query/query-builder.d.ts.map +1 -1
- package/dist/query/query-builder.js +275 -25
- package/dist/query/query-builder.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DatabaseContext = exports.DbEntityTable = exports.EntityInsertBuilder = exports.DataContext = exports.TableAccessor = exports.InsertBuilder = exports.QueryExecutor = exports.TimeTracer = void 0;
|
|
4
4
|
const entity_base_1 = require("./entity-base");
|
|
5
5
|
const model_config_1 = require("./model-config");
|
|
6
|
-
const conditions_1 = require("../query/conditions");
|
|
7
6
|
const query_builder_1 = require("../query/query-builder");
|
|
8
7
|
const db_schema_manager_1 = require("../migration/db-schema-manager");
|
|
9
8
|
const sequence_builder_1 = require("../schema/sequence-builder");
|
|
@@ -601,7 +600,12 @@ class TableAccessor {
|
|
|
601
600
|
sql += '\n OVERRIDING SYSTEM VALUE';
|
|
602
601
|
}
|
|
603
602
|
sql += `
|
|
604
|
-
VALUES ${valueClauses.join(', ')}
|
|
603
|
+
VALUES ${valueClauses.join(', ')}`;
|
|
604
|
+
// Add ON CONFLICT DO NOTHING if specified
|
|
605
|
+
if (insertConfig?.onConflictDoNothing) {
|
|
606
|
+
sql += '\n ON CONFLICT DO NOTHING';
|
|
607
|
+
}
|
|
608
|
+
sql += `
|
|
605
609
|
RETURNING ${returningColumns}
|
|
606
610
|
`;
|
|
607
611
|
const result = this.executor
|
|
@@ -664,65 +668,6 @@ class TableAccessor {
|
|
|
664
668
|
}
|
|
665
669
|
return builder.execute();
|
|
666
670
|
}
|
|
667
|
-
/**
|
|
668
|
-
* Bulk insert multiple rows (simple version, kept for compatibility)
|
|
669
|
-
*/
|
|
670
|
-
async insertMany(dataArray) {
|
|
671
|
-
if (dataArray.length === 0) {
|
|
672
|
-
return [];
|
|
673
|
-
}
|
|
674
|
-
// Extract all unique column names from all data objects
|
|
675
|
-
const columnSet = new Set();
|
|
676
|
-
for (const data of dataArray) {
|
|
677
|
-
for (const key of Object.keys(data)) {
|
|
678
|
-
const column = this.schema.columns[key];
|
|
679
|
-
if (column) {
|
|
680
|
-
const config = column.build();
|
|
681
|
-
if (!config.autoIncrement) {
|
|
682
|
-
columnSet.add(key);
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
const columns = Array.from(columnSet);
|
|
688
|
-
const values = [];
|
|
689
|
-
const valuePlaceholders = [];
|
|
690
|
-
let paramIndex = 1;
|
|
691
|
-
// Build placeholders for each row
|
|
692
|
-
for (const data of dataArray) {
|
|
693
|
-
const rowPlaceholders = [];
|
|
694
|
-
for (const key of columns) {
|
|
695
|
-
const value = data[key];
|
|
696
|
-
const column = this.schema.columns[key];
|
|
697
|
-
const config = column.build();
|
|
698
|
-
// Apply toDriver mapper if present
|
|
699
|
-
const mappedValue = config.mapper
|
|
700
|
-
? config.mapper.toDriver(value !== undefined ? value : null)
|
|
701
|
-
: (value !== undefined ? value : null);
|
|
702
|
-
values.push(mappedValue);
|
|
703
|
-
rowPlaceholders.push(`$${paramIndex++}`);
|
|
704
|
-
}
|
|
705
|
-
valuePlaceholders.push(`(${rowPlaceholders.join(', ')})`);
|
|
706
|
-
}
|
|
707
|
-
const columnNames = columns.map(key => {
|
|
708
|
-
const column = this.schema.columns[key];
|
|
709
|
-
const config = column.build();
|
|
710
|
-
return `"${config.name}"`;
|
|
711
|
-
});
|
|
712
|
-
const returningColumns = Object.entries(this.schema.columns)
|
|
713
|
-
.map(([_, col]) => `"${col.build().name}"`)
|
|
714
|
-
.join(', ');
|
|
715
|
-
const qualifiedTableName = (0, sql_utils_1.getQualifiedTableName)(this.schema);
|
|
716
|
-
const sql = `
|
|
717
|
-
INSERT INTO ${qualifiedTableName} (${columnNames.join(', ')})
|
|
718
|
-
VALUES ${valuePlaceholders.join(', ')}
|
|
719
|
-
RETURNING ${returningColumns}
|
|
720
|
-
`;
|
|
721
|
-
const result = this.executor
|
|
722
|
-
? await this.executor.query(sql, values)
|
|
723
|
-
: await this.client.query(sql, values);
|
|
724
|
-
return result.rows;
|
|
725
|
-
}
|
|
726
671
|
/**
|
|
727
672
|
* Insert with conflict resolution (upsert)
|
|
728
673
|
*/
|
|
@@ -856,10 +801,23 @@ class DataContext {
|
|
|
856
801
|
return accessor;
|
|
857
802
|
}
|
|
858
803
|
/**
|
|
859
|
-
* Execute raw SQL
|
|
804
|
+
* Execute raw SQL query with optional type parameter for results
|
|
805
|
+
*
|
|
806
|
+
* @example
|
|
807
|
+
* ```typescript
|
|
808
|
+
* // Untyped query
|
|
809
|
+
* const result = await db.query('SELECT * FROM users');
|
|
810
|
+
*
|
|
811
|
+
* // Typed query - returns T[]
|
|
812
|
+
* const users = await db.query<{ id: number; name: string }>('SELECT id, name FROM users');
|
|
813
|
+
*
|
|
814
|
+
* // With parameters
|
|
815
|
+
* const user = await db.query<{ id: number }>('SELECT id FROM users WHERE name = $1', ['alice']);
|
|
816
|
+
* ```
|
|
860
817
|
*/
|
|
861
818
|
async query(sql, params) {
|
|
862
|
-
|
|
819
|
+
const result = await this.client.query(sql, params);
|
|
820
|
+
return result.rows;
|
|
863
821
|
}
|
|
864
822
|
/**
|
|
865
823
|
* Execute in transaction
|
|
@@ -972,6 +930,89 @@ class DbEntityTable {
|
|
|
972
930
|
_getCollectionStrategy() {
|
|
973
931
|
return this.context.queryOptions?.collectionStrategy;
|
|
974
932
|
}
|
|
933
|
+
/**
|
|
934
|
+
* Get information about all columns in this table.
|
|
935
|
+
* This method returns metadata about database columns only, excluding navigation properties.
|
|
936
|
+
*
|
|
937
|
+
* @param options - Optional configuration
|
|
938
|
+
* @param options.includeNavigation - If false (default), only returns database columns.
|
|
939
|
+
* Navigation properties are never included as they are not columns.
|
|
940
|
+
*
|
|
941
|
+
* @returns Array of column information objects
|
|
942
|
+
*
|
|
943
|
+
* @example
|
|
944
|
+
* ```typescript
|
|
945
|
+
* // Get all columns
|
|
946
|
+
* const columns = db.users.getColumns();
|
|
947
|
+
* // Returns: [
|
|
948
|
+
* // { propertyName: 'id', columnName: 'id', type: 'integer', isPrimaryKey: true, ... },
|
|
949
|
+
* // { propertyName: 'username', columnName: 'username', type: 'varchar', ... },
|
|
950
|
+
* // { propertyName: 'email', columnName: 'email', type: 'text', ... },
|
|
951
|
+
* // ]
|
|
952
|
+
*
|
|
953
|
+
* // Get column names only
|
|
954
|
+
* const columnNames = db.users.getColumns().map(c => c.propertyName);
|
|
955
|
+
* // Returns: ['id', 'username', 'email', ...]
|
|
956
|
+
*
|
|
957
|
+
* // Get database column names
|
|
958
|
+
* const dbColumnNames = db.users.getColumns().map(c => c.columnName);
|
|
959
|
+
* // Returns: ['id', 'username', 'email', ...]
|
|
960
|
+
* ```
|
|
961
|
+
*/
|
|
962
|
+
getColumns() {
|
|
963
|
+
const schema = this._getSchema();
|
|
964
|
+
const columns = [];
|
|
965
|
+
for (const [propName, colBuilder] of Object.entries(schema.columns)) {
|
|
966
|
+
const config = colBuilder.build();
|
|
967
|
+
columns.push({
|
|
968
|
+
propertyName: propName,
|
|
969
|
+
columnName: config.name,
|
|
970
|
+
type: config.type,
|
|
971
|
+
isPrimaryKey: config.primaryKey || false,
|
|
972
|
+
isAutoIncrement: config.autoIncrement || !!config.identity,
|
|
973
|
+
isNullable: config.nullable !== false,
|
|
974
|
+
isUnique: config.unique || false,
|
|
975
|
+
defaultValue: config.default,
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
return columns;
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Get an object containing all entity properties as DbColumn references.
|
|
982
|
+
* Useful for building dynamic queries or accessing column metadata.
|
|
983
|
+
*
|
|
984
|
+
* @param options - Optional configuration
|
|
985
|
+
* @param options.excludeNavigation - If true (default), excludes navigation properties.
|
|
986
|
+
* Set to false to include navigation properties.
|
|
987
|
+
*
|
|
988
|
+
* @returns Object with property names as keys and their DbColumn/navigation references as values
|
|
989
|
+
*
|
|
990
|
+
* @example
|
|
991
|
+
* ```typescript
|
|
992
|
+
* // Get all column properties (excludes navigation by default)
|
|
993
|
+
* const cols = db.users.props();
|
|
994
|
+
* // Use in select: db.users.select(u => ({ id: cols.id, name: cols.username }))
|
|
995
|
+
*
|
|
996
|
+
* // Include navigation properties
|
|
997
|
+
* const allProps = db.users.props({ excludeNavigation: false });
|
|
998
|
+
* ```
|
|
999
|
+
*/
|
|
1000
|
+
props(options) {
|
|
1001
|
+
const schema = this._getSchema();
|
|
1002
|
+
const excludeNav = options?.excludeNavigation !== false; // Default true
|
|
1003
|
+
// Create a temporary QueryBuilder to reuse the createMockRow logic
|
|
1004
|
+
const qb = new query_builder_1.QueryBuilder(schema, this._getClient(), undefined, undefined, undefined, undefined, this._getExecutor(), undefined, undefined, this._getCollectionStrategy(), this.context.schemaRegistry);
|
|
1005
|
+
const mockRow = qb._createMockRow();
|
|
1006
|
+
if (excludeNav) {
|
|
1007
|
+
// Filter out navigation properties, keep only columns
|
|
1008
|
+
const result = {};
|
|
1009
|
+
for (const propName of Object.keys(schema.columns)) {
|
|
1010
|
+
result[propName] = mockRow[propName];
|
|
1011
|
+
}
|
|
1012
|
+
return result;
|
|
1013
|
+
}
|
|
1014
|
+
return mockRow;
|
|
1015
|
+
}
|
|
975
1016
|
/**
|
|
976
1017
|
* Get qualified table name with schema prefix if specified
|
|
977
1018
|
* @internal
|
|
@@ -1264,77 +1305,22 @@ class DbEntityTable {
|
|
|
1264
1305
|
* ```
|
|
1265
1306
|
*/
|
|
1266
1307
|
insert(data) {
|
|
1267
|
-
const
|
|
1268
|
-
const executeInsert = async (returning) => {
|
|
1269
|
-
const schema = table._getSchema();
|
|
1270
|
-
const executor = table._getExecutor();
|
|
1271
|
-
const client = table._getClient();
|
|
1272
|
-
// Build INSERT columns and values
|
|
1273
|
-
const columns = [];
|
|
1274
|
-
const values = [];
|
|
1275
|
-
const placeholders = [];
|
|
1276
|
-
let paramIndex = 1;
|
|
1277
|
-
for (const [key, value] of Object.entries(data)) {
|
|
1278
|
-
const column = schema.columns[key];
|
|
1279
|
-
if (column) {
|
|
1280
|
-
const config = column.build();
|
|
1281
|
-
if (!config.autoIncrement) {
|
|
1282
|
-
columns.push(`"${config.name}"`);
|
|
1283
|
-
const mappedValue = config.mapper ? config.mapper.toDriver(value) : value;
|
|
1284
|
-
values.push(mappedValue);
|
|
1285
|
-
placeholders.push(`$${paramIndex++}`);
|
|
1286
|
-
}
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
// Build RETURNING clause
|
|
1290
|
-
const returningClause = table.buildReturningClause(returning);
|
|
1291
|
-
const qualifiedTableName = table._getQualifiedTableName();
|
|
1292
|
-
let sql = `INSERT INTO ${qualifiedTableName} (${columns.join(', ')}) VALUES (${placeholders.join(', ')})`;
|
|
1293
|
-
if (returningClause) {
|
|
1294
|
-
sql += ` RETURNING ${returningClause.sql}`;
|
|
1295
|
-
}
|
|
1296
|
-
const result = executor
|
|
1297
|
-
? await executor.query(sql, values)
|
|
1298
|
-
: await client.query(sql, values);
|
|
1299
|
-
if (!returningClause) {
|
|
1300
|
-
return undefined;
|
|
1301
|
-
}
|
|
1302
|
-
const mappedResults = table.mapReturningResults(result.rows, returning);
|
|
1303
|
-
return mappedResults[0];
|
|
1304
|
-
};
|
|
1308
|
+
const bulkBuilder = this.insertBulk([data]);
|
|
1305
1309
|
return {
|
|
1306
1310
|
then(onfulfilled, onrejected) {
|
|
1307
|
-
return
|
|
1311
|
+
return bulkBuilder.then(onfulfilled, onrejected);
|
|
1308
1312
|
},
|
|
1309
1313
|
returning(selector) {
|
|
1310
|
-
const
|
|
1314
|
+
const bulkReturning = selector ? bulkBuilder.returning(selector) : bulkBuilder.returning();
|
|
1311
1315
|
return {
|
|
1312
1316
|
then(onfulfilled, onrejected) {
|
|
1313
|
-
|
|
1317
|
+
// Unwrap array to single item
|
|
1318
|
+
return bulkReturning.then((results) => results?.[0], undefined).then(onfulfilled, onrejected);
|
|
1314
1319
|
}
|
|
1315
1320
|
};
|
|
1316
1321
|
}
|
|
1317
1322
|
};
|
|
1318
1323
|
}
|
|
1319
|
-
/**
|
|
1320
|
-
* Insert multiple records
|
|
1321
|
-
* Returns a fluent builder that can be awaited directly or chained with .returning()
|
|
1322
|
-
*
|
|
1323
|
-
* @example
|
|
1324
|
-
* ```typescript
|
|
1325
|
-
* // No returning (default) - returns void
|
|
1326
|
-
* await db.users.insertMany([{ username: 'alice' }, { username: 'bob' }]);
|
|
1327
|
-
*
|
|
1328
|
-
* // With returning() - returns full entities
|
|
1329
|
-
* const users = await db.users.insertMany([{ username: 'alice' }]).returning();
|
|
1330
|
-
*
|
|
1331
|
-
* // With returning(selector) - returns selected columns
|
|
1332
|
-
* const results = await db.users.insertMany([{ username: 'alice' }]).returning(u => ({ id: u.id }));
|
|
1333
|
-
* ```
|
|
1334
|
-
*/
|
|
1335
|
-
insertMany(data) {
|
|
1336
|
-
return this.insertBulk(data);
|
|
1337
|
-
}
|
|
1338
1324
|
/**
|
|
1339
1325
|
* Upsert (insert or update on conflict)
|
|
1340
1326
|
* Returns a fluent builder that can be awaited directly or chained with .returning()
|
|
@@ -1367,8 +1353,11 @@ class DbEntityTable {
|
|
|
1367
1353
|
* // With returning(selector) - returns selected columns
|
|
1368
1354
|
* const results = await db.users.insertBulk([{ username: 'alice' }]).returning(u => ({ id: u.id }));
|
|
1369
1355
|
*
|
|
1370
|
-
* // With
|
|
1356
|
+
* // With chunk size
|
|
1371
1357
|
* await db.users.insertBulk([{ username: 'alice' }], { chunkSize: 100 });
|
|
1358
|
+
*
|
|
1359
|
+
* // Skip duplicates (ON CONFLICT DO NOTHING)
|
|
1360
|
+
* await db.users.insertBulk([{ username: 'alice' }], { onConflictDoNothing: true });
|
|
1372
1361
|
* ```
|
|
1373
1362
|
*/
|
|
1374
1363
|
insertBulk(value, options) {
|
|
@@ -1391,13 +1380,13 @@ class DbEntityTable {
|
|
|
1391
1380
|
const allResults = [];
|
|
1392
1381
|
for (let i = 0; i < dataArray.length; i += chunkSize) {
|
|
1393
1382
|
const chunk = dataArray.slice(i, i + chunkSize);
|
|
1394
|
-
const chunkResults = await table.insertBulkSingle(chunk, returning, options?.overridingSystemValue);
|
|
1383
|
+
const chunkResults = await table.insertBulkSingle(chunk, returning, options?.overridingSystemValue, options?.onConflictDoNothing);
|
|
1395
1384
|
if (chunkResults)
|
|
1396
1385
|
allResults.push(...chunkResults);
|
|
1397
1386
|
}
|
|
1398
1387
|
return returning === undefined ? undefined : allResults;
|
|
1399
1388
|
}
|
|
1400
|
-
return table.insertBulkSingle(dataArray, returning, options?.overridingSystemValue);
|
|
1389
|
+
return table.insertBulkSingle(dataArray, returning, options?.overridingSystemValue, options?.onConflictDoNothing);
|
|
1401
1390
|
};
|
|
1402
1391
|
return {
|
|
1403
1392
|
then(onfulfilled, onrejected) {
|
|
@@ -1417,7 +1406,7 @@ class DbEntityTable {
|
|
|
1417
1406
|
* Execute a single bulk insert batch
|
|
1418
1407
|
* @internal
|
|
1419
1408
|
*/
|
|
1420
|
-
async insertBulkSingle(data, returning, overridingSystemValue) {
|
|
1409
|
+
async insertBulkSingle(data, returning, overridingSystemValue, onConflictDoNothing) {
|
|
1421
1410
|
const schema = this._getSchema();
|
|
1422
1411
|
const executor = this._getExecutor();
|
|
1423
1412
|
const client = this._getClient();
|
|
@@ -1460,6 +1449,9 @@ class DbEntityTable {
|
|
|
1460
1449
|
sql += ' OVERRIDING SYSTEM VALUE';
|
|
1461
1450
|
}
|
|
1462
1451
|
sql += ` VALUES ${valuesClauses.join(', ')}`;
|
|
1452
|
+
if (onConflictDoNothing) {
|
|
1453
|
+
sql += ' ON CONFLICT DO NOTHING';
|
|
1454
|
+
}
|
|
1463
1455
|
if (returningClause) {
|
|
1464
1456
|
sql += ` RETURNING ${returningClause.sql}`;
|
|
1465
1457
|
}
|
|
@@ -1730,23 +1722,15 @@ class DbEntityTable {
|
|
|
1730
1722
|
return new EntityInsertBuilder(builder);
|
|
1731
1723
|
}
|
|
1732
1724
|
/**
|
|
1733
|
-
* Update records
|
|
1725
|
+
* Update all records in the table
|
|
1734
1726
|
* Returns a fluent builder that can be awaited directly or chained with .returning()
|
|
1735
1727
|
*
|
|
1736
|
-
*
|
|
1737
|
-
*
|
|
1738
|
-
*
|
|
1739
|
-
* await db.users.
|
|
1740
|
-
*
|
|
1741
|
-
* // With returning() - returns full entities
|
|
1742
|
-
* const users = await db.users.update({ age: 30 }, u => eq(u.id, 1)).returning();
|
|
1743
|
-
*
|
|
1744
|
-
* // With returning(selector) - returns selected columns
|
|
1745
|
-
* const results = await db.users.update({ age: 30 }, u => eq(u.id, 1))
|
|
1746
|
-
* .returning(u => ({ id: u.id, age: u.age }));
|
|
1747
|
-
* ```
|
|
1728
|
+
* Usage:
|
|
1729
|
+
* await db.users.update({ age: 30 }) // Update all
|
|
1730
|
+
* await db.users.where(u => eq(u.id, 1)).update({ age: 30 }) // Update with condition
|
|
1731
|
+
* const updated = await db.users.where(u => eq(u.id, 1)).update({ age: 30 }).returning()
|
|
1748
1732
|
*/
|
|
1749
|
-
update(data
|
|
1733
|
+
update(data) {
|
|
1750
1734
|
const table = this;
|
|
1751
1735
|
const executeUpdate = async (returning) => {
|
|
1752
1736
|
const schema = table._getSchema();
|
|
@@ -1767,16 +1751,11 @@ class DbEntityTable {
|
|
|
1767
1751
|
if (setClauses.length === 0) {
|
|
1768
1752
|
throw new Error('No valid columns to update');
|
|
1769
1753
|
}
|
|
1770
|
-
//
|
|
1771
|
-
const mockEntity = table.createMockEntity();
|
|
1772
|
-
const whereCondition = condition(mockEntity);
|
|
1773
|
-
const condBuilder = new conditions_1.ConditionBuilder();
|
|
1774
|
-
const { sql: whereSql, params: whereParams } = condBuilder.build(whereCondition, paramIndex);
|
|
1775
|
-
values.push(...whereParams);
|
|
1754
|
+
// No WHERE clause - updates all records
|
|
1776
1755
|
// Build RETURNING clause
|
|
1777
1756
|
const returningClause = table.buildReturningClause(returning);
|
|
1778
1757
|
const qualifiedTableName = table._getQualifiedTableName();
|
|
1779
|
-
let sql = `UPDATE ${qualifiedTableName} SET ${setClauses.join(', ')}
|
|
1758
|
+
let sql = `UPDATE ${qualifiedTableName} SET ${setClauses.join(', ')}`;
|
|
1780
1759
|
if (returningClause) {
|
|
1781
1760
|
sql += ` RETURNING ${returningClause.sql}`;
|
|
1782
1761
|
}
|
|
@@ -1995,23 +1974,54 @@ WHERE ${whereClause}`.trim();
|
|
|
1995
1974
|
return this.mapReturningResults(result.rows, returning);
|
|
1996
1975
|
}
|
|
1997
1976
|
/**
|
|
1998
|
-
* Delete records
|
|
1999
|
-
*
|
|
1977
|
+
* Delete all records from the table
|
|
1978
|
+
* Returns a fluent builder that can be awaited directly or chained with .returning()
|
|
1979
|
+
*
|
|
1980
|
+
* Usage:
|
|
1981
|
+
* await db.users.delete() // Delete all
|
|
1982
|
+
* await db.users.where(u => eq(u.id, 1)).delete() // Delete with condition
|
|
1983
|
+
* const deleted = await db.users.where(u => eq(u.id, 1)).delete().returning()
|
|
2000
1984
|
*/
|
|
2001
|
-
|
|
1985
|
+
delete() {
|
|
2002
1986
|
const schema = this._getSchema();
|
|
2003
1987
|
const executor = this._getExecutor();
|
|
2004
1988
|
const client = this._getClient();
|
|
2005
|
-
// Build WHERE clause
|
|
2006
|
-
const mockEntity = this.createMockEntity();
|
|
2007
|
-
const whereCondition = condition(mockEntity);
|
|
2008
|
-
const condBuilder = new conditions_1.ConditionBuilder();
|
|
2009
|
-
const { sql: whereSql, params: whereParams } = condBuilder.build(whereCondition, 1);
|
|
2010
1989
|
const qualifiedTableName = this._getQualifiedTableName();
|
|
2011
|
-
|
|
2012
|
-
const
|
|
2013
|
-
|
|
2014
|
-
|
|
1990
|
+
// No WHERE condition - deletes all records
|
|
1991
|
+
const baseSql = `DELETE FROM ${qualifiedTableName}`;
|
|
1992
|
+
const table = this;
|
|
1993
|
+
const executeDelete = async (returningConfig) => {
|
|
1994
|
+
if (!returningConfig) {
|
|
1995
|
+
const sql = baseSql;
|
|
1996
|
+
const result = executor
|
|
1997
|
+
? await executor.query(sql, [])
|
|
1998
|
+
: await client.query(sql, []);
|
|
1999
|
+
return;
|
|
2000
|
+
}
|
|
2001
|
+
// Build RETURNING clause
|
|
2002
|
+
const returningClause = table.buildReturningClause(returningConfig);
|
|
2003
|
+
const sql = returningClause ? `${baseSql} RETURNING ${returningClause.sql}` : baseSql;
|
|
2004
|
+
const result = executor
|
|
2005
|
+
? await executor.query(sql, [])
|
|
2006
|
+
: await client.query(sql, []);
|
|
2007
|
+
if (returningClause && result.rows) {
|
|
2008
|
+
return table.mapReturningResults(result.rows, returningConfig);
|
|
2009
|
+
}
|
|
2010
|
+
};
|
|
2011
|
+
const fluent = {
|
|
2012
|
+
then: (resolve, reject) => {
|
|
2013
|
+
return executeDelete().then(resolve, reject);
|
|
2014
|
+
},
|
|
2015
|
+
returning: ((selector) => {
|
|
2016
|
+
const returningConfig = selector ?? true;
|
|
2017
|
+
return {
|
|
2018
|
+
then: (resolve, reject) => {
|
|
2019
|
+
return executeDelete(returningConfig).then(resolve, reject);
|
|
2020
|
+
}
|
|
2021
|
+
};
|
|
2022
|
+
})
|
|
2023
|
+
};
|
|
2024
|
+
return fluent;
|
|
2015
2025
|
}
|
|
2016
2026
|
/**
|
|
2017
2027
|
* Create a mock entity for type inference in lambdas
|