proto.io 0.0.164 → 0.0.165
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/adapters/file/database.d.ts +2 -2
- package/dist/adapters/file/database.js.map +1 -1
- package/dist/adapters/file/database.mjs +2 -2
- package/dist/adapters/file/database.mjs.map +1 -1
- package/dist/adapters/file/filesystem.d.ts +2 -2
- package/dist/adapters/file/filesystem.js.map +1 -1
- package/dist/adapters/file/filesystem.mjs.map +1 -1
- package/dist/adapters/file/google-cloud-storage.d.ts +2 -2
- package/dist/adapters/file/google-cloud-storage.js.map +1 -1
- package/dist/adapters/file/google-cloud-storage.mjs.map +1 -1
- package/dist/adapters/storage/progres.d.ts +16 -13
- package/dist/adapters/storage/progres.js +136 -81
- package/dist/adapters/storage/progres.js.map +1 -1
- package/dist/adapters/storage/progres.mjs +138 -83
- package/dist/adapters/storage/progres.mjs.map +1 -1
- package/dist/client.d.ts +3 -3
- package/dist/client.mjs +3 -3
- package/dist/index.d.ts +7 -12
- package/dist/index.js +24 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +28 -27
- package/dist/index.mjs.map +1 -1
- package/dist/internals/{index-ByfpVHca.mjs → index-BYbMU-Ao.mjs} +2 -2
- package/dist/internals/{index-ByfpVHca.mjs.map → index-BYbMU-Ao.mjs.map} +1 -1
- package/dist/internals/{index-S5Bq-KsU.mjs → index-BejQNqvC.mjs} +2 -2
- package/dist/internals/{index-S5Bq-KsU.mjs.map → index-BejQNqvC.mjs.map} +1 -1
- package/dist/internals/{index-BoP4kl2R.mjs → index-BibByOcU.mjs} +2 -2
- package/dist/internals/{index-BoP4kl2R.mjs.map → index-BibByOcU.mjs.map} +1 -1
- package/dist/internals/index-BqFdBhFc.js.map +1 -1
- package/dist/internals/index-CSNRyhjB.js.map +1 -1
- package/dist/internals/index-CVutVPmd.js.map +1 -1
- package/dist/internals/{index-BeV63sFw.d.ts → index-DaDfXlay.d.ts} +2 -2
- package/dist/internals/index-DaDfXlay.d.ts.map +1 -0
- package/dist/internals/index-Dz3jvqxZ.js.map +1 -1
- package/dist/internals/{index-YdOGTHp1.d.ts → index-RPh4TX0T.d.ts} +3 -2
- package/dist/internals/index-RPh4TX0T.d.ts.map +1 -0
- package/dist/internals/{index-BsuUdR0W.d.ts → index-bCACA0cS.d.ts} +2 -2
- package/dist/internals/index-bCACA0cS.d.ts.map +1 -0
- package/dist/internals/index-be1VYBY2.mjs.map +1 -1
- package/dist/internals/{random-w8WDYQEe.mjs → random-B1P0EZO5.mjs} +5 -10
- package/dist/internals/random-B1P0EZO5.mjs.map +1 -0
- package/dist/internals/{random-uT4D0y_q.js → random-q0PeamQE.js} +3 -8
- package/dist/internals/random-q0PeamQE.js.map +1 -0
- package/package.json +20 -20
- package/dist/internals/index-BeV63sFw.d.ts.map +0 -1
- package/dist/internals/index-BsuUdR0W.d.ts.map +0 -1
- package/dist/internals/index-YdOGTHp1.d.ts.map +0 -1
- package/dist/internals/random-uT4D0y_q.js.map +0 -1
- package/dist/internals/random-w8WDYQEe.mjs.map +0 -1
|
@@ -11,7 +11,7 @@ var Decimal = require('decimal.js');
|
|
|
11
11
|
var utils = require('pg/lib/utils');
|
|
12
12
|
var index$1 = require('../../internals/index-CSNRyhjB.js');
|
|
13
13
|
require('@o2ter/crypto-js');
|
|
14
|
-
var random$1 = require('../../internals/random-
|
|
14
|
+
var random$1 = require('../../internals/random-q0PeamQE.js');
|
|
15
15
|
var _private = require('../../internals/private-CSB1Ep4g.js');
|
|
16
16
|
|
|
17
17
|
//
|
|
@@ -224,12 +224,14 @@ class QueryCompiler {
|
|
|
224
224
|
dialect;
|
|
225
225
|
selectLock;
|
|
226
226
|
isUpdate;
|
|
227
|
+
extraFilter;
|
|
227
228
|
idx = 0;
|
|
228
|
-
constructor(
|
|
229
|
-
this.schema = schema;
|
|
230
|
-
this.dialect = dialect;
|
|
231
|
-
this.selectLock = selectLock;
|
|
232
|
-
this.isUpdate = isUpdate;
|
|
229
|
+
constructor(options) {
|
|
230
|
+
this.schema = options.schema;
|
|
231
|
+
this.dialect = options.dialect;
|
|
232
|
+
this.selectLock = options.selectLock;
|
|
233
|
+
this.isUpdate = options.isUpdate;
|
|
234
|
+
this.extraFilter = options.extraFilter;
|
|
233
235
|
}
|
|
234
236
|
nextIdx() {
|
|
235
237
|
return this.idx++;
|
|
@@ -286,11 +288,11 @@ class QueryCompiler {
|
|
|
286
288
|
}
|
|
287
289
|
_baseSelectQuery(query, options) {
|
|
288
290
|
const context = this._makeContext(query);
|
|
289
|
-
const _stages = _.mapValues(context.populates, (populate) => this.dialect.encodePopulate(this,
|
|
291
|
+
const _stages = _.mapValues(context.populates, (populate) => this.dialect.encodePopulate(this, populate));
|
|
290
292
|
const stages = _.fromPairs(_.flatMap(_.values(_stages), (p) => _.toPairs(p)));
|
|
291
293
|
const fetchName = `_fetch_$${query.className.toLowerCase()}`;
|
|
292
294
|
const parent = { className: query.className, name: fetchName };
|
|
293
|
-
const baseFilter = this._encodeFilter(
|
|
295
|
+
const baseFilter = this._encodeFilter(parent, query.filter);
|
|
294
296
|
const populates = this._selectPopulateMap(context, query.className, fetchName);
|
|
295
297
|
const joins = _.compact(_.map(populates, ({ join }) => join));
|
|
296
298
|
const includes = {
|
|
@@ -304,7 +306,7 @@ class QueryCompiler {
|
|
|
304
306
|
const filter = _.compact([
|
|
305
307
|
baseFilter,
|
|
306
308
|
_options?.extraFilter,
|
|
307
|
-
query.relatedBy && this.dialect.encodeRelation(this,
|
|
309
|
+
query.relatedBy && this.dialect.encodeRelation(this, parent, query.relatedBy),
|
|
308
310
|
]);
|
|
309
311
|
return {
|
|
310
312
|
stages,
|
|
@@ -325,9 +327,9 @@ class QueryCompiler {
|
|
|
325
327
|
`,
|
|
326
328
|
};
|
|
327
329
|
}
|
|
328
|
-
_refetch(name, query
|
|
330
|
+
_refetch(name, query) {
|
|
329
331
|
const _context = this._encodeIncludes(query.className, query.includes, query.matches);
|
|
330
|
-
const populates = _.mapValues(_context.populates, (populate) => this.dialect.encodePopulate(this,
|
|
332
|
+
const populates = _.mapValues(_context.populates, (populate) => this.dialect.encodePopulate(this, populate, { className: query.className, name }));
|
|
331
333
|
const stages = _.fromPairs(_.flatMap(_.values(populates), (p) => _.toPairs(p)));
|
|
332
334
|
const _populates = this._selectPopulateMap(_context, query.className, name);
|
|
333
335
|
const _joins = _.compact(_.map(_populates, ({ join }) => join));
|
|
@@ -398,8 +400,8 @@ class QueryCompiler {
|
|
|
398
400
|
}
|
|
399
401
|
return result;
|
|
400
402
|
}
|
|
401
|
-
_encodeCoditionalSelector(parent, filter
|
|
402
|
-
const queries = _.compact(_.map(filter.exprs, x => this._encodeFilter(
|
|
403
|
+
_encodeCoditionalSelector(parent, filter) {
|
|
404
|
+
const queries = _.compact(_.map(filter.exprs, x => this._encodeFilter(parent, x)));
|
|
403
405
|
if (_.isEmpty(queries))
|
|
404
406
|
return;
|
|
405
407
|
switch (filter.type) {
|
|
@@ -408,12 +410,12 @@ class QueryCompiler {
|
|
|
408
410
|
case '$or': return sql `(${{ literal: _.map(queries, x => sql `(${x})`), separator: ' OR ' }})`;
|
|
409
411
|
}
|
|
410
412
|
}
|
|
411
|
-
_encodeFilter(
|
|
413
|
+
_encodeFilter(parent, filter) {
|
|
412
414
|
if (filter instanceof index$1.QueryCoditionalSelector) {
|
|
413
|
-
return this._encodeCoditionalSelector(parent, filter
|
|
415
|
+
return this._encodeCoditionalSelector(parent, filter);
|
|
414
416
|
}
|
|
415
417
|
if (filter instanceof index$1.QueryFieldSelector) {
|
|
416
|
-
return this.dialect.encodeFieldExpression(this,
|
|
418
|
+
return this.dialect.encodeFieldExpression(this, parent, filter.field, filter.expr);
|
|
417
419
|
}
|
|
418
420
|
if (filter instanceof index$1.QueryExpressionSelector) {
|
|
419
421
|
return this.dialect.encodeQueryExpression(this, parent, filter.expr);
|
|
@@ -454,7 +456,7 @@ class QueryCompiler {
|
|
|
454
456
|
});
|
|
455
457
|
const name = `_insert_$${options.className.toLowerCase()}`;
|
|
456
458
|
const context = this._makeContext(options);
|
|
457
|
-
const populates = _.mapValues(context.populates, (populate) => this.dialect.encodePopulate(this,
|
|
459
|
+
const populates = _.mapValues(context.populates, (populate) => this.dialect.encodePopulate(this, populate));
|
|
458
460
|
const stages = _.fromPairs(_.flatMap(_.values(populates), (p) => _.toPairs(p)));
|
|
459
461
|
const _populates = this._selectPopulateMap(context, options.className, name);
|
|
460
462
|
const joins = _.compact(_.map(_populates, ({ join }) => join));
|
|
@@ -489,7 +491,7 @@ class QueryCompiler {
|
|
|
489
491
|
`;
|
|
490
492
|
}
|
|
491
493
|
updateOne(query, update) {
|
|
492
|
-
return this._modifyQuery({ ...query, limit: 1 }, (fetchName
|
|
494
|
+
return this._modifyQuery({ ...query, limit: 1 }, (fetchName) => {
|
|
493
495
|
const name = `_update_$${query.className.toLowerCase()}`;
|
|
494
496
|
return sql `
|
|
495
497
|
, ${{ identifier: name }} AS (
|
|
@@ -499,7 +501,7 @@ class QueryCompiler {
|
|
|
499
501
|
WHERE ${{ identifier: query.className }}._id IN (SELECT ${{ identifier: fetchName }}._id FROM ${{ identifier: fetchName }})
|
|
500
502
|
RETURNING *
|
|
501
503
|
)
|
|
502
|
-
${this._refetch(name, query
|
|
504
|
+
${this._refetch(name, query)}
|
|
503
505
|
`;
|
|
504
506
|
});
|
|
505
507
|
}
|
|
@@ -508,7 +510,7 @@ class QueryCompiler {
|
|
|
508
510
|
..._defaultInsertOpts(query),
|
|
509
511
|
...this._encodeObjectAttrs(query.className, setOnInsert),
|
|
510
512
|
});
|
|
511
|
-
return this._modifyQuery({ ...query, limit: 1 }, (fetchName
|
|
513
|
+
return this._modifyQuery({ ...query, limit: 1 }, (fetchName) => {
|
|
512
514
|
const updateName = `_update_$${query.className.toLowerCase()}`;
|
|
513
515
|
const insertName = `_insert_$${query.className.toLowerCase()}`;
|
|
514
516
|
const upsertName = `_upsert_$${query.className.toLowerCase()}`;
|
|
@@ -532,7 +534,7 @@ class QueryCompiler {
|
|
|
532
534
|
UNION
|
|
533
535
|
SELECT * FROM ${{ identifier: insertName }}
|
|
534
536
|
)
|
|
535
|
-
${this._refetch(upsertName, query
|
|
537
|
+
${this._refetch(upsertName, query)}
|
|
536
538
|
`;
|
|
537
539
|
});
|
|
538
540
|
}
|
|
@@ -667,12 +669,21 @@ class SqlStorage {
|
|
|
667
669
|
}
|
|
668
670
|
return obj;
|
|
669
671
|
}
|
|
672
|
+
_makeCompiler(isUpdate, extraFilter) {
|
|
673
|
+
return new QueryCompiler({
|
|
674
|
+
schema: this.schema,
|
|
675
|
+
dialect: this.dialect,
|
|
676
|
+
selectLock: this.selectLock(),
|
|
677
|
+
isUpdate,
|
|
678
|
+
extraFilter,
|
|
679
|
+
});
|
|
680
|
+
}
|
|
670
681
|
async explain(query) {
|
|
671
|
-
const compiler =
|
|
682
|
+
const compiler = this._makeCompiler(false, query.extraFilter);
|
|
672
683
|
return this._explain(compiler, query);
|
|
673
684
|
}
|
|
674
685
|
async count(query) {
|
|
675
|
-
const compiler =
|
|
686
|
+
const compiler = this._makeCompiler(false, query.extraFilter);
|
|
676
687
|
const [{ count: _count }] = await this.query(compiler._selectQuery(query, {
|
|
677
688
|
select: sql `COUNT(*) AS count`,
|
|
678
689
|
}));
|
|
@@ -681,7 +692,7 @@ class SqlStorage {
|
|
|
681
692
|
}
|
|
682
693
|
find(query) {
|
|
683
694
|
const self = this;
|
|
684
|
-
const compiler =
|
|
695
|
+
const compiler = self._makeCompiler(false, query.extraFilter);
|
|
685
696
|
const _query = compiler._selectQuery(query);
|
|
686
697
|
return (async function* () {
|
|
687
698
|
const objects = self.query(_query);
|
|
@@ -692,7 +703,7 @@ class SqlStorage {
|
|
|
692
703
|
}
|
|
693
704
|
random(query, opts) {
|
|
694
705
|
const self = this;
|
|
695
|
-
const compiler =
|
|
706
|
+
const compiler = self._makeCompiler(false, query.extraFilter);
|
|
696
707
|
const _query = compiler._selectQuery({ ...query, sort: {} }, {
|
|
697
708
|
sort: sql `ORDER BY ${self.dialect.random(opts ?? {})}`,
|
|
698
709
|
});
|
|
@@ -719,7 +730,7 @@ class SqlStorage {
|
|
|
719
730
|
}
|
|
720
731
|
nonrefs(query) {
|
|
721
732
|
const self = this;
|
|
722
|
-
const compiler =
|
|
733
|
+
const compiler = self._makeCompiler(false, query.extraFilter);
|
|
723
734
|
const _query = compiler._selectQuery(query, ({ fetchName }) => ({
|
|
724
735
|
extraFilter: sql `
|
|
725
736
|
NOT EXISTS (${this._refs(this.schema, query.className, ['_id'], sql `(${{ quote: query.className + '$' }} || ${{ identifier: fetchName }}.${{ identifier: '_id' }})`)})
|
|
@@ -733,32 +744,32 @@ class SqlStorage {
|
|
|
733
744
|
})();
|
|
734
745
|
}
|
|
735
746
|
async insert(options, attrs) {
|
|
736
|
-
const compiler =
|
|
747
|
+
const compiler = this._makeCompiler(true);
|
|
737
748
|
const result = _.first(await this.query(compiler.insert(options, attrs)));
|
|
738
749
|
return _.isNil(result) ? undefined : this._decodeObject(options.className, result);
|
|
739
750
|
}
|
|
740
751
|
async insertMany(options, values) {
|
|
741
|
-
const compiler =
|
|
752
|
+
const compiler = this._makeCompiler(true);
|
|
742
753
|
const result = await this.query(compiler.insertMany(options, values));
|
|
743
754
|
return result.length;
|
|
744
755
|
}
|
|
745
756
|
async updateOne(query, update) {
|
|
746
|
-
const compiler =
|
|
757
|
+
const compiler = this._makeCompiler(true, query.extraFilter);
|
|
747
758
|
const updated = _.first(await this.query(compiler.updateOne(query, update)));
|
|
748
759
|
return _.isNil(updated) ? undefined : this._decodeObject(query.className, updated);
|
|
749
760
|
}
|
|
750
761
|
async upsertOne(query, update, setOnInsert) {
|
|
751
|
-
const compiler =
|
|
762
|
+
const compiler = this._makeCompiler(true, query.extraFilter);
|
|
752
763
|
const upserted = _.first(await this.query(compiler.upsertOne(query, update, setOnInsert)));
|
|
753
764
|
return _.isNil(upserted) ? undefined : this._decodeObject(query.className, upserted);
|
|
754
765
|
}
|
|
755
766
|
async deleteOne(query) {
|
|
756
|
-
const compiler =
|
|
767
|
+
const compiler = this._makeCompiler(true, query.extraFilter);
|
|
757
768
|
const deleted = _.first(await this.query(compiler.deleteOne(query)));
|
|
758
769
|
return _.isNil(deleted) ? undefined : this._decodeObject(query.className, deleted);
|
|
759
770
|
}
|
|
760
771
|
async deleteMany(query) {
|
|
761
|
-
const compiler =
|
|
772
|
+
const compiler = this._makeCompiler(true, query.extraFilter);
|
|
762
773
|
const deleted = await this.query(compiler.deleteMany(query));
|
|
763
774
|
return deleted.length;
|
|
764
775
|
}
|
|
@@ -1114,10 +1125,55 @@ class PostgresClientDriver {
|
|
|
1114
1125
|
});
|
|
1115
1126
|
}
|
|
1116
1127
|
}
|
|
1128
|
+
class PostgresPubSub {
|
|
1129
|
+
client;
|
|
1130
|
+
subscribers = {};
|
|
1131
|
+
channels = [];
|
|
1132
|
+
constructor(client) {
|
|
1133
|
+
this.client = client;
|
|
1134
|
+
(async () => {
|
|
1135
|
+
try {
|
|
1136
|
+
(await client).on('notification', ({ channel, payload }) => {
|
|
1137
|
+
if (!payload)
|
|
1138
|
+
return;
|
|
1139
|
+
try {
|
|
1140
|
+
const _payload = index._decodeValue(JSON.parse(payload));
|
|
1141
|
+
for (const subscriber of this.subscribers[_.toUpper(channel)]) {
|
|
1142
|
+
subscriber(_payload);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
catch (e) {
|
|
1146
|
+
console.error(`Unknown payload: ${e}`);
|
|
1147
|
+
}
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
catch (e) {
|
|
1151
|
+
console.error(e);
|
|
1152
|
+
}
|
|
1153
|
+
})();
|
|
1154
|
+
}
|
|
1155
|
+
async shutdown() {
|
|
1156
|
+
(await this.client).release();
|
|
1157
|
+
}
|
|
1158
|
+
async listen(channel) {
|
|
1159
|
+
this.channels.push(channel);
|
|
1160
|
+
await (await this.client).query(`LISTEN ${channel}`);
|
|
1161
|
+
}
|
|
1162
|
+
subscribe(channel, callback) {
|
|
1163
|
+
if (_.isNil(this.subscribers[channel]))
|
|
1164
|
+
this.subscribers[channel] = [];
|
|
1165
|
+
this.subscribers[channel].push(callback);
|
|
1166
|
+
return () => {
|
|
1167
|
+
this.subscribers[channel] = this.subscribers[channel].filter(x => x !== callback);
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
isEmpty() {
|
|
1171
|
+
return _.every(_.values(this.subscribers), x => _.isEmpty(x));
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1117
1174
|
class PostgresDriver extends PostgresClientDriver {
|
|
1118
1175
|
database;
|
|
1119
1176
|
pubsub;
|
|
1120
|
-
subscribers = [];
|
|
1121
1177
|
constructor(config) {
|
|
1122
1178
|
if (_.isEmpty(config))
|
|
1123
1179
|
throw Error('Invalid postgre config.');
|
|
@@ -1130,26 +1186,11 @@ class PostgresDriver extends PostgresClientDriver {
|
|
|
1130
1186
|
await this._release_pubsub();
|
|
1131
1187
|
await this.database.end();
|
|
1132
1188
|
}
|
|
1133
|
-
|
|
1189
|
+
_init_pubsub() {
|
|
1134
1190
|
if (this.pubsub)
|
|
1135
1191
|
return;
|
|
1136
1192
|
try {
|
|
1137
|
-
this.pubsub = this.database.connect();
|
|
1138
|
-
const pubsub = await this.pubsub;
|
|
1139
|
-
pubsub.on('notification', ({ channel, payload }) => {
|
|
1140
|
-
if (_.toUpper(channel) !== PROTO_POSTGRES_MSG || !payload)
|
|
1141
|
-
return;
|
|
1142
|
-
try {
|
|
1143
|
-
const _payload = index._decodeValue(JSON.parse(payload));
|
|
1144
|
-
for (const subscriber of this.subscribers) {
|
|
1145
|
-
subscriber(_payload);
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
catch (e) {
|
|
1149
|
-
console.error(`Unknown payload: ${e}`);
|
|
1150
|
-
}
|
|
1151
|
-
});
|
|
1152
|
-
await pubsub.query(`LISTEN ${PROTO_POSTGRES_MSG}`);
|
|
1193
|
+
this.pubsub = new PostgresPubSub(this.database.connect());
|
|
1153
1194
|
}
|
|
1154
1195
|
catch (e) {
|
|
1155
1196
|
console.error(e);
|
|
@@ -1158,18 +1199,22 @@ class PostgresDriver extends PostgresClientDriver {
|
|
|
1158
1199
|
async _release_pubsub() {
|
|
1159
1200
|
const pubsub = this.pubsub;
|
|
1160
1201
|
this.pubsub = undefined;
|
|
1161
|
-
await
|
|
1202
|
+
await pubsub?.shutdown();
|
|
1162
1203
|
}
|
|
1163
|
-
|
|
1204
|
+
_subscribe(channel, callback) {
|
|
1164
1205
|
this._init_pubsub();
|
|
1165
|
-
this.
|
|
1206
|
+
if (!_.includes(this.pubsub.channels, channel))
|
|
1207
|
+
this.pubsub.listen(channel);
|
|
1208
|
+
const release = this.pubsub.subscribe(channel, callback);
|
|
1166
1209
|
return () => {
|
|
1167
|
-
|
|
1168
|
-
if (
|
|
1210
|
+
release();
|
|
1211
|
+
if (this.pubsub?.isEmpty())
|
|
1169
1212
|
this._release_pubsub();
|
|
1170
|
-
}
|
|
1171
1213
|
};
|
|
1172
1214
|
}
|
|
1215
|
+
subscribe(callback) {
|
|
1216
|
+
return this._subscribe(PROTO_POSTGRES_MSG, callback);
|
|
1217
|
+
}
|
|
1173
1218
|
}
|
|
1174
1219
|
|
|
1175
1220
|
//
|
|
@@ -1857,7 +1902,7 @@ const encodeQueryExpression = (compiler, parent, expr) => {
|
|
|
1857
1902
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
1858
1903
|
// THE SOFTWARE.
|
|
1859
1904
|
//
|
|
1860
|
-
const encodeFieldExpression = (compiler,
|
|
1905
|
+
const encodeFieldExpression = (compiler, parent, field, expr) => {
|
|
1861
1906
|
const [colname] = _.toPath(field);
|
|
1862
1907
|
const { element, dataType, relation } = fetchElement(compiler, parent, field);
|
|
1863
1908
|
const encodeValue = (value) => dataType ? encodeType(colname, dataType, value) : _encodeJsonValue(index._encodeValue(value));
|
|
@@ -2086,7 +2131,7 @@ const encodeFieldExpression = (compiler, context, parent, field, expr) => {
|
|
|
2086
2131
|
{
|
|
2087
2132
|
if (!(expr.value instanceof index$1.FieldSelectorExpression))
|
|
2088
2133
|
break;
|
|
2089
|
-
return sql `NOT (${encodeFieldExpression(compiler,
|
|
2134
|
+
return sql `NOT (${encodeFieldExpression(compiler, parent, field, expr.value)})`;
|
|
2090
2135
|
}
|
|
2091
2136
|
case '$pattern':
|
|
2092
2137
|
{
|
|
@@ -2178,7 +2223,7 @@ const encodeFieldExpression = (compiler, context, parent, field, expr) => {
|
|
|
2178
2223
|
if (!(expr.value instanceof index$1.QuerySelector))
|
|
2179
2224
|
break;
|
|
2180
2225
|
const tempName = `_expr_$${compiler.nextIdx()}`;
|
|
2181
|
-
const filter = compiler._encodeFilter(
|
|
2226
|
+
const filter = compiler._encodeFilter({ name: tempName, className: relation?.target }, expr.value);
|
|
2182
2227
|
if (!filter)
|
|
2183
2228
|
break;
|
|
2184
2229
|
if (relation) {
|
|
@@ -2205,7 +2250,7 @@ const encodeFieldExpression = (compiler, context, parent, field, expr) => {
|
|
|
2205
2250
|
if (!(expr.value instanceof index$1.QuerySelector))
|
|
2206
2251
|
break;
|
|
2207
2252
|
const tempName = `_expr_$${compiler.nextIdx()}`;
|
|
2208
|
-
const filter = compiler._encodeFilter(
|
|
2253
|
+
const filter = compiler._encodeFilter({ name: tempName, className: relation?.target }, expr.value);
|
|
2209
2254
|
if (!filter)
|
|
2210
2255
|
break;
|
|
2211
2256
|
if (relation) {
|
|
@@ -2299,31 +2344,36 @@ const selectPopulate = (compiler, parent, populate, field) => {
|
|
|
2299
2344
|
const _local = (field) => sql `${{ identifier: parent.name }}.${{ identifier: field }}`;
|
|
2300
2345
|
const _foreign = (field) => sql `${{ identifier: populate.name }}.${{ identifier: field }}`;
|
|
2301
2346
|
const subpaths = resolveSubpaths(compiler, populate);
|
|
2347
|
+
const cond = [];
|
|
2348
|
+
if (compiler.extraFilter) {
|
|
2349
|
+
const filter = compiler.extraFilter(populate.className);
|
|
2350
|
+
cond.push(compiler._encodeFilter(populate, filter));
|
|
2351
|
+
}
|
|
2302
2352
|
if (populate.type === 'pointer') {
|
|
2353
|
+
cond.push(sql `${sql `(${{ quote: populate.className + '$' }} || ${_foreign('_id')})`} = ${_local(field)}`);
|
|
2303
2354
|
return {
|
|
2304
2355
|
columns: _.map(subpaths, ({ path }) => sql `${{ identifier: populate.name }}.${{ identifier: path }} AS ${{ identifier: `${field}.${path}` }}`),
|
|
2305
2356
|
join: sql `
|
|
2306
2357
|
LEFT JOIN ${{ identifier: populate.name }}
|
|
2307
|
-
ON ${
|
|
2358
|
+
ON ${{ literal: _.map(_.compact(cond), x => sql `(${x})`), separator: ' AND ' }}
|
|
2308
2359
|
`,
|
|
2309
2360
|
};
|
|
2310
2361
|
}
|
|
2311
|
-
let cond;
|
|
2312
2362
|
if (_.isNil(populate.foreignField)) {
|
|
2313
|
-
cond
|
|
2363
|
+
cond.push(sql `${sql `(${{ quote: populate.className + '$' }} || ${_foreign('_id')})`} = ANY(${_local(field)})`);
|
|
2314
2364
|
}
|
|
2315
2365
|
else if (_isPointer(compiler.schema, populate.className, populate.foreignField)) {
|
|
2316
|
-
cond
|
|
2366
|
+
cond.push(sql `${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ${_foreign(populate.colname)}`);
|
|
2317
2367
|
}
|
|
2318
2368
|
else {
|
|
2319
|
-
cond
|
|
2369
|
+
cond.push(sql `${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ANY(${_foreign(populate.colname)})`);
|
|
2320
2370
|
}
|
|
2321
2371
|
return {
|
|
2322
2372
|
columns: [sql `
|
|
2323
2373
|
ARRAY(
|
|
2324
2374
|
SELECT to_jsonb(${{ identifier: populate.name }}) FROM (
|
|
2325
2375
|
SELECT ${_.map(subpaths, ({ path, type }) => _encodePopulateInclude(populate.name, path, type))}
|
|
2326
|
-
FROM ${{ identifier: populate.name }} WHERE ${cond}
|
|
2376
|
+
FROM ${{ identifier: populate.name }} WHERE ${{ literal: _.map(_.compact(cond), x => sql `(${x})`), separator: ' AND ' }}
|
|
2327
2377
|
${!_.isEmpty(populate.sort) ? sql `ORDER BY ${compiler._encodeSort(populate.sort, { className: populate.className, name: populate.name })}` : sql ``}
|
|
2328
2378
|
${populate.limit ? sql `LIMIT ${{ literal: `${populate.limit}` }}` : sql ``}
|
|
2329
2379
|
${populate.skip ? sql `OFFSET ${{ literal: `${populate.skip}` }}` : sql ``}
|
|
@@ -2336,13 +2386,13 @@ const selectPopulate = (compiler, parent, populate, field) => {
|
|
|
2336
2386
|
const encodeRemix = (parent, remix) => sql `${remix?.className === parent.className ? sql `
|
|
2337
2387
|
(SELECT * FROM ${{ identifier: remix.name }} UNION SELECT * FROM ${{ identifier: parent.className }})
|
|
2338
2388
|
` : { identifier: parent.className }}`;
|
|
2339
|
-
const encodeForeignField = (compiler,
|
|
2389
|
+
const encodeForeignField = (compiler, parent, foreignField, remix) => {
|
|
2340
2390
|
const { paths: [colname, ...subpath], dataType } = random$1.resolveColumn(compiler.schema, parent.className, foreignField);
|
|
2341
2391
|
const tempName = `_populate_$${compiler.nextIdx()}`;
|
|
2342
2392
|
const _local = (field) => sql `${{ identifier: parent.name }}.${{ identifier: field }}`;
|
|
2343
2393
|
const _foreign = (field) => sql `${{ identifier: tempName }}.${{ identifier: field }}`;
|
|
2344
2394
|
if (_.isEmpty(subpath) && index.isRelation(dataType) && dataType.foreignField) {
|
|
2345
|
-
const { joins, field, rows, array } = encodeForeignField(compiler,
|
|
2395
|
+
const { joins, field, rows, array } = encodeForeignField(compiler, { className: dataType.target, name: tempName }, dataType.foreignField, remix);
|
|
2346
2396
|
return {
|
|
2347
2397
|
joins: [],
|
|
2348
2398
|
field: sql `(
|
|
@@ -2365,27 +2415,32 @@ const encodeForeignField = (compiler, context, parent, foreignField, remix) => {
|
|
|
2365
2415
|
}
|
|
2366
2416
|
if (!index.isPointer(dataType) && !index.isRelation(dataType))
|
|
2367
2417
|
throw Error(`Invalid path: ${foreignField}`);
|
|
2368
|
-
const { joins, field, rows, array } = encodeForeignField(compiler,
|
|
2418
|
+
const { joins, field, rows, array } = encodeForeignField(compiler, { className: dataType.target, name: tempName }, subpath.join('.'), remix);
|
|
2419
|
+
const cond = [];
|
|
2420
|
+
if (compiler.extraFilter) {
|
|
2421
|
+
const filter = compiler.extraFilter(dataType.target);
|
|
2422
|
+
cond.push(compiler._encodeFilter({ className: dataType.target, name: tempName }, filter));
|
|
2423
|
+
}
|
|
2369
2424
|
if (index.isPointer(dataType)) {
|
|
2425
|
+
cond.push(sql `${sql `(${{ quote: dataType.target + '$' }} || ${_foreign('_id')})`} = ${_local(colname)}`);
|
|
2370
2426
|
return {
|
|
2371
2427
|
joins: [sql `
|
|
2372
2428
|
LEFT JOIN ${encodeRemix({ className: dataType.target }, remix)} AS ${{ identifier: tempName }}
|
|
2373
|
-
ON ${
|
|
2429
|
+
ON ${{ literal: _.map(_.compact(cond), x => sql `(${x})`), separator: ' AND ' }}
|
|
2374
2430
|
`, ...joins],
|
|
2375
2431
|
field,
|
|
2376
2432
|
array,
|
|
2377
2433
|
rows,
|
|
2378
2434
|
};
|
|
2379
2435
|
}
|
|
2380
|
-
let cond;
|
|
2381
2436
|
if (_.isNil(dataType.foreignField)) {
|
|
2382
|
-
cond
|
|
2437
|
+
cond.push(sql `${sql `(${{ quote: dataType.target + '$' }} || ${_foreign('_id')})`} = ANY(${_local(colname)})`);
|
|
2383
2438
|
}
|
|
2384
2439
|
else if (_isPointer(compiler.schema, dataType.target, dataType.foreignField)) {
|
|
2385
|
-
cond
|
|
2440
|
+
cond.push(sql `${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ${_foreign(dataType.foreignField)}`);
|
|
2386
2441
|
}
|
|
2387
2442
|
else {
|
|
2388
|
-
cond
|
|
2443
|
+
cond.push(sql `${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ANY(${_foreign(dataType.foreignField)})`);
|
|
2389
2444
|
}
|
|
2390
2445
|
return {
|
|
2391
2446
|
joins: [],
|
|
@@ -2393,23 +2448,23 @@ const encodeForeignField = (compiler, context, parent, foreignField, remix) => {
|
|
|
2393
2448
|
SELECT ${array ? sql `UNNEST(${field})` : field}
|
|
2394
2449
|
FROM ${encodeRemix({ className: dataType.target }, remix)} AS ${{ identifier: tempName }}
|
|
2395
2450
|
${!_.isEmpty(joins) ? { literal: joins, separator: '\n' } : sql ``}
|
|
2396
|
-
WHERE ${cond}
|
|
2451
|
+
WHERE ${{ literal: _.map(_.compact(cond), x => sql `(${x})`), separator: ' AND ' }}
|
|
2397
2452
|
)`,
|
|
2398
2453
|
array: false,
|
|
2399
2454
|
rows: true,
|
|
2400
2455
|
};
|
|
2401
2456
|
};
|
|
2402
|
-
const encodePopulate = (compiler,
|
|
2403
|
-
const _filter = compiler._encodeFilter(
|
|
2457
|
+
const encodePopulate = (compiler, parent, remix) => {
|
|
2458
|
+
const _filter = parent.filter && compiler._encodeFilter(parent, parent.filter);
|
|
2404
2459
|
const _populates = _.map(parent.populates, (populate, field) => selectPopulate(compiler, parent, populate, field));
|
|
2405
2460
|
const _joins = _.compact(_.map(_populates, ({ join }) => join));
|
|
2406
2461
|
const _includes = _.pickBy(parent.includes, v => index.isPrimitive(v));
|
|
2407
|
-
const { joins: _joins2 = [], field: _foreignField = undefined, rows = false, } = parent.foreignField ? encodeForeignField(compiler,
|
|
2462
|
+
const { joins: _joins2 = [], field: _foreignField = undefined, rows = false, } = parent.foreignField ? encodeForeignField(compiler, {
|
|
2408
2463
|
className: parent.className,
|
|
2409
2464
|
name: parent.name,
|
|
2410
2465
|
}, parent.foreignField, remix) : {};
|
|
2411
2466
|
return _.reduce(parent.populates, (acc, populate) => ({
|
|
2412
|
-
...encodePopulate(compiler,
|
|
2467
|
+
...encodePopulate(compiler, populate, remix),
|
|
2413
2468
|
...acc,
|
|
2414
2469
|
}), {
|
|
2415
2470
|
[parent.name]: sql `
|
|
@@ -2454,11 +2509,11 @@ const encodePopulate = (compiler, context, parent, remix) => {
|
|
|
2454
2509
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
2455
2510
|
// THE SOFTWARE.
|
|
2456
2511
|
//
|
|
2457
|
-
const encodeRelation = (compiler,
|
|
2512
|
+
const encodeRelation = (compiler, parent, relatedBy) => {
|
|
2458
2513
|
const name = `_relation_$${relatedBy.className.toLowerCase()}`;
|
|
2459
2514
|
const _local = (field) => sql `${{ identifier: parent.name }}.${{ identifier: field }}`;
|
|
2460
2515
|
const _foreign = (field) => sql `${{ identifier: name }}.${{ identifier: field }}`;
|
|
2461
|
-
const { joins, field } = encodeForeignField(compiler,
|
|
2516
|
+
const { joins, field } = encodeForeignField(compiler, { className: relatedBy.className, name }, relatedBy.key);
|
|
2462
2517
|
return sql `EXISTS (
|
|
2463
2518
|
SELECT 1
|
|
2464
2519
|
FROM ${{ identifier: relatedBy.className }} AS ${{ identifier: name }}
|