orange-orm 3.10.3 → 4.0.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/README.md +30 -4
- package/docs/changelog.md +7 -5
- package/package.json +1 -1
- package/src/client/index.js +42 -34
- package/src/client/index.mjs +42 -34
- package/src/hostExpress/executePath.js +74 -8
- package/src/hostExpress/getMeta.js +2 -9
- package/src/map.d.ts +75 -27
- package/src/validateDeleteConflict.js +2 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
The ultimate Object Relational Mapper for Node.js and Typescript, offering seamless integration with a variety of popular databases. Whether you're building applications in TypeScript or JavaScript (including both CommonJS and ECMAScript), Orange ORM has got you covered.
|
|
6
6
|
|
|
7
|
-
[](https://www.npmjs.org/package/orange-orm)
|
|
8
8
|
[](https://github.com/alfateam/orange-orm/actions)
|
|
9
9
|
[](https://github.com/alfateam/orange-orm/actions)
|
|
10
10
|
[](https://github.com/alfateam/orange-orm)
|
|
@@ -740,8 +740,8 @@ async function update() {
|
|
|
740
740
|
await orders.saveChanges();
|
|
741
741
|
}
|
|
742
742
|
```
|
|
743
|
-
|
|
744
|
-
The update method is
|
|
743
|
+
__Selective updates__
|
|
744
|
+
The update method is ideal for updating specific columns and relationships across one or multiple rows. You must provide a where filter to specify which rows to target. If you include a fetching strategy, the affected rows and their related data will be returned; otherwise, no data is returned.
|
|
745
745
|
|
|
746
746
|
```javascript
|
|
747
747
|
import map from './map';
|
|
@@ -751,7 +751,33 @@ update();
|
|
|
751
751
|
|
|
752
752
|
async function update() {
|
|
753
753
|
|
|
754
|
+
const propsToBeModified = {
|
|
755
|
+
orderDate: new Date(),
|
|
756
|
+
customerId: 2,
|
|
757
|
+
lines: [
|
|
758
|
+
{ id: 1, product: 'Bicycle', amount: 250 }, //already existing line
|
|
759
|
+
{ id: 2, product: 'Small guitar', amount: 150 }, //already existing line
|
|
760
|
+
{ product: 'Piano', amount: 800 } //the new line to be inserted
|
|
761
|
+
]
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
const strategy = {customer: true, deliveryAddress: true, lines: true};
|
|
765
|
+
const orders = await db.order.update(propsToBeModified, { where: x => x.id.eq(1) }, strategy);
|
|
766
|
+
}
|
|
767
|
+
```
|
|
768
|
+
__Replacing a row from JSON__
|
|
769
|
+
The replace method is suitable when a complete overwrite is required from a JSON object - typically in a REST API. However, it's important to consider that this method replaces the entire row and it's children, which might not always be desirable in a multi-user environment.
|
|
770
|
+
|
|
771
|
+
```javascript
|
|
772
|
+
import map from './map';
|
|
773
|
+
const db = map.sqlite('demo.db');
|
|
774
|
+
|
|
775
|
+
replace();
|
|
776
|
+
|
|
777
|
+
async function replace() {
|
|
778
|
+
|
|
754
779
|
const modified = {
|
|
780
|
+
id: 1,
|
|
755
781
|
orderDate: '2023-07-14T12:00:00',
|
|
756
782
|
customer: {
|
|
757
783
|
id: 2
|
|
@@ -770,7 +796,7 @@ async function update() {
|
|
|
770
796
|
]
|
|
771
797
|
};
|
|
772
798
|
|
|
773
|
-
const order = await db.order.
|
|
799
|
+
const order = await db.order.replace(modified, {customer: true, deliveryAddress: true, lines: true});
|
|
774
800
|
}
|
|
775
801
|
```
|
|
776
802
|
__Partially updating from JSON__
|
package/docs/changelog.md
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
## Changelog
|
|
2
|
-
|
|
2
|
+
__4.0.0__
|
|
3
|
+
Changed the behaviour of `update` to accept a `where` filter and only update passed in columns and relations. The previous behaviour of `update` has moved to `replace` method.
|
|
4
|
+
__3.10.3__
|
|
3
5
|
Fix duplicate method signatures for those still using code generation
|
|
4
|
-
__3.10.
|
|
6
|
+
__3.10.2__
|
|
5
7
|
Orange ORM was renamed from rdb. New installation url: [npmjs.org/package/orange-orm](https://npmjs.org/package/orange-orm) . Old url was npmjs.org/package/rdb
|
|
6
|
-
__3.10.
|
|
8
|
+
__3.10.1__
|
|
7
9
|
Bugfix: Adding hasOne row to existing parent throws. See [#86](https://github.com/alfateam/orange-orm/issues/86)
|
|
8
|
-
__3.10.
|
|
10
|
+
__3.10.0__
|
|
9
11
|
Aggregate functions
|
|
10
|
-
__3.9.
|
|
12
|
+
__3.9.1__
|
|
11
13
|
Bugfix: Crashing on many relations if foreign key column is omitted in strategy. See [#83](https://github.com/alfateam/orange-orm/issues/83)
|
|
12
14
|
__3.9.0__
|
|
13
15
|
Possible to elevate associated column on a related table to a parent table when fetching. See https://github.com/alfateam/orange-orm/#user-content-aggregate-results
|
package/package.json
CHANGED
package/src/client/index.js
CHANGED
|
@@ -190,6 +190,7 @@ function rdbClient(options = {}) {
|
|
|
190
190
|
getById,
|
|
191
191
|
proxify,
|
|
192
192
|
update,
|
|
193
|
+
replace,
|
|
193
194
|
updateChanges,
|
|
194
195
|
insert,
|
|
195
196
|
insertAndForget,
|
|
@@ -289,31 +290,32 @@ function rdbClient(options = {}) {
|
|
|
289
290
|
function negotiateWhere(_, strategy, ...rest) {
|
|
290
291
|
const args = Array.prototype.slice.call(arguments);
|
|
291
292
|
if (strategy)
|
|
292
|
-
return [_,
|
|
293
|
+
return [_, negotiateWhereSingle(strategy), ...rest];
|
|
293
294
|
else
|
|
294
295
|
return args;
|
|
295
296
|
|
|
296
|
-
function where(_strategy, path = '') {
|
|
297
|
-
if (typeof _strategy !== 'object' || _strategy === null)
|
|
298
|
-
return _strategy;
|
|
299
297
|
|
|
300
|
-
|
|
301
|
-
return _strategy.map(item => where(item, path));
|
|
302
|
-
}
|
|
298
|
+
}
|
|
303
299
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
}
|
|
311
|
-
else
|
|
312
|
-
strategy[name] = where(_strategy[name], path + name + '.');
|
|
313
|
-
}
|
|
314
|
-
return strategy;
|
|
300
|
+
function negotiateWhereSingle(_strategy, path = '') {
|
|
301
|
+
if (typeof _strategy !== 'object' || _strategy === null)
|
|
302
|
+
return _strategy;
|
|
303
|
+
|
|
304
|
+
if (Array.isArray(_strategy)) {
|
|
305
|
+
return _strategy.map(item => negotiateWhereSingle(item, path));
|
|
315
306
|
}
|
|
316
307
|
|
|
308
|
+
const strategy = { ..._strategy };
|
|
309
|
+
for (let name in _strategy) {
|
|
310
|
+
if (name === 'where' && typeof strategy[name] === 'function')
|
|
311
|
+
strategy.where = column(path + 'where')(strategy.where); // Assuming `column` is defined elsewhere.
|
|
312
|
+
else if (typeof strategy[name] === 'function') {
|
|
313
|
+
strategy[name] = aggregate(path, strategy[name]);
|
|
314
|
+
}
|
|
315
|
+
else
|
|
316
|
+
strategy[name] = negotiateWhereSingle(_strategy[name], path + name + '.');
|
|
317
|
+
}
|
|
318
|
+
return strategy;
|
|
317
319
|
}
|
|
318
320
|
|
|
319
321
|
|
|
@@ -372,28 +374,34 @@ function rdbClient(options = {}) {
|
|
|
372
374
|
return adapter.post(body);
|
|
373
375
|
}
|
|
374
376
|
|
|
375
|
-
async function update(
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
377
|
+
async function update(_row, _where, strategy) {
|
|
378
|
+
let args = [_row, negotiateWhereSingle(_where), negotiateWhereSingle(strategy)];
|
|
379
|
+
let body = stringify({
|
|
380
|
+
path: 'update',
|
|
381
|
+
args
|
|
382
|
+
});
|
|
383
|
+
let adapter = netAdapter(url, tableName, { axios: axiosInterceptor, tableOptions });
|
|
384
|
+
const result = await adapter.post(body);
|
|
385
|
+
if (strategy)
|
|
386
|
+
return proxify(result, strategy);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
async function replace(_row, strategy) {
|
|
390
|
+
let args = [_row, negotiateWhereSingle(strategy)];
|
|
391
|
+
let body = stringify({
|
|
392
|
+
path: 'replace',
|
|
393
|
+
args
|
|
394
|
+
});
|
|
395
|
+
let adapter = netAdapter(url, tableName, { axios: axiosInterceptor, tableOptions });
|
|
396
|
+
const result = await adapter.post(body);
|
|
397
|
+
if (strategy)
|
|
398
|
+
return proxify(result, strategy);
|
|
390
399
|
}
|
|
391
400
|
|
|
392
401
|
async function updateChanges(rows, oldRows, ...rest) {
|
|
393
402
|
const concurrency = undefined;
|
|
394
403
|
const args = [concurrency].concat(rest);
|
|
395
404
|
if (Array.isArray(rows)) {
|
|
396
|
-
//todo
|
|
397
405
|
const proxy = await getMany.apply(null, [rows, ...rest]);
|
|
398
406
|
proxy.splice.apply(proxy, [0, proxy.length, ...rows]);
|
|
399
407
|
await proxy.saveChanges.apply(proxy, args);
|
package/src/client/index.mjs
CHANGED
|
@@ -5486,6 +5486,7 @@ function rdbClient(options = {}) {
|
|
|
5486
5486
|
getById,
|
|
5487
5487
|
proxify,
|
|
5488
5488
|
update,
|
|
5489
|
+
replace,
|
|
5489
5490
|
updateChanges,
|
|
5490
5491
|
insert,
|
|
5491
5492
|
insertAndForget,
|
|
@@ -5585,31 +5586,32 @@ function rdbClient(options = {}) {
|
|
|
5585
5586
|
function negotiateWhere(_, strategy, ...rest) {
|
|
5586
5587
|
const args = Array.prototype.slice.call(arguments);
|
|
5587
5588
|
if (strategy)
|
|
5588
|
-
return [_,
|
|
5589
|
+
return [_, negotiateWhereSingle(strategy), ...rest];
|
|
5589
5590
|
else
|
|
5590
5591
|
return args;
|
|
5591
5592
|
|
|
5592
|
-
function where(_strategy, path = '') {
|
|
5593
|
-
if (typeof _strategy !== 'object' || _strategy === null)
|
|
5594
|
-
return _strategy;
|
|
5595
5593
|
|
|
5596
|
-
|
|
5597
|
-
return _strategy.map(item => where(item, path));
|
|
5598
|
-
}
|
|
5594
|
+
}
|
|
5599
5595
|
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
}
|
|
5607
|
-
else
|
|
5608
|
-
strategy[name] = where(_strategy[name], path + name + '.');
|
|
5609
|
-
}
|
|
5610
|
-
return strategy;
|
|
5596
|
+
function negotiateWhereSingle(_strategy, path = '') {
|
|
5597
|
+
if (typeof _strategy !== 'object' || _strategy === null)
|
|
5598
|
+
return _strategy;
|
|
5599
|
+
|
|
5600
|
+
if (Array.isArray(_strategy)) {
|
|
5601
|
+
return _strategy.map(item => negotiateWhereSingle(item, path));
|
|
5611
5602
|
}
|
|
5612
5603
|
|
|
5604
|
+
const strategy = { ..._strategy };
|
|
5605
|
+
for (let name in _strategy) {
|
|
5606
|
+
if (name === 'where' && typeof strategy[name] === 'function')
|
|
5607
|
+
strategy.where = column(path + 'where')(strategy.where); // Assuming `column` is defined elsewhere.
|
|
5608
|
+
else if (typeof strategy[name] === 'function') {
|
|
5609
|
+
strategy[name] = aggregate(path, strategy[name]);
|
|
5610
|
+
}
|
|
5611
|
+
else
|
|
5612
|
+
strategy[name] = negotiateWhereSingle(_strategy[name], path + name + '.');
|
|
5613
|
+
}
|
|
5614
|
+
return strategy;
|
|
5613
5615
|
}
|
|
5614
5616
|
|
|
5615
5617
|
|
|
@@ -5668,28 +5670,34 @@ function rdbClient(options = {}) {
|
|
|
5668
5670
|
return adapter.post(body);
|
|
5669
5671
|
}
|
|
5670
5672
|
|
|
5671
|
-
async function update(
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5673
|
+
async function update(_row, _where, strategy) {
|
|
5674
|
+
let args = [_row, negotiateWhereSingle(_where), negotiateWhereSingle(strategy)];
|
|
5675
|
+
let body = stringify({
|
|
5676
|
+
path: 'update',
|
|
5677
|
+
args
|
|
5678
|
+
});
|
|
5679
|
+
let adapter = netAdapter(url, tableName, { axios: axiosInterceptor, tableOptions });
|
|
5680
|
+
const result = await adapter.post(body);
|
|
5681
|
+
if (strategy)
|
|
5682
|
+
return proxify(result, strategy);
|
|
5683
|
+
}
|
|
5684
|
+
|
|
5685
|
+
async function replace(_row, strategy) {
|
|
5686
|
+
let args = [_row, negotiateWhereSingle(strategy)];
|
|
5687
|
+
let body = stringify({
|
|
5688
|
+
path: 'replace',
|
|
5689
|
+
args
|
|
5690
|
+
});
|
|
5691
|
+
let adapter = netAdapter(url, tableName, { axios: axiosInterceptor, tableOptions });
|
|
5692
|
+
const result = await adapter.post(body);
|
|
5693
|
+
if (strategy)
|
|
5694
|
+
return proxify(result, strategy);
|
|
5686
5695
|
}
|
|
5687
5696
|
|
|
5688
5697
|
async function updateChanges(rows, oldRows, ...rest) {
|
|
5689
5698
|
const concurrency = undefined;
|
|
5690
5699
|
const args = [concurrency].concat(rest);
|
|
5691
5700
|
if (Array.isArray(rows)) {
|
|
5692
|
-
//todo
|
|
5693
5701
|
const proxy = await getMany.apply(null, [rows, ...rest]);
|
|
5694
5702
|
proxy.splice.apply(proxy, [0, proxy.length, ...rows]);
|
|
5695
5703
|
await proxy.saveChanges.apply(proxy, args);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
const createPatch = require('../client/createPatch');
|
|
2
|
+
const emptyFilter = require('../emptyFilter');
|
|
2
3
|
const negotiateRawSqlFilter = require('../table/column/negotiateRawSqlFilter');
|
|
3
4
|
let getMeta = require('./getMeta');
|
|
4
5
|
let isSafe = Symbol();
|
|
@@ -70,7 +71,8 @@ let _allowedOps = {
|
|
|
70
71
|
|
|
71
72
|
async function executePath({ table, JSONFilter, baseFilter, customFilters = {}, request, response, readonly, disableBulkDeletes, isHttp, client }) {
|
|
72
73
|
let allowedOps = { ..._allowedOps, insert: !readonly, ...extractRelations(getMeta(table)) };
|
|
73
|
-
let ops = { ..._ops, ...getCustomFilterPaths(customFilters), getManyDto, getMany, aggregate, count, delete: _delete, cascadeDelete };
|
|
74
|
+
let ops = { ..._ops, ...getCustomFilterPaths(customFilters), getManyDto, getMany, aggregate, count, delete: _delete, cascadeDelete, update, replace };
|
|
75
|
+
|
|
74
76
|
let res = await parseFilter(JSONFilter, table);
|
|
75
77
|
if (res === undefined)
|
|
76
78
|
return {};
|
|
@@ -85,7 +87,7 @@ async function executePath({ table, JSONFilter, baseFilter, customFilters = {},
|
|
|
85
87
|
if (anyAllNone) {
|
|
86
88
|
if (isHttp)
|
|
87
89
|
validateArgs(json.args[0]);
|
|
88
|
-
const f =
|
|
90
|
+
const f = anyAllNone(x => parseFilter(json.args[0], x));
|
|
89
91
|
f.isSafe = isSafe;
|
|
90
92
|
return f;
|
|
91
93
|
}
|
|
@@ -114,7 +116,7 @@ async function executePath({ table, JSONFilter, baseFilter, customFilters = {},
|
|
|
114
116
|
let ops = new Set(['all', 'any', 'none', 'where', '_aggregate']);
|
|
115
117
|
// let ops = new Set(['all', 'any', 'none', 'where']);
|
|
116
118
|
let last = path.slice(-1)[0];
|
|
117
|
-
if (ops.has(last) || (table &&
|
|
119
|
+
if (ops.has(last) || (table && (table._primaryColumns || (table.any && table.all))))
|
|
118
120
|
return table;
|
|
119
121
|
}
|
|
120
122
|
|
|
@@ -136,7 +138,7 @@ async function executePath({ table, JSONFilter, baseFilter, customFilters = {},
|
|
|
136
138
|
let op = pathArray[pathArray.length - 1];
|
|
137
139
|
if (!allowedOps[op] && isHttp) {
|
|
138
140
|
|
|
139
|
-
let e =
|
|
141
|
+
let e = new Error('Disallowed operator ' + op);
|
|
140
142
|
// @ts-ignore
|
|
141
143
|
e.status = 403;
|
|
142
144
|
throw e;
|
|
@@ -146,6 +148,8 @@ async function executePath({ table, JSONFilter, baseFilter, customFilters = {},
|
|
|
146
148
|
target = target[pathArray[i]];
|
|
147
149
|
}
|
|
148
150
|
|
|
151
|
+
if (!target)
|
|
152
|
+
throw new Error(`Method '${path}' does not exist`);
|
|
149
153
|
let res = target.apply(null, args);
|
|
150
154
|
setSafe(res);
|
|
151
155
|
return res;
|
|
@@ -272,6 +276,66 @@ async function executePath({ table, JSONFilter, baseFilter, customFilters = {},
|
|
|
272
276
|
return table.getManyDto.apply(null, args);
|
|
273
277
|
}
|
|
274
278
|
|
|
279
|
+
async function replace(subject, strategy = { insertAndForget: true }) {
|
|
280
|
+
validateStrategy(table, strategy);
|
|
281
|
+
const refinedStrategy = objectToStrategy(subject, {}, table);
|
|
282
|
+
const JSONFilter2 = {
|
|
283
|
+
path: 'getManyDto',
|
|
284
|
+
args: [subject, refinedStrategy]
|
|
285
|
+
};
|
|
286
|
+
const originals = await executePath({ table, JSONFilter: JSONFilter2, baseFilter, customFilters, request, response, readonly, disableBulkDeletes, isHttp, client });
|
|
287
|
+
const meta = getMeta(table);
|
|
288
|
+
const patch = createPatch(originals, Array.isArray(subject) ? subject : [subject], meta);
|
|
289
|
+
const { changed } = await table.patch(patch, { strategy });
|
|
290
|
+
if (Array.isArray(subject))
|
|
291
|
+
return changed;
|
|
292
|
+
else
|
|
293
|
+
return changed[0];
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
async function update(subject, whereStrategy, strategy = { insertAndForget: true }) {
|
|
297
|
+
validateStrategy(table, strategy);
|
|
298
|
+
const refinedWhereStrategy = objectToStrategy(subject, whereStrategy, table);
|
|
299
|
+
const JSONFilter2 = {
|
|
300
|
+
path: 'getManyDto',
|
|
301
|
+
args: [null, refinedWhereStrategy]
|
|
302
|
+
};
|
|
303
|
+
const rows = await executePath({ table, JSONFilter: JSONFilter2, baseFilter, customFilters, request, response, readonly, disableBulkDeletes, isHttp, client });
|
|
304
|
+
const originals = new Array(rows.length);
|
|
305
|
+
for (let i = 0; i < rows.length; i++) {
|
|
306
|
+
const row = rows[i];
|
|
307
|
+
originals[i] = { ...row };
|
|
308
|
+
for (let p in subject) {
|
|
309
|
+
row[p] = subject[p];
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const meta = getMeta(table);
|
|
313
|
+
const patch = createPatch(originals, rows, meta);
|
|
314
|
+
const { changed } = await table.patch(patch, { strategy });
|
|
315
|
+
return changed;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function objectToStrategy(object, whereStrategy, table, strategy = {}) {
|
|
319
|
+
strategy = {...whereStrategy, ...strategy};
|
|
320
|
+
if (Array.isArray(object)) {
|
|
321
|
+
for (let i = 0; i < object.length; i++) {
|
|
322
|
+
objectToStrategy(object[i], table, strategy);
|
|
323
|
+
}
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
for (let name in object) {
|
|
327
|
+
const relation = table[name]?._relation;
|
|
328
|
+
if (relation && !relation.columns) {//notJoin, that is one or many
|
|
329
|
+
strategy[name] = {};
|
|
330
|
+
objectToStrategy(object[name], whereStrategy?.[name], table[name], strategy[name]);
|
|
331
|
+
}
|
|
332
|
+
else
|
|
333
|
+
strategy[name] = true;
|
|
334
|
+
}
|
|
335
|
+
return strategy;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
|
|
275
339
|
async function aggregate(filter, strategy) {
|
|
276
340
|
validateStrategy(table, strategy);
|
|
277
341
|
filter = negotiateFilter(filter);
|
|
@@ -283,11 +347,13 @@ async function executePath({ table, JSONFilter, baseFilter, customFilters = {},
|
|
|
283
347
|
return table.aggregate.apply(null, args);
|
|
284
348
|
}
|
|
285
349
|
|
|
350
|
+
|
|
351
|
+
|
|
286
352
|
async function negotiateWhereAndAggregate(strategy) {
|
|
287
353
|
if (typeof strategy !== 'object')
|
|
288
354
|
return;
|
|
289
355
|
|
|
290
|
-
for(let name in strategy) {
|
|
356
|
+
for (let name in strategy) {
|
|
291
357
|
const target = strategy[name];
|
|
292
358
|
if (isFilter(target))
|
|
293
359
|
strategy[name] = await parseFilter(strategy[name], table);
|
|
@@ -325,7 +391,7 @@ function validateStrategy(table, strategy) {
|
|
|
325
391
|
function validateLimit(strategy) {
|
|
326
392
|
if (!('limit' in strategy) || Number.isInteger(strategy.limit))
|
|
327
393
|
return;
|
|
328
|
-
const e =
|
|
394
|
+
const e = new Error('Invalid limit: ' + strategy.limit);
|
|
329
395
|
// @ts-ignore
|
|
330
396
|
e.status = 400;
|
|
331
397
|
}
|
|
@@ -333,7 +399,7 @@ function validateLimit(strategy) {
|
|
|
333
399
|
function validateOffset(strategy) {
|
|
334
400
|
if (!('offset' in strategy) || Number.isInteger(strategy.offset))
|
|
335
401
|
return;
|
|
336
|
-
const e =
|
|
402
|
+
const e = new Error('Invalid offset: ' + strategy.offset);
|
|
337
403
|
// @ts-ignore
|
|
338
404
|
e.status = 400;
|
|
339
405
|
throw e;
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
let extractSubStrategy = _extractSubStrategy;
|
|
2
|
-
|
|
3
|
-
function _extractSubStrategy(table, map) {
|
|
4
|
-
extractSubStrategy = require('./getMeta');
|
|
5
|
-
return extractSubStrategy(table, map);
|
|
6
|
-
}
|
|
7
|
-
|
|
8
1
|
function getMeta(table, map = new Map()) {
|
|
9
2
|
if (map.has(table))
|
|
10
3
|
return map.get(table).id;
|
|
@@ -30,11 +23,11 @@ function getMeta(table, map = new Map()) {
|
|
|
30
23
|
|
|
31
24
|
let visitor = {};
|
|
32
25
|
visitor.visitJoin = function(relation) {
|
|
33
|
-
strategy.relations[relationName] =
|
|
26
|
+
strategy.relations[relationName] = getMeta(relation.childTable, map);
|
|
34
27
|
};
|
|
35
28
|
|
|
36
29
|
visitor.visitMany = function(relation) {
|
|
37
|
-
strategy.relations[relationName] =
|
|
30
|
+
strategy.relations[relationName] = getMeta(relation.childTable, map);
|
|
38
31
|
};
|
|
39
32
|
|
|
40
33
|
visitor.visitOne = visitor.visitMany;
|
package/src/map.d.ts
CHANGED
|
@@ -167,37 +167,48 @@ type ExpandedMappedTable<T, FL = ExpandedFetchingStrategy<T>> = {
|
|
|
167
167
|
fetchingStrategy?: FS
|
|
168
168
|
): Promise<StrategyToRow<FetchedProperties<T, FL>, T>>;
|
|
169
169
|
|
|
170
|
-
|
|
171
170
|
update(
|
|
172
|
-
|
|
171
|
+
values: StrategyToUpdateRowData<T>,
|
|
172
|
+
where: FetchingStrategy<T>
|
|
173
|
+
): Promise<void>;
|
|
174
|
+
|
|
175
|
+
update<FS extends FetchingStrategy<T>>(
|
|
176
|
+
values: StrategyToUpdateRowData<T>,
|
|
177
|
+
where: FetchingStrategy<T>,
|
|
178
|
+
strategy: FS
|
|
179
|
+
): Promise<StrategyToRowArray<FetchedProperties<T, FL>, T>>;
|
|
180
|
+
|
|
181
|
+
replace(
|
|
182
|
+
row: StrategyToInsertRowData<T> | StrategyToInsertRowData<T>[]
|
|
183
|
+
): Promise<void>;
|
|
184
|
+
|
|
185
|
+
replace<FS extends FetchingStrategy<T>>(
|
|
186
|
+
row: StrategyToInsertRowData<T>,
|
|
187
|
+
strategy: FS
|
|
173
188
|
): Promise<StrategyToRow<FetchedProperties<T, FL>, T>>;
|
|
189
|
+
|
|
190
|
+
replace<FS extends FetchingStrategy<T>>(
|
|
191
|
+
rows: StrategyToInsertRowData<T>[],
|
|
192
|
+
strategy: FS
|
|
193
|
+
): Promise<StrategyToRowArray<FetchedProperties<T, FL>, T>>;
|
|
194
|
+
|
|
195
|
+
|
|
174
196
|
updateChanges(
|
|
175
197
|
row: StrategyToInsertRowData<T>,
|
|
176
198
|
originalRow: StrategyToInsertRowData<T>
|
|
177
199
|
): Promise<StrategyToRow<FetchedProperties<T, FL>, T>>;
|
|
178
200
|
|
|
179
|
-
update(
|
|
180
|
-
rows: StrategyToInsertRowData<T>[]
|
|
181
|
-
): Promise<StrategyToRowArray<FetchedProperties<T, FL>, T>>;
|
|
182
201
|
updateChanges(
|
|
183
202
|
rows: StrategyToInsertRowData<T>[],
|
|
184
203
|
originalRows: StrategyToInsertRowData<T>[]
|
|
185
204
|
): Promise<StrategyToRowArray<FetchedProperties<T, FL>, T>>;
|
|
186
205
|
|
|
187
|
-
update<FS extends FetchingStrategy<T>>(
|
|
188
|
-
row: StrategyToInsertRowData<T>,
|
|
189
|
-
strategy: FS
|
|
190
|
-
): Promise<StrategyToRow<FetchedProperties<T, FL>, T>>;
|
|
191
206
|
updateChanges<FS extends FetchingStrategy<T>>(
|
|
192
207
|
row: StrategyToInsertRowData<T>,
|
|
193
208
|
originalRow: StrategyToInsertRowData<T>,
|
|
194
209
|
strategy: FS
|
|
195
210
|
): Promise<StrategyToRow<FetchedProperties<T, FL>, T>>;
|
|
196
211
|
|
|
197
|
-
update<FS extends FetchingStrategy<T>>(
|
|
198
|
-
rows: StrategyToInsertRowData<T>[],
|
|
199
|
-
strategy: FS
|
|
200
|
-
): Promise<StrategyToRowArray<FetchedProperties<T, FL>, T>>;
|
|
201
212
|
updateChanges<FS extends FetchingStrategy<T>>(
|
|
202
213
|
rows: StrategyToInsertRowData<T>[],
|
|
203
214
|
originalRows: StrategyToInsertRowData<T>[],
|
|
@@ -295,37 +306,49 @@ type MappedTable<T> = {
|
|
|
295
306
|
filter?: Filter | PrimaryRowFilter<T>,
|
|
296
307
|
fetchingStrategy?: FS
|
|
297
308
|
): Promise<StrategyToRow<FetchedProperties<T, FS>, T>>;
|
|
298
|
-
|
|
309
|
+
|
|
299
310
|
update(
|
|
300
|
-
|
|
301
|
-
|
|
311
|
+
values: StrategyToUpdateRowData<T>,
|
|
312
|
+
where: FetchingStrategy<T>
|
|
313
|
+
): Promise<void>;
|
|
314
|
+
|
|
315
|
+
update<FS extends FetchingStrategy<T>>(
|
|
316
|
+
values: StrategyToUpdateRowData<T>,
|
|
317
|
+
where: FetchingStrategy<T>,
|
|
318
|
+
strategy: FS
|
|
319
|
+
): Promise<StrategyToRowArray<FetchedProperties<T, FS>, T>>;
|
|
320
|
+
|
|
321
|
+
replace(
|
|
322
|
+
row: StrategyToInsertRowData<T> | StrategyToInsertRowData<T>[]
|
|
323
|
+
): Promise<void>;
|
|
324
|
+
|
|
325
|
+
replace<FS extends FetchingStrategy<T>>(
|
|
326
|
+
row: StrategyToInsertRowData<T>,
|
|
327
|
+
strategy: FS
|
|
328
|
+
): Promise<StrategyToRow<FetchedProperties<T, FS>, T>>;
|
|
329
|
+
|
|
330
|
+
replace<FS extends FetchingStrategy<T>>(
|
|
331
|
+
rows: StrategyToInsertRowData<T>[],
|
|
332
|
+
strategy: FS
|
|
333
|
+
): Promise<StrategyToRowArray<FetchedProperties<T, FS>, T>>;
|
|
334
|
+
|
|
302
335
|
updateChanges(
|
|
303
336
|
modifiedRow: StrategyToInsertRowData<T>,
|
|
304
337
|
originalRow: StrategyToInsertRowData<T>
|
|
305
338
|
): Promise<StrategyToRow<FetchedProperties<T, {}>, T>>;
|
|
306
339
|
|
|
307
|
-
|
|
308
|
-
rows: StrategyToInsertRowData<T>[]
|
|
309
|
-
): Promise<StrategyToRowArray<FetchedProperties<T, {}>, T>>;
|
|
340
|
+
|
|
310
341
|
updateChanges(
|
|
311
342
|
modifiedRows: StrategyToInsertRowData<T>[],
|
|
312
343
|
originalRows: StrategyToInsertRowData<T>[]
|
|
313
344
|
): Promise<StrategyToRowArray<FetchedProperties<T, {}>, T>>;
|
|
314
345
|
|
|
315
|
-
update<FS extends FetchingStrategy<T>>(
|
|
316
|
-
row: StrategyToInsertRowData<T>,
|
|
317
|
-
strategy: FS
|
|
318
|
-
): Promise<StrategyToRow<FetchedProperties<T, FS>, T>>;
|
|
319
346
|
updateChanges<FS extends FetchingStrategy<T>>(
|
|
320
347
|
modifiedRow: StrategyToInsertRowData<T>,
|
|
321
348
|
originalRow: StrategyToInsertRowData<T>,
|
|
322
349
|
strategy: FS
|
|
323
350
|
): Promise<StrategyToRow<FetchedProperties<T, FS>, T>>;
|
|
324
351
|
|
|
325
|
-
update<FS extends FetchingStrategy<T>>(
|
|
326
|
-
rows: StrategyToInsertRowData<T>[],
|
|
327
|
-
strategy: FS
|
|
328
|
-
): Promise<StrategyToRowArray<FetchedProperties<T, FS>, T>>;
|
|
329
352
|
updateChanges<FS extends FetchingStrategy<T>>(
|
|
330
353
|
modifiedRows: StrategyToInsertRowData<T>[],
|
|
331
354
|
originalRows: StrategyToInsertRowData<T>[],
|
|
@@ -1155,6 +1178,31 @@ type StrategyToRowData<T> = {
|
|
|
1155
1178
|
: StrategyToRowData<T[K]>;
|
|
1156
1179
|
};
|
|
1157
1180
|
|
|
1181
|
+
type StrategyToUpdateRowData<T> = Omit<{
|
|
1182
|
+
[K in keyof T]?: T[K] extends StringColumnSymbol
|
|
1183
|
+
? string
|
|
1184
|
+
: T[K] extends UuidColumnSymbol
|
|
1185
|
+
? string
|
|
1186
|
+
: T[K] extends NumericColumnSymbol
|
|
1187
|
+
? number
|
|
1188
|
+
: T[K] extends DateColumnSymbol
|
|
1189
|
+
? string | Date
|
|
1190
|
+
: T[K] extends DateWithTimeZoneColumnSymbol
|
|
1191
|
+
? string | Date
|
|
1192
|
+
: T[K] extends BinaryColumnSymbol
|
|
1193
|
+
? string
|
|
1194
|
+
: T[K] extends BooleanColumnSymbol
|
|
1195
|
+
? boolean
|
|
1196
|
+
: T[K] extends JsonOf<infer M>
|
|
1197
|
+
? M
|
|
1198
|
+
: T[K] extends JSONColumnSymbol
|
|
1199
|
+
? JsonType
|
|
1200
|
+
: T[K] extends ManyRelation
|
|
1201
|
+
? StrategyToInsertRowData<T[K]>[]
|
|
1202
|
+
: StrategyToInsertRowData<T[K]>;
|
|
1203
|
+
}, 'formulaDiscriminators' | 'columnDiscriminators' | 'map' | ' isManyRelation' | ' relatedTable' | ' isOneRelation'>
|
|
1204
|
+
;
|
|
1205
|
+
|
|
1158
1206
|
type StrategyToInsertRowData<T> = Omit<{
|
|
1159
1207
|
[K in keyof RemoveNever<
|
|
1160
1208
|
NotNullInsertProperties<T>
|
|
@@ -31,7 +31,7 @@ async function validateDeleteConflict({ row, oldValue, options, table }) {
|
|
|
31
31
|
let childRow = await childTable.tryGetById.apply(null, JSON.parse(name));
|
|
32
32
|
if (!childRow)
|
|
33
33
|
throw new Error(`${p} with id ${name} was deleted by another user`);
|
|
34
|
-
if (! await validateDeleteConflict({ row: childRow, oldValue: oldValue[p][name],
|
|
34
|
+
if (! await validateDeleteConflict({ row: childRow, oldValue: oldValue[p][name], options: inferOptions(options, p), table: childTable }))
|
|
35
35
|
return false;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -40,7 +40,7 @@ async function validateDeleteConflict({ row, oldValue, options, table }) {
|
|
|
40
40
|
let childRow = await row[p];
|
|
41
41
|
if (!childRow)
|
|
42
42
|
throw new Error(`${p} was deleted by another user`);
|
|
43
|
-
if (! await validateDeleteConflict({ row: childRow, oldValue: oldValue[p],
|
|
43
|
+
if (! await validateDeleteConflict({ row: childRow, oldValue: oldValue[p], options: inferOptions(options, p), table: childTable }))
|
|
44
44
|
return false;
|
|
45
45
|
}
|
|
46
46
|
|