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