proto.io 0.0.157 → 0.0.159
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/filesystem.d.ts +2 -2
- package/dist/adapters/file/google-cloud-storage.d.ts +2 -2
- package/dist/adapters/storage/progres.d.ts +3 -5
- package/dist/adapters/storage/progres.js +178 -46
- package/dist/adapters/storage/progres.js.map +1 -1
- package/dist/adapters/storage/progres.mjs +178 -46
- package/dist/adapters/storage/progres.mjs.map +1 -1
- package/dist/client.d.ts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/internals/index-B01TqoO1.mjs.map +1 -1
- package/dist/internals/{index-dkBoWkei.d.ts → index-BraAbRER.d.ts} +2 -2
- package/dist/internals/index-BraAbRER.d.ts.map +1 -0
- package/dist/internals/index-Bs06MNCK.js.map +1 -1
- package/dist/internals/{index-Bb9jyfQC.d.ts → index-CXPH5Pup.d.ts} +4 -2
- package/dist/internals/index-CXPH5Pup.d.ts.map +1 -0
- package/dist/internals/{index-DbUghBO0.d.ts → index-sFLwlp-C.d.ts} +2 -2
- package/dist/internals/index-sFLwlp-C.d.ts.map +1 -0
- package/dist/internals/{random-CPI-IjeV.js → random-B5INLcHZ.js} +48 -31
- package/dist/internals/random-B5INLcHZ.js.map +1 -0
- package/dist/internals/{random-DLFngtjg.mjs → random-Dst9-WVo.mjs} +47 -31
- package/dist/internals/random-Dst9-WVo.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/internals/index-Bb9jyfQC.d.ts.map +0 -1
- package/dist/internals/index-DbUghBO0.d.ts.map +0 -1
- package/dist/internals/index-dkBoWkei.d.ts.map +0 -1
- package/dist/internals/random-CPI-IjeV.js.map +0 -1
- package/dist/internals/random-DLFngtjg.mjs.map +0 -1
|
@@ -7,7 +7,7 @@ import Decimal from 'decimal.js';
|
|
|
7
7
|
import { escapeLiteral, escapeIdentifier } from 'pg/lib/utils';
|
|
8
8
|
import { a as QueryCoditionalSelector, b as QueryFieldSelector, c as QueryExpressionSelector, d as QueryDistanceExpression, e as QueryCoditionalExpression, f as QueryComparisonExpression, g as QueryNotExpression, h as QueryArrayExpression, i as QueryValueExpression, j as QueryKeyExpression, Q as QuerySelector, F as FieldSelectorExpression } from '../../internals/index-tU-lsQqj.mjs';
|
|
9
9
|
import '@o2ter/crypto-js';
|
|
10
|
-
import {
|
|
10
|
+
import { a as resolveColumn, r as resolveDataType, g as generateId, Q as QueryValidator } from '../../internals/random-Dst9-WVo.mjs';
|
|
11
11
|
import { P as PVK } from '../../internals/private-BUpLAMZi.mjs';
|
|
12
12
|
|
|
13
13
|
//
|
|
@@ -240,7 +240,7 @@ class QueryCompiler {
|
|
|
240
240
|
const names = {};
|
|
241
241
|
const populates = {};
|
|
242
242
|
for (const include of includes) {
|
|
243
|
-
const { paths: [colname, ...subpath], dataType } =
|
|
243
|
+
const { paths: [colname, ...subpath], dataType } = resolveColumn(this.schema, className, include);
|
|
244
244
|
names[colname] = dataType;
|
|
245
245
|
if (isPointer(dataType) || isRelation(dataType)) {
|
|
246
246
|
if (_.isEmpty(subpath))
|
|
@@ -257,13 +257,12 @@ class QueryCompiler {
|
|
|
257
257
|
colname,
|
|
258
258
|
};
|
|
259
259
|
if (isRelation(dataType) && dataType.foreignField) {
|
|
260
|
-
const targetType = this.schema
|
|
260
|
+
const targetType = resolveDataType(this.schema, dataType.target, dataType.foreignField);
|
|
261
|
+
if (_.isNil(targetType))
|
|
262
|
+
throw Error(`Invalid path: ${include}`);
|
|
261
263
|
if (!isPointer(targetType) && !isRelation(targetType))
|
|
262
264
|
throw Error(`Invalid path: ${include}`);
|
|
263
|
-
populates[colname].foreignField =
|
|
264
|
-
colname: dataType.foreignField,
|
|
265
|
-
type: targetType.type,
|
|
266
|
-
};
|
|
265
|
+
populates[colname].foreignField = dataType.foreignField;
|
|
267
266
|
}
|
|
268
267
|
populates[colname].subpaths.push(subpath.join('.'));
|
|
269
268
|
}
|
|
@@ -358,7 +357,7 @@ class QueryCompiler {
|
|
|
358
357
|
_encodeUpdateAttrs(className, attrs) {
|
|
359
358
|
const updates = [];
|
|
360
359
|
for (const [path, op] of _.toPairs(attrs)) {
|
|
361
|
-
const { paths: [column, ...subpath], dataType } =
|
|
360
|
+
const { paths: [column, ...subpath], dataType } = resolveColumn(this.schema, className, path);
|
|
362
361
|
if (isShape(dataType)) {
|
|
363
362
|
const [_op, value] = decodeUpdateOp(op);
|
|
364
363
|
if (_op !== '$set')
|
|
@@ -378,7 +377,7 @@ class QueryCompiler {
|
|
|
378
377
|
_encodeObjectAttrs(className, attrs) {
|
|
379
378
|
const result = {};
|
|
380
379
|
for (const [key, value] of _.toPairs(attrs)) {
|
|
381
|
-
const { paths: [column, ...subpath], dataType } =
|
|
380
|
+
const { paths: [column, ...subpath], dataType } = resolveColumn(this.schema, className, key);
|
|
382
381
|
if (!_.isEmpty(subpath))
|
|
383
382
|
throw Error(`Invalid insert key: ${key}`);
|
|
384
383
|
if (isShape(dataType)) {
|
|
@@ -784,6 +783,34 @@ class SqlStorage {
|
|
|
784
783
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
785
784
|
// THE SOFTWARE.
|
|
786
785
|
//
|
|
786
|
+
const foreignFieldType = (schema, className, path) => {
|
|
787
|
+
let fields = schema[className].fields;
|
|
788
|
+
let last;
|
|
789
|
+
let result = false;
|
|
790
|
+
for (const key of _.toPath(path)) {
|
|
791
|
+
const dataType = fields[key];
|
|
792
|
+
if (_.isNil(dataType))
|
|
793
|
+
return;
|
|
794
|
+
if (isPrimitive(dataType) || isVector(dataType))
|
|
795
|
+
return;
|
|
796
|
+
if (isShape(dataType)) {
|
|
797
|
+
fields = dataType.shape;
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
if (_.isNil(schema[dataType.target]))
|
|
801
|
+
return;
|
|
802
|
+
if (dataType.type === 'relation')
|
|
803
|
+
result = true;
|
|
804
|
+
fields = schema[dataType.target].fields;
|
|
805
|
+
last = dataType;
|
|
806
|
+
}
|
|
807
|
+
if (!last)
|
|
808
|
+
return;
|
|
809
|
+
return {
|
|
810
|
+
target: last.target,
|
|
811
|
+
type: result ? 'relation' : last.type,
|
|
812
|
+
};
|
|
813
|
+
};
|
|
787
814
|
const _fetchElement = (parent, colname, subpath, dataType) => {
|
|
788
815
|
const element = sql `${{ identifier: parent.name }}.${{ identifier: parent.name.startsWith('_expr_$') ? '$' : colname }}`;
|
|
789
816
|
if (!parent.className) {
|
|
@@ -824,7 +851,7 @@ const _fetchElement = (parent, colname, subpath, dataType) => {
|
|
|
824
851
|
return { element, json: false };
|
|
825
852
|
};
|
|
826
853
|
const resolvePaths = (compiler, className, paths) => {
|
|
827
|
-
const { paths: [colname, ...subpath], dataType } =
|
|
854
|
+
const { paths: [colname, ...subpath], dataType } = resolveColumn(compiler.schema, className, paths.join('.'));
|
|
828
855
|
if (!_.isEmpty(subpath) && isVector(dataType)) {
|
|
829
856
|
if (subpath.length !== 1)
|
|
830
857
|
throw Error(`Invalid key: ${paths.join('.')}`);
|
|
@@ -850,14 +877,38 @@ const resolvePaths = (compiler, className, paths) => {
|
|
|
850
877
|
const fetchElement = (compiler, parent, field) => {
|
|
851
878
|
if (parent.className) {
|
|
852
879
|
const { dataType, colname, subpath } = resolvePaths(compiler, parent.className, _.toPath(field));
|
|
880
|
+
const { element, json } = _fetchElement(parent, colname, subpath, dataType);
|
|
881
|
+
if (!_.isEmpty(subpath)) {
|
|
882
|
+
const foreignField = foreignFieldType(compiler.schema, parent.className, field);
|
|
883
|
+
if (foreignField) {
|
|
884
|
+
return {
|
|
885
|
+
element,
|
|
886
|
+
dataType: foreignField,
|
|
887
|
+
relation: {
|
|
888
|
+
target: foreignField.target,
|
|
889
|
+
sql: (callback) => sql `SELECT
|
|
890
|
+
${callback(sql `UNNEST`)}
|
|
891
|
+
FROM UNNEST(${{ identifier: parent.name }}.${{ identifier: colname }})`,
|
|
892
|
+
},
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
}
|
|
853
896
|
if (isPointer(dataType))
|
|
854
897
|
return { element: sql `${{ identifier: parent.name }}.${{ identifier: `${colname}._id` }}`, dataType };
|
|
855
|
-
|
|
856
|
-
|
|
898
|
+
return {
|
|
899
|
+
element,
|
|
900
|
+
dataType: json ? null : dataType,
|
|
901
|
+
relation: isRelation(dataType) ? {
|
|
902
|
+
target: dataType.target,
|
|
903
|
+
sql: (callback) => sql `SELECT
|
|
904
|
+
${callback(sql `${json ? sql `VALUE` : sql `UNNEST`}`)}
|
|
905
|
+
FROM ${json ? sql `jsonb_array_elements(${element})` : sql `UNNEST(${element})`}`,
|
|
906
|
+
} : null,
|
|
907
|
+
};
|
|
857
908
|
}
|
|
858
909
|
const [colname, ...subpath] = _.toPath(field);
|
|
859
|
-
const { element
|
|
860
|
-
return { element,
|
|
910
|
+
const { element } = _fetchElement(parent, colname, subpath);
|
|
911
|
+
return { element, dataType: null, relation: null };
|
|
861
912
|
};
|
|
862
913
|
|
|
863
914
|
//
|
|
@@ -1803,7 +1854,7 @@ const encodeQueryExpression = (compiler, parent, expr) => {
|
|
|
1803
1854
|
//
|
|
1804
1855
|
const encodeFieldExpression = (compiler, context, parent, field, expr) => {
|
|
1805
1856
|
const [colname] = _.toPath(field);
|
|
1806
|
-
const { element,
|
|
1857
|
+
const { element, dataType, relation } = fetchElement(compiler, parent, field);
|
|
1807
1858
|
const encodeValue = (value) => dataType ? encodeType(colname, dataType, value) : _encodeJsonValue(_encodeValue(value));
|
|
1808
1859
|
switch (expr.type) {
|
|
1809
1860
|
case '$eq':
|
|
@@ -1963,10 +2014,10 @@ const encodeFieldExpression = (compiler, context, parent, field, expr) => {
|
|
|
1963
2014
|
if (dataType === 'array' || (!_.isString(dataType) && dataType?.type === 'array')) {
|
|
1964
2015
|
return sql `${element} <@ ${{ value: _encodeValue(expr.value) }}`;
|
|
1965
2016
|
}
|
|
1966
|
-
else if (
|
|
2017
|
+
else if (relation) {
|
|
1967
2018
|
if (!_.every(expr.value, x => x instanceof TObject && x.objectId))
|
|
1968
2019
|
break;
|
|
1969
|
-
return sql `ARRAY(
|
|
2020
|
+
return sql `ARRAY(${relation.sql((v) => sql `${v} ->> '_id'`)}) <@ ARRAY[${_.map(expr.value, (x) => sql `${{ value: x.objectId }}`)}]`;
|
|
1970
2021
|
}
|
|
1971
2022
|
else if (!dataType) {
|
|
1972
2023
|
return sql `jsonb_typeof(${element}) ${nullSafeEqual()} 'array' AND ${element} <@ ${_encodeJsonValue(_encodeValue(expr.value))}`;
|
|
@@ -1981,10 +2032,10 @@ const encodeFieldExpression = (compiler, context, parent, field, expr) => {
|
|
|
1981
2032
|
if (dataType === 'array' || (!_.isString(dataType) && dataType?.type === 'array')) {
|
|
1982
2033
|
return sql `${element} @> ${{ value: _encodeValue(expr.value) }}`;
|
|
1983
2034
|
}
|
|
1984
|
-
else if (
|
|
2035
|
+
else if (relation) {
|
|
1985
2036
|
if (!_.every(expr.value, x => x instanceof TObject && x.objectId))
|
|
1986
2037
|
break;
|
|
1987
|
-
return sql `ARRAY(
|
|
2038
|
+
return sql `ARRAY(${relation.sql((v) => sql `${v} ->> '_id'`)}) @> ARRAY[${_.map(expr.value, (x) => sql `${{ value: x.objectId }}`)}]`;
|
|
1988
2039
|
}
|
|
1989
2040
|
else if (!dataType) {
|
|
1990
2041
|
return sql `jsonb_typeof(${element}) ${nullSafeEqual()} 'array' AND ${element} @> ${_encodeJsonValue(_encodeValue(expr.value))}`;
|
|
@@ -1999,10 +2050,10 @@ const encodeFieldExpression = (compiler, context, parent, field, expr) => {
|
|
|
1999
2050
|
if (dataType === 'array' || (!_.isString(dataType) && dataType?.type === 'array')) {
|
|
2000
2051
|
return sql `NOT ${element} && ${{ value: _encodeValue(expr.value) }}`;
|
|
2001
2052
|
}
|
|
2002
|
-
else if (
|
|
2053
|
+
else if (relation) {
|
|
2003
2054
|
if (!_.every(expr.value, x => x instanceof TObject && x.objectId))
|
|
2004
2055
|
break;
|
|
2005
|
-
return sql `NOT ARRAY(
|
|
2056
|
+
return sql `NOT ARRAY(${relation.sql((v) => sql `${v} ->> '_id'`)}) && ARRAY[${_.map(expr.value, (x) => sql `${{ value: x.objectId }}`)}]`;
|
|
2006
2057
|
}
|
|
2007
2058
|
else if (!dataType) {
|
|
2008
2059
|
return sql `jsonb_typeof(${element}) ${nullSafeEqual()} 'array' AND NOT ${element} && ${_encodeJsonValue(_encodeValue(expr.value))}`;
|
|
@@ -2017,10 +2068,10 @@ const encodeFieldExpression = (compiler, context, parent, field, expr) => {
|
|
|
2017
2068
|
if (dataType === 'array' || (!_.isString(dataType) && dataType?.type === 'array')) {
|
|
2018
2069
|
return sql `${element} && ${{ value: _encodeValue(expr.value) }}`;
|
|
2019
2070
|
}
|
|
2020
|
-
else if (
|
|
2071
|
+
else if (relation) {
|
|
2021
2072
|
if (!_.every(expr.value, x => x instanceof TObject && x.objectId))
|
|
2022
2073
|
break;
|
|
2023
|
-
return sql `ARRAY(
|
|
2074
|
+
return sql `ARRAY(${relation.sql((v) => sql `${v} ->> '_id'`)}) && ARRAY[${_.map(expr.value, (x) => sql `${{ value: x.objectId }}`)}]`;
|
|
2024
2075
|
}
|
|
2025
2076
|
else if (!dataType) {
|
|
2026
2077
|
return sql `jsonb_typeof(${element}) ${nullSafeEqual()} 'array' AND ${element} && ${_encodeJsonValue(_encodeValue(expr.value))}`;
|
|
@@ -2127,11 +2178,7 @@ const encodeFieldExpression = (compiler, context, parent, field, expr) => {
|
|
|
2127
2178
|
break;
|
|
2128
2179
|
if (relation) {
|
|
2129
2180
|
return sql `NOT EXISTS(
|
|
2130
|
-
SELECT * FROM (
|
|
2131
|
-
SELECT
|
|
2132
|
-
${json ? sql `VALUE` : sql `UNNEST`} AS "$"
|
|
2133
|
-
FROM ${json ? sql `jsonb_array_elements(${element})` : sql `UNNEST(${element})`}
|
|
2134
|
-
) AS ${{ identifier: tempName }}
|
|
2181
|
+
SELECT * FROM (${relation.sql((v) => sql `${v} AS "$"`)}) AS ${{ identifier: tempName }}
|
|
2135
2182
|
WHERE NOT (${filter})
|
|
2136
2183
|
)`;
|
|
2137
2184
|
}
|
|
@@ -2158,11 +2205,7 @@ const encodeFieldExpression = (compiler, context, parent, field, expr) => {
|
|
|
2158
2205
|
break;
|
|
2159
2206
|
if (relation) {
|
|
2160
2207
|
return sql `EXISTS(
|
|
2161
|
-
SELECT * FROM (
|
|
2162
|
-
SELECT
|
|
2163
|
-
${json ? sql `VALUE` : sql `UNNEST`} AS "$"
|
|
2164
|
-
FROM ${json ? sql `jsonb_array_elements(${element})` : sql `UNNEST(${element})`}
|
|
2165
|
-
) AS ${{ identifier: tempName }}
|
|
2208
|
+
SELECT * FROM (${relation.sql((v) => sql `${v} AS "$"`)}) AS ${{ identifier: tempName }}
|
|
2166
2209
|
WHERE ${filter}
|
|
2167
2210
|
)`;
|
|
2168
2211
|
}
|
|
@@ -2225,6 +2268,28 @@ const resolveSubpaths = (compiler, populate) => {
|
|
|
2225
2268
|
}
|
|
2226
2269
|
return subpaths;
|
|
2227
2270
|
};
|
|
2271
|
+
const _isPointer = (schema, className, path) => {
|
|
2272
|
+
let fields = schema[className].fields;
|
|
2273
|
+
let last;
|
|
2274
|
+
for (const key of _.toPath(path)) {
|
|
2275
|
+
const dataType = fields[key];
|
|
2276
|
+
if (_.isNil(dataType))
|
|
2277
|
+
throw Error(`Invalid path: ${path}`);
|
|
2278
|
+
if (isPrimitive(dataType) || isVector(dataType))
|
|
2279
|
+
throw Error(`Invalid path: ${path}`);
|
|
2280
|
+
if (isShape(dataType)) {
|
|
2281
|
+
fields = dataType.shape;
|
|
2282
|
+
continue;
|
|
2283
|
+
}
|
|
2284
|
+
if (dataType.type !== 'pointer')
|
|
2285
|
+
return false;
|
|
2286
|
+
if (_.isNil(schema[dataType.target]))
|
|
2287
|
+
throw Error(`Invalid path: ${path}`);
|
|
2288
|
+
fields = schema[dataType.target].fields;
|
|
2289
|
+
last = dataType;
|
|
2290
|
+
}
|
|
2291
|
+
return last?.type === 'pointer';
|
|
2292
|
+
};
|
|
2228
2293
|
const selectPopulate = (compiler, parent, populate, field) => {
|
|
2229
2294
|
const _local = (field) => sql `${{ identifier: parent.name }}.${{ identifier: field }}`;
|
|
2230
2295
|
const _foreign = (field) => sql `${{ identifier: populate.name }}.${{ identifier: field }}`;
|
|
@@ -2242,11 +2307,11 @@ const selectPopulate = (compiler, parent, populate, field) => {
|
|
|
2242
2307
|
if (_.isNil(populate.foreignField)) {
|
|
2243
2308
|
cond = sql `${sql `(${{ quote: populate.className + '$' }} || ${_foreign('_id')})`} = ANY(${_local(field)})`;
|
|
2244
2309
|
}
|
|
2245
|
-
else if (populate.foreignField
|
|
2246
|
-
cond = sql `${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ${_foreign(populate.
|
|
2310
|
+
else if (_isPointer(compiler.schema, populate.className, populate.foreignField)) {
|
|
2311
|
+
cond = sql `${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ${_foreign(populate.colname)}`;
|
|
2247
2312
|
}
|
|
2248
2313
|
else {
|
|
2249
|
-
cond = sql `${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ANY(${_foreign(populate.
|
|
2314
|
+
cond = sql `${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ANY(${_foreign(populate.colname)})`;
|
|
2250
2315
|
}
|
|
2251
2316
|
return {
|
|
2252
2317
|
columns: [sql `
|
|
@@ -2263,11 +2328,80 @@ const selectPopulate = (compiler, parent, populate, field) => {
|
|
|
2263
2328
|
`],
|
|
2264
2329
|
};
|
|
2265
2330
|
};
|
|
2331
|
+
const encodeRemix = (parent, remix) => sql `${remix?.className === parent.className ? sql `
|
|
2332
|
+
(SELECT * FROM ${{ identifier: remix.name }} UNION SELECT * FROM ${{ identifier: parent.className }})
|
|
2333
|
+
` : { identifier: parent.className }}`;
|
|
2334
|
+
const encodeForeignField = (compiler, context, parent, foreignField, remix) => {
|
|
2335
|
+
const { paths: [colname, ...subpath], dataType } = resolveColumn(compiler.schema, parent.className, foreignField);
|
|
2336
|
+
const tempName = `_populate_$${compiler.nextIdx()}`;
|
|
2337
|
+
const _local = (field) => sql `${{ identifier: parent.name }}.${{ identifier: field }}`;
|
|
2338
|
+
const _foreign = (field) => sql `${{ identifier: tempName }}.${{ identifier: field }}`;
|
|
2339
|
+
if (_.isEmpty(subpath) && isRelation(dataType) && dataType.foreignField) {
|
|
2340
|
+
const { joins, field, rows, array } = encodeForeignField(compiler, context, { className: dataType.target, name: tempName }, dataType.foreignField, remix);
|
|
2341
|
+
return {
|
|
2342
|
+
joins: [],
|
|
2343
|
+
field: sql `(
|
|
2344
|
+
SELECT ${sql `(${{ quote: parent.className + '$' }} || ${_foreign('_id')})`}
|
|
2345
|
+
FROM ${encodeRemix(parent, remix)} AS ${{ identifier: tempName }}
|
|
2346
|
+
${!_.isEmpty(joins) ? { literal: joins, separator: '\n' } : sql ``}
|
|
2347
|
+
WHERE ${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ${array || rows ? sql `ANY(${field})` : field}
|
|
2348
|
+
)`,
|
|
2349
|
+
array: false,
|
|
2350
|
+
rows: true,
|
|
2351
|
+
};
|
|
2352
|
+
}
|
|
2353
|
+
if (_.isEmpty(subpath)) {
|
|
2354
|
+
return {
|
|
2355
|
+
joins: [],
|
|
2356
|
+
field: sql `${{ identifier: parent.name }}.${{ identifier: foreignField }}`,
|
|
2357
|
+
array: isRelation(dataType),
|
|
2358
|
+
rows: false,
|
|
2359
|
+
};
|
|
2360
|
+
}
|
|
2361
|
+
if (!isPointer(dataType) && !isRelation(dataType))
|
|
2362
|
+
throw Error(`Invalid path: ${foreignField}`);
|
|
2363
|
+
const { joins, field, rows, array } = encodeForeignField(compiler, context, { className: dataType.target, name: tempName }, subpath.join('.'), remix);
|
|
2364
|
+
if (isPointer(dataType)) {
|
|
2365
|
+
return {
|
|
2366
|
+
joins: [sql `
|
|
2367
|
+
LEFT JOIN ${encodeRemix(parent, remix)} AS ${{ identifier: tempName }}
|
|
2368
|
+
ON ${sql `(${{ quote: dataType.target + '$' }} || ${_foreign('_id')})`} = ${_local(colname)}
|
|
2369
|
+
`, ...joins],
|
|
2370
|
+
field,
|
|
2371
|
+
array,
|
|
2372
|
+
rows,
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
let cond;
|
|
2376
|
+
if (_.isNil(dataType.foreignField)) {
|
|
2377
|
+
cond = sql `${sql `(${{ quote: dataType.target + '$' }} || ${_foreign('_id')})`} = ANY(${_local(colname)})`;
|
|
2378
|
+
}
|
|
2379
|
+
else if (_isPointer(compiler.schema, dataType.target, dataType.foreignField)) {
|
|
2380
|
+
cond = sql `${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ${_foreign(dataType.foreignField)}`;
|
|
2381
|
+
}
|
|
2382
|
+
else {
|
|
2383
|
+
cond = sql `${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ANY(${_foreign(dataType.foreignField)})`;
|
|
2384
|
+
}
|
|
2385
|
+
return {
|
|
2386
|
+
joins: [],
|
|
2387
|
+
field: sql `(
|
|
2388
|
+
SELECT ${array ? sql `UNNEST(${field})` : field} FROM ${encodeRemix(parent, remix)} AS ${{ identifier: tempName }}
|
|
2389
|
+
${!_.isEmpty(joins) ? { literal: joins, separator: '\n' } : sql ``}
|
|
2390
|
+
WHERE ${cond}
|
|
2391
|
+
)`,
|
|
2392
|
+
array: false,
|
|
2393
|
+
rows: true,
|
|
2394
|
+
};
|
|
2395
|
+
};
|
|
2266
2396
|
const encodePopulate = (compiler, context, parent, remix) => {
|
|
2267
2397
|
const _filter = compiler._encodeFilter(context, parent, parent.filter);
|
|
2268
2398
|
const _populates = _.map(parent.populates, (populate, field) => selectPopulate(compiler, parent, populate, field));
|
|
2269
2399
|
const _joins = _.compact(_.map(_populates, ({ join }) => join));
|
|
2270
2400
|
const _includes = _.pickBy(parent.includes, v => isPrimitive(v));
|
|
2401
|
+
const { joins: _joins2 = [], field: _foreignField = undefined, rows = false, } = parent.foreignField ? encodeForeignField(compiler, context, {
|
|
2402
|
+
className: parent.className,
|
|
2403
|
+
name: parent.name,
|
|
2404
|
+
}, parent.foreignField, remix) : {};
|
|
2271
2405
|
return _.reduce(parent.populates, (acc, populate) => ({
|
|
2272
2406
|
...encodePopulate(compiler, context, populate, remix),
|
|
2273
2407
|
...acc,
|
|
@@ -2278,14 +2412,12 @@ const encodePopulate = (compiler, context, parent, remix) => {
|
|
|
2278
2412
|
${{
|
|
2279
2413
|
literal: [
|
|
2280
2414
|
..._.map(_.keys(_includes), colname => sql `${{ identifier: parent.name }}.${{ identifier: colname }}`),
|
|
2281
|
-
...parent.foreignField ? [sql `${{ identifier: parent.name }}.${{ identifier: parent.foreignField.colname }}`] : [],
|
|
2282
2415
|
..._.flatMap(_populates, ({ columns: column }) => column),
|
|
2416
|
+
..._foreignField ? [sql `${rows ? sql `ARRAY(${_foreignField})` : _foreignField} AS ${{ identifier: parent.colname }}`] : [],
|
|
2283
2417
|
], separator: ',\n'
|
|
2284
2418
|
}}
|
|
2285
|
-
FROM ${remix
|
|
2286
|
-
(
|
|
2287
|
-
` : { identifier: parent.className }} AS ${{ identifier: parent.name }}
|
|
2288
|
-
${!_.isEmpty(_joins) ? { literal: _joins, separator: '\n' } : sql ``}
|
|
2419
|
+
FROM ${encodeRemix(parent, remix)} AS ${{ identifier: parent.name }}
|
|
2420
|
+
${!_.isEmpty(_joins) || !_.isEmpty(_joins2) ? { literal: [..._joins, ..._joins2], separator: '\n' } : sql ``}
|
|
2289
2421
|
) AS ${{ identifier: parent.name }}
|
|
2290
2422
|
${_filter ? sql `WHERE ${_filter}` : sql ``}
|
|
2291
2423
|
`,
|
|
@@ -2320,13 +2452,13 @@ const encodeRelation = (compiler, context, parent, relatedBy) => {
|
|
|
2320
2452
|
const name = `_relation_$${relatedBy.className.toLowerCase()}`;
|
|
2321
2453
|
const _local = (field) => sql `${{ identifier: parent.name }}.${{ identifier: field }}`;
|
|
2322
2454
|
const _foreign = (field) => sql `${{ identifier: name }}.${{ identifier: field }}`;
|
|
2323
|
-
|
|
2324
|
-
|
|
2455
|
+
const { joins, field } = encodeForeignField(compiler, context, { className: relatedBy.className, name }, relatedBy.key);
|
|
2456
|
+
return sql `EXISTS (
|
|
2325
2457
|
SELECT 1
|
|
2326
2458
|
FROM ${{ identifier: relatedBy.className }} AS ${{ identifier: name }}
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
`;
|
|
2459
|
+
${!_.isEmpty(joins) ? { literal: joins, separator: '\n' } : sql ``}
|
|
2460
|
+
WHERE ${_foreign('_id')} = ${{ value: relatedBy.objectId }} AND ${sql `(${{ quote: parent.className + '$' }} || ${_local('_id')})`} = ANY(${field})
|
|
2461
|
+
)`;
|
|
2330
2462
|
};
|
|
2331
2463
|
|
|
2332
2464
|
//
|