nesoi 3.2.1 → 3.2.2
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/lib/elements/blocks/job/internal/resource_job.js +1 -1
- package/lib/elements/blocks/resource/resource.builder.js +1 -1
- package/lib/elements/blocks/resource/resource.js +1 -0
- package/lib/elements/entities/bucket/adapters/bucket_adapter.d.ts +2 -2
- package/lib/elements/entities/bucket/adapters/bucket_adapter.js +2 -2
- package/lib/elements/entities/bucket/adapters/memory.nql.d.ts +1 -1
- package/lib/elements/entities/bucket/adapters/memory.nql.js +9 -5
- package/lib/elements/entities/bucket/bucket.d.ts +13 -2
- package/lib/elements/entities/bucket/bucket.js +40 -2
- package/lib/elements/entities/bucket/graph/bucket_graph.d.ts +11 -0
- package/lib/elements/entities/bucket/graph/bucket_graph.js +49 -2
- package/lib/elements/entities/bucket/model/bucket_model.schema.js +14 -11
- package/lib/elements/entities/bucket/query/nql_engine.d.ts +2 -2
- package/lib/elements/entities/bucket/query/nql_engine.js +8 -4
- package/lib/elements/entities/bucket/view/bucket_view.js +65 -12
- package/lib/engine/transaction/nodes/bucket.trx_node.d.ts +5 -0
- package/lib/engine/transaction/nodes/bucket.trx_node.js +10 -0
- package/lib/engine/transaction/nodes/bucket_query.trx_node.d.ts +2 -0
- package/lib/engine/transaction/nodes/bucket_query.trx_node.js +15 -4
- package/lib/engine/util/log.d.ts +1 -1
- package/lib/engine/util/log.js +1 -0
- package/package.json +1 -1
- package/tools/joaquin/bucket.d.ts +23 -3
- package/tools/joaquin/bucket.js +48 -20
- package/tools/joaquin/job.js +4 -4
- package/tsconfig.build.tsbuildinfo +1 -1
- /package/lib/engine/apps/distributed/inc/{test.d.ts → sandbox.d.ts} +0 -0
- /package/lib/engine/apps/distributed/inc/{test.js → sandbox.js} +0 -0
|
@@ -30,7 +30,7 @@ class ResourceJob {
|
|
|
30
30
|
obj = await scope.execMethod({ ...$, obj, bucket: scope.bucket });
|
|
31
31
|
}
|
|
32
32
|
if (scope.afterMethod) {
|
|
33
|
-
|
|
33
|
+
await scope.afterMethod({ ...$, obj, bucket: scope.bucket });
|
|
34
34
|
}
|
|
35
35
|
return obj;
|
|
36
36
|
}
|
|
@@ -63,7 +63,7 @@ class ResourceBuilder extends block_builder_1.BlockBuilder {
|
|
|
63
63
|
const jobBuilder = new resource_job_builder_1.ResourceJobBuilder(this.module, name, this._bucket.refName, 'query', alias, resource_1.Resource.query, this._authn)
|
|
64
64
|
.input($ => ({
|
|
65
65
|
view: $.enum(views).default(views[0]),
|
|
66
|
-
query: $.dict($.any).default({}),
|
|
66
|
+
query: $.dict($.any.optional).default({}),
|
|
67
67
|
page: $.int.default(0),
|
|
68
68
|
perPage: $.int.default(10)
|
|
69
69
|
}))
|
|
@@ -136,10 +136,10 @@ export declare abstract class BucketAdapter<Obj extends NesoiObj> {
|
|
|
136
136
|
/**
|
|
137
137
|
* Return the results of a query
|
|
138
138
|
*/
|
|
139
|
-
query<MetadataOnly extends boolean>(trx: AnyTrxNode, query: NQL_AnyQuery, pagination?: NQL_Pagination, params?: Record<string, any
|
|
139
|
+
query<MetadataOnly extends boolean>(trx: AnyTrxNode, query: NQL_AnyQuery, pagination?: NQL_Pagination, params?: Record<string, any>[], config?: {
|
|
140
140
|
view?: string;
|
|
141
141
|
metadataOnly?: MetadataOnly;
|
|
142
|
-
}): Promise<NQL_Result<MetadataOnly extends true ? {
|
|
142
|
+
}, runner?: NQLRunner): Promise<NQL_Result<MetadataOnly extends true ? {
|
|
143
143
|
id: Obj['id'];
|
|
144
144
|
[x: string]: any;
|
|
145
145
|
} : Obj>>;
|
|
@@ -25,14 +25,14 @@ class BucketAdapter {
|
|
|
25
25
|
/**
|
|
26
26
|
* Return the results of a query
|
|
27
27
|
*/
|
|
28
|
-
async query(trx, query, pagination, params, config) {
|
|
28
|
+
async query(trx, query, pagination, params, config, runner) {
|
|
29
29
|
const module = trx_node_1.TrxNode.getModule(trx);
|
|
30
30
|
const refName = (module.name === this.schema.module
|
|
31
31
|
? '' : `${this.schema.module}::`)
|
|
32
32
|
+ this.schema.name;
|
|
33
33
|
const compiled = await nql_compiler_1.NQL_Compiler.build(module, refName, query);
|
|
34
34
|
const view = config?.view ? this.schema.views[config.view] : undefined;
|
|
35
|
-
const result = await module.nql.run(trx, compiled, pagination, params, view);
|
|
35
|
+
const result = await module.nql.run(trx, compiled, pagination, params, view, runner);
|
|
36
36
|
if (config?.metadataOnly) {
|
|
37
37
|
result.data = result.data.map(obj => ({
|
|
38
38
|
id: obj.id,
|
|
@@ -10,7 +10,7 @@ export declare class MemoryNQLRunner extends NQLRunner {
|
|
|
10
10
|
protected adapter?: AnyMemoryBucketAdapter;
|
|
11
11
|
constructor();
|
|
12
12
|
bind(adapter: AnyMemoryBucketAdapter): void;
|
|
13
|
-
run(trx: AnyTrxNode, part: NQL_Part, params: Obj, pagination?: NQL_Pagination): Promise<{
|
|
13
|
+
run(trx: AnyTrxNode, part: NQL_Part, params: Obj[], pagination?: NQL_Pagination): Promise<{
|
|
14
14
|
data: any[];
|
|
15
15
|
totalItems: number | undefined;
|
|
16
16
|
page: number | undefined;
|
|
@@ -21,7 +21,7 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
|
|
|
21
21
|
let response;
|
|
22
22
|
// Empty query, don't filter data
|
|
23
23
|
if (part.union.inters.length === 0) {
|
|
24
|
-
response = data;
|
|
24
|
+
response = { ...data };
|
|
25
25
|
}
|
|
26
26
|
// Non-empty query
|
|
27
27
|
else {
|
|
@@ -105,7 +105,7 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
|
|
|
105
105
|
for (const rule of inter.rules) {
|
|
106
106
|
// <Union>
|
|
107
107
|
if ('inters' in rule) {
|
|
108
|
-
if (!_union(rule, objs,
|
|
108
|
+
if (!_union(rule, objs, params))
|
|
109
109
|
return false;
|
|
110
110
|
}
|
|
111
111
|
// <Rule>
|
|
@@ -132,8 +132,12 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
|
|
|
132
132
|
continue;
|
|
133
133
|
}
|
|
134
134
|
const obj = objs[id];
|
|
135
|
-
let match =
|
|
136
|
-
|
|
135
|
+
let match = false;
|
|
136
|
+
for (const paramGroup of params) {
|
|
137
|
+
match = _obj(rule, obj, paramGroup);
|
|
138
|
+
if (match)
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
137
141
|
if (rule.not) {
|
|
138
142
|
match = !match;
|
|
139
143
|
}
|
|
@@ -174,7 +178,7 @@ class MemoryNQLRunner extends nql_engine_1.NQLRunner {
|
|
|
174
178
|
let queryValue;
|
|
175
179
|
// Value is a subquery, run union
|
|
176
180
|
if ('subquery' in rule.value) {
|
|
177
|
-
const subOut = _union(rule.value.subquery.union, objs, params);
|
|
181
|
+
const subOut = _union(rule.value.subquery.union, objs, [params]);
|
|
178
182
|
const subList = Object.values(subOut);
|
|
179
183
|
// Subquery operator is for a list, filter
|
|
180
184
|
if (rule.op === 'in' || rule.op === 'contains_any') {
|
|
@@ -85,7 +85,7 @@ export declare class Bucket<M extends $Module, $ extends $Bucket> {
|
|
|
85
85
|
no_tenancy: boolean;
|
|
86
86
|
}): Promise<Obj[]>;
|
|
87
87
|
/**
|
|
88
|
-
* Read raw entity of a graph link
|
|
88
|
+
* Read raw entity of a graph link for 1 object
|
|
89
89
|
*
|
|
90
90
|
* - Options:
|
|
91
91
|
* - `silent`: If not found, return `undefined` instead of throwing an exception
|
|
@@ -95,6 +95,17 @@ export declare class Bucket<M extends $Module, $ extends $Bucket> {
|
|
|
95
95
|
silent?: boolean;
|
|
96
96
|
no_tenancy?: boolean;
|
|
97
97
|
}): Promise<Link['#many'] extends true ? Obj[] : (Obj | undefined)>;
|
|
98
|
+
/**
|
|
99
|
+
* Read raw entities of a graph link for N objects
|
|
100
|
+
*
|
|
101
|
+
* - Options:
|
|
102
|
+
* - `silent`: If not found, return `undefined` instead of throwing an exception
|
|
103
|
+
* - `no_tenancy`: Don't apply tenancy rules.
|
|
104
|
+
*/
|
|
105
|
+
readManyLinks<LinkName extends keyof $['graph']['links'], Link extends $['graph']['links'][LinkName], LinkBucket extends Link['#bucket'], V extends ViewName<LinkBucket>, Obj extends ViewObj<LinkBucket, V>>(trx: AnyTrxNode, ids: $['#data']['id'][], link: LinkName, options?: {
|
|
106
|
+
silent?: boolean;
|
|
107
|
+
no_tenancy?: boolean;
|
|
108
|
+
}): Promise<Link['#many'] extends true ? Obj[] : (Obj | undefined)>;
|
|
98
109
|
/**
|
|
99
110
|
* Read the view of an entity of a graph link
|
|
100
111
|
*
|
|
@@ -190,7 +201,7 @@ export declare class Bucket<M extends $Module, $ extends $Bucket> {
|
|
|
190
201
|
*/
|
|
191
202
|
query<V extends ViewName<$>, Obj extends ViewObj<$, V>>(trx: AnyTrxNode, query: NQL_AnyQuery, pagination?: NQL_Pagination, view?: V, options?: {
|
|
192
203
|
no_tenancy?: boolean;
|
|
193
|
-
params?: Record<string, any
|
|
204
|
+
params?: Record<string, any>[];
|
|
194
205
|
}): Promise<NQL_Result<Obj>>;
|
|
195
206
|
/**
|
|
196
207
|
* Add `created_by`, `created_at`, `updated_by` and `updated_at` fields to object
|
|
@@ -120,7 +120,7 @@ class Bucket {
|
|
|
120
120
|
let raws;
|
|
121
121
|
// With Tenancy
|
|
122
122
|
if (tenancy) {
|
|
123
|
-
const result = await this.adapter.query(trx, tenancy, undefined, options?.query_view ? { view: options?.query_view } : undefined);
|
|
123
|
+
const result = await this.adapter.query(trx, tenancy, undefined, options?.query_view ? [{ view: options?.query_view }] : undefined);
|
|
124
124
|
raws = result.data;
|
|
125
125
|
}
|
|
126
126
|
// Without Tenancy
|
|
@@ -169,7 +169,7 @@ class Bucket {
|
|
|
169
169
|
}
|
|
170
170
|
// Graph
|
|
171
171
|
/**
|
|
172
|
-
* Read raw entity of a graph link
|
|
172
|
+
* Read raw entity of a graph link for 1 object
|
|
173
173
|
*
|
|
174
174
|
* - Options:
|
|
175
175
|
* - `silent`: If not found, return `undefined` instead of throwing an exception
|
|
@@ -201,6 +201,44 @@ class Bucket {
|
|
|
201
201
|
}
|
|
202
202
|
return linkObj;
|
|
203
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Read raw entities of a graph link for N objects
|
|
206
|
+
*
|
|
207
|
+
* - Options:
|
|
208
|
+
* - `silent`: If not found, return `undefined` instead of throwing an exception
|
|
209
|
+
* - `no_tenancy`: Don't apply tenancy rules.
|
|
210
|
+
*/
|
|
211
|
+
async readManyLinks(trx, ids, link, options) {
|
|
212
|
+
log_1.Log.debug('bucket', this.schema.name, `Read Link, ids=${ids} l=${link}`);
|
|
213
|
+
// Validate IDs
|
|
214
|
+
for (const id of ids) {
|
|
215
|
+
if (typeof id !== 'string' && typeof id !== 'number') {
|
|
216
|
+
throw error_1.NesoiError.Bucket.InvalidId({ bucket: this.schema.alias, id });
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Read object
|
|
220
|
+
const objs = await this.query(trx, {
|
|
221
|
+
'id in': ids
|
|
222
|
+
}).then(res => res.data);
|
|
223
|
+
// Empty response
|
|
224
|
+
if (!objs.length) {
|
|
225
|
+
const schema = this.schema.graph.links[link];
|
|
226
|
+
if (schema.many) {
|
|
227
|
+
return [];
|
|
228
|
+
}
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
231
|
+
// Read link
|
|
232
|
+
const linkObj = await this.graph.readManyLinks(trx, objs, link, options);
|
|
233
|
+
// TODO
|
|
234
|
+
// // Encryption
|
|
235
|
+
// if (linkObj) {
|
|
236
|
+
// if (this.schema.model.hasEncryptedField) {
|
|
237
|
+
// await this.decrypt(trx, linkObj);
|
|
238
|
+
// }
|
|
239
|
+
// }
|
|
240
|
+
return linkObj;
|
|
241
|
+
}
|
|
204
242
|
/**
|
|
205
243
|
* Read the view of an entity of a graph link
|
|
206
244
|
*
|
|
@@ -22,6 +22,17 @@ export declare class BucketGraph<M extends $Module, $ extends $Bucket> {
|
|
|
22
22
|
silent?: boolean;
|
|
23
23
|
no_tenancy?: boolean;
|
|
24
24
|
}): Promise<Obj | Obj[] | undefined>;
|
|
25
|
+
/**
|
|
26
|
+
* Read the data from a link
|
|
27
|
+
*
|
|
28
|
+
* - Options
|
|
29
|
+
* - `silent`: If not found, returns undefined instead of raising an exception (default: `false`)
|
|
30
|
+
* - `no_tenancy`: Don't apply tenancy rules (default: `false`)
|
|
31
|
+
*/
|
|
32
|
+
readManyLinks<LinkName extends keyof $['graph']['links'], LinkBucketName extends $['graph']['links'][LinkName]['bucket']['refName'], LinkBucket extends M['buckets'][LinkBucketName], Obj = LinkBucket['#data']>(trx: AnyTrxNode, objs: $['#data'][], link: LinkName, options?: {
|
|
33
|
+
silent?: boolean;
|
|
34
|
+
no_tenancy?: boolean;
|
|
35
|
+
}): Promise<Obj[] | Obj[][]>;
|
|
25
36
|
/**
|
|
26
37
|
* Read the data from a link and build it with a given view
|
|
27
38
|
*
|
|
@@ -4,6 +4,7 @@ exports.BucketGraph = void 0;
|
|
|
4
4
|
const trx_node_1 = require("../../../../engine/transaction/trx_node");
|
|
5
5
|
const log_1 = require("../../../../engine/util/log");
|
|
6
6
|
const error_1 = require("../../../../engine/data/error");
|
|
7
|
+
const memory_bucket_adapter_1 = require("../adapters/memory.bucket_adapter");
|
|
7
8
|
/**
|
|
8
9
|
* @category Elements
|
|
9
10
|
* @subcategory Entity
|
|
@@ -35,7 +36,7 @@ class BucketGraph {
|
|
|
35
36
|
'#and': tenancy
|
|
36
37
|
}, {
|
|
37
38
|
perPage: schema.many ? undefined : 1,
|
|
38
|
-
}, { ...obj });
|
|
39
|
+
}, [{ ...obj }]);
|
|
39
40
|
// Empty response
|
|
40
41
|
if (!schema.many && !schema.optional && !links.data.length) {
|
|
41
42
|
// silent = undefined
|
|
@@ -57,6 +58,52 @@ class BucketGraph {
|
|
|
57
58
|
return links.data[0];
|
|
58
59
|
}
|
|
59
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Read the data from a link
|
|
63
|
+
*
|
|
64
|
+
* - Options
|
|
65
|
+
* - `silent`: If not found, returns undefined instead of raising an exception (default: `false`)
|
|
66
|
+
* - `no_tenancy`: Don't apply tenancy rules (default: `false`)
|
|
67
|
+
*/
|
|
68
|
+
async readManyLinks(trx, objs, link, options) {
|
|
69
|
+
log_1.Log.trace('bucket', this.bucketName, `Read link ${link}`);
|
|
70
|
+
const schema = this.schema.links[link];
|
|
71
|
+
// Make tenancy query
|
|
72
|
+
const tenancy = (options?.no_tenancy)
|
|
73
|
+
? undefined
|
|
74
|
+
: this.bucket.getTenancyQuery(trx);
|
|
75
|
+
// Query
|
|
76
|
+
const otherBucket = trx_node_1.TrxNode.getModule(trx).buckets[schema.bucket.refName];
|
|
77
|
+
// let tempData: Record<string, any> = {};
|
|
78
|
+
let tempAdapter;
|
|
79
|
+
if (otherBucket.adapter instanceof memory_bucket_adapter_1.MemoryBucketAdapter) {
|
|
80
|
+
tempAdapter = otherBucket.adapter;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const allLinks = await otherBucket.adapter.query(trx, {
|
|
84
|
+
...schema.query,
|
|
85
|
+
'#and': tenancy
|
|
86
|
+
}, undefined, objs.map(obj => ({ ...obj })));
|
|
87
|
+
const tempData = {};
|
|
88
|
+
for (const obj of allLinks.data)
|
|
89
|
+
tempData[obj.id] = obj;
|
|
90
|
+
tempAdapter = new memory_bucket_adapter_1.MemoryBucketAdapter(otherBucket.schema, tempData);
|
|
91
|
+
}
|
|
92
|
+
const links = [];
|
|
93
|
+
for (const obj of objs) {
|
|
94
|
+
const result = await tempAdapter.query(trx, schema.query, {
|
|
95
|
+
perPage: schema.many ? undefined : 1,
|
|
96
|
+
}, [{ ...obj }], undefined, tempAdapter.nql);
|
|
97
|
+
if (schema.many) {
|
|
98
|
+
links.push(result.data);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
links.push(result.data[0]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Empty response
|
|
105
|
+
return links;
|
|
106
|
+
}
|
|
60
107
|
/**
|
|
61
108
|
* Read the data from a link and build it with a given view
|
|
62
109
|
*
|
|
@@ -102,7 +149,7 @@ class BucketGraph {
|
|
|
102
149
|
'#and': tenancy
|
|
103
150
|
}, {
|
|
104
151
|
perPage: 1,
|
|
105
|
-
}, { ...obj });
|
|
152
|
+
}, [{ ...obj }]);
|
|
106
153
|
return !!links.data.length;
|
|
107
154
|
}
|
|
108
155
|
}
|
|
@@ -55,7 +55,6 @@ class $BucketModel {
|
|
|
55
55
|
}
|
|
56
56
|
// If it's a list or dict, or an object
|
|
57
57
|
if (field.type === 'list' || field.type === 'dict') {
|
|
58
|
-
// If not, iterate
|
|
59
58
|
next.push({
|
|
60
59
|
i: item.i + 1,
|
|
61
60
|
field: field.children['#']
|
|
@@ -70,6 +69,10 @@ class $BucketModel {
|
|
|
70
69
|
})));
|
|
71
70
|
continue;
|
|
72
71
|
}
|
|
72
|
+
if (field.type === 'unknown') {
|
|
73
|
+
results.push(field);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
73
76
|
const child = field.children[path];
|
|
74
77
|
if (child) {
|
|
75
78
|
next.push({
|
|
@@ -127,53 +130,53 @@ class $BucketModel {
|
|
|
127
130
|
while (poll.length) {
|
|
128
131
|
const next = [];
|
|
129
132
|
for (const entry of poll) {
|
|
130
|
-
const val = obj[entry.path];
|
|
133
|
+
const val = entry.obj[entry.path];
|
|
131
134
|
if (val === undefined) {
|
|
132
135
|
continue;
|
|
133
136
|
}
|
|
134
137
|
if (val === null) {
|
|
135
|
-
copy[entry.path] = null;
|
|
138
|
+
entry.copy[entry.path] = null;
|
|
136
139
|
continue;
|
|
137
140
|
}
|
|
138
141
|
if (entry.field.type === 'list') {
|
|
139
142
|
if (!Array.isArray(val))
|
|
140
143
|
continue;
|
|
141
|
-
copy[entry.path] = [];
|
|
144
|
+
entry.copy[entry.path] = [];
|
|
142
145
|
next.push(...val.map((_, i) => ({
|
|
143
146
|
path: i.toString(),
|
|
144
147
|
obj: val,
|
|
145
|
-
copy: copy[entry.path],
|
|
148
|
+
copy: entry.copy[entry.path],
|
|
146
149
|
field: entry.field.children['*']
|
|
147
150
|
})));
|
|
148
151
|
}
|
|
149
152
|
else if (entry.field.type === 'dict') {
|
|
150
153
|
if (typeof val !== 'object' || Array.isArray(val))
|
|
151
154
|
continue;
|
|
152
|
-
copy[entry.path] = {};
|
|
155
|
+
entry.copy[entry.path] = {};
|
|
153
156
|
next.push(...Object.keys(val).map((path) => ({
|
|
154
157
|
path,
|
|
155
158
|
obj: val,
|
|
156
|
-
copy: copy[entry.path],
|
|
159
|
+
copy: entry.copy[entry.path],
|
|
157
160
|
field: entry.field.children['*']
|
|
158
161
|
})));
|
|
159
162
|
}
|
|
160
163
|
else if (entry.field.type === 'obj') {
|
|
161
164
|
if (typeof val !== 'object' || Array.isArray(val))
|
|
162
165
|
continue;
|
|
163
|
-
copy[entry.path] = {};
|
|
166
|
+
entry.copy[entry.path] = {};
|
|
164
167
|
next.push(...Object.keys(entry.field.children).map(path => ({
|
|
165
168
|
path: path,
|
|
166
169
|
obj: val,
|
|
167
|
-
copy: copy[entry.path],
|
|
170
|
+
copy: entry.copy[entry.path],
|
|
168
171
|
field: entry.field.children[path]
|
|
169
172
|
})));
|
|
170
173
|
}
|
|
171
174
|
else if (entry.field.type === 'union') {
|
|
172
175
|
// TODO: ??????????
|
|
173
|
-
copy[entry.path] = obj[entry.path];
|
|
176
|
+
entry.copy[entry.path] = entry.obj[entry.path];
|
|
174
177
|
}
|
|
175
178
|
else {
|
|
176
|
-
copy[entry.path] = obj[entry.path];
|
|
179
|
+
entry.copy[entry.path] = entry.obj[entry.path];
|
|
177
180
|
}
|
|
178
181
|
}
|
|
179
182
|
poll = next;
|
|
@@ -15,7 +15,7 @@ export type NQL_Result<T = Obj> = {
|
|
|
15
15
|
* @category NQL
|
|
16
16
|
* */
|
|
17
17
|
export declare abstract class NQLRunner {
|
|
18
|
-
abstract run(trx: AnyTrxNode, part: NQL_Part, params: Record<string, any
|
|
18
|
+
abstract run(trx: AnyTrxNode, part: NQL_Part, params: Record<string, any>[], pagination?: NQL_Pagination, view?: $BucketView): Promise<NQL_Result>;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* @category NQL
|
|
@@ -24,7 +24,7 @@ export declare class NQL_Engine {
|
|
|
24
24
|
private module;
|
|
25
25
|
private runners;
|
|
26
26
|
constructor(module: AnyModule);
|
|
27
|
-
run(trx: AnyTrxNode, query: NQL_CompiledQuery, pagination?: NQL_Pagination, params?: Record<string, any
|
|
27
|
+
run(trx: AnyTrxNode, query: NQL_CompiledQuery, pagination?: NQL_Pagination, params?: Record<string, any>[], view?: $BucketView, runner?: NQLRunner): Promise<NQL_Result>;
|
|
28
28
|
linkExternal(bucket: AnyBucket): void;
|
|
29
29
|
}
|
|
30
30
|
export {};
|
|
@@ -22,7 +22,9 @@ class NQL_Engine {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
async run(trx, query, pagination, params = {}, view) {
|
|
25
|
+
async run(trx, query, pagination, params = [{}], view, runner) {
|
|
26
|
+
if (!params.length)
|
|
27
|
+
params = [{}];
|
|
26
28
|
let result = {
|
|
27
29
|
data: []
|
|
28
30
|
};
|
|
@@ -30,8 +32,8 @@ class NQL_Engine {
|
|
|
30
32
|
const part_i = query.execOrder[i];
|
|
31
33
|
const part = query.parts[part_i];
|
|
32
34
|
// Run part
|
|
33
|
-
const
|
|
34
|
-
const out = await
|
|
35
|
+
const _runner = runner || this.runners[part.union.meta.scope];
|
|
36
|
+
const out = await _runner.run(trx, part, params, pagination, view);
|
|
35
37
|
result = out;
|
|
36
38
|
// Part failed, return
|
|
37
39
|
// Failure here is only when a single value is expected,
|
|
@@ -43,7 +45,9 @@ class NQL_Engine {
|
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
// Fill part params
|
|
46
|
-
|
|
48
|
+
for (const paramGroup of params) {
|
|
49
|
+
paramGroup[`%__${part_i}__%`] = part.many ? result.data : result.data[0];
|
|
50
|
+
}
|
|
47
51
|
}
|
|
48
52
|
return result;
|
|
49
53
|
}
|
|
@@ -4,9 +4,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.BucketView = void 0;
|
|
7
|
+
const trx_node_1 = require("../../../../engine/transaction/trx_node");
|
|
7
8
|
const promise_1 = __importDefault(require("../../../../engine/util/promise"));
|
|
8
9
|
const error_1 = require("../../../../engine/data/error");
|
|
9
10
|
const tree_1 = require("../../../../engine/data/tree");
|
|
11
|
+
const dependency_1 = require("../../../../engine/dependency");
|
|
10
12
|
class ViewValue {
|
|
11
13
|
constructor() {
|
|
12
14
|
this.value = undefined;
|
|
@@ -27,6 +29,7 @@ class BucketView {
|
|
|
27
29
|
Object.assign(parsed, raw);
|
|
28
30
|
}
|
|
29
31
|
let layer = Object.values(this.schema.fields).map(field => ({
|
|
32
|
+
bucket: this.bucket,
|
|
30
33
|
field,
|
|
31
34
|
data: [{
|
|
32
35
|
raw,
|
|
@@ -54,6 +57,7 @@ class BucketView {
|
|
|
54
57
|
parseds.push(parsed);
|
|
55
58
|
}
|
|
56
59
|
let layer = Object.values(this.schema.fields).map(field => ({
|
|
60
|
+
bucket: this.bucket,
|
|
57
61
|
field,
|
|
58
62
|
data: raws.map((raw, i) => ({
|
|
59
63
|
raw,
|
|
@@ -89,7 +93,7 @@ class BucketView {
|
|
|
89
93
|
for (const node of layer) {
|
|
90
94
|
if (node.field.scope !== 'graph')
|
|
91
95
|
continue;
|
|
92
|
-
await this.parseGraphProp(trx, node);
|
|
96
|
+
next.push(...await this.parseGraphProp(trx, node));
|
|
93
97
|
}
|
|
94
98
|
// Drive props
|
|
95
99
|
for (const node of layer) {
|
|
@@ -109,6 +113,7 @@ class BucketView {
|
|
|
109
113
|
}
|
|
110
114
|
}
|
|
111
115
|
next.push(...Object.values(node.field.children).map(field => ({
|
|
116
|
+
bucket: node.bucket,
|
|
112
117
|
field,
|
|
113
118
|
data: node.data
|
|
114
119
|
})));
|
|
@@ -118,6 +123,7 @@ class BucketView {
|
|
|
118
123
|
if (!node.field.chain)
|
|
119
124
|
continue;
|
|
120
125
|
next.push({
|
|
126
|
+
bucket: node.bucket,
|
|
121
127
|
field: node.field.chain,
|
|
122
128
|
data: node.data.map(d => ({
|
|
123
129
|
index: d.index,
|
|
@@ -144,6 +150,7 @@ class BucketView {
|
|
|
144
150
|
if (key === '__raw')
|
|
145
151
|
continue;
|
|
146
152
|
next.push({
|
|
153
|
+
bucket: node.bucket,
|
|
147
154
|
field: node.field.children[key],
|
|
148
155
|
data: nextData
|
|
149
156
|
});
|
|
@@ -249,7 +256,7 @@ class BucketView {
|
|
|
249
256
|
async parseComputedProp(trx, node) {
|
|
250
257
|
const meta = node.field.meta.computed;
|
|
251
258
|
for (const entry of node.data) {
|
|
252
|
-
entry.target[node.field.name] = await promise_1.default.solve(meta.fn({ trx, raw: entry.raw, bucket:
|
|
259
|
+
entry.target[node.field.name] = await promise_1.default.solve(meta.fn({ trx, raw: entry.raw, bucket: node.bucket.schema }));
|
|
253
260
|
}
|
|
254
261
|
}
|
|
255
262
|
/**
|
|
@@ -257,23 +264,69 @@ class BucketView {
|
|
|
257
264
|
*/
|
|
258
265
|
async parseGraphProp(trx, node) {
|
|
259
266
|
const meta = node.field.meta.graph;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
if (
|
|
263
|
-
link =
|
|
267
|
+
const links = await node.bucket.graph.readManyLinks(trx, node.data.map(entry => entry.raw), meta.link, { silent: true });
|
|
268
|
+
for (let i = 0; i < links.length; i++) {
|
|
269
|
+
if (meta.view) {
|
|
270
|
+
const link = node.bucket.schema.graph.links[meta.link];
|
|
271
|
+
node.data[i].target[node.field.name] = link.many ? [] : {};
|
|
264
272
|
}
|
|
265
273
|
else {
|
|
266
|
-
|
|
274
|
+
node.data[i].target[node.field.name] = links[i];
|
|
267
275
|
}
|
|
268
|
-
entry.target[node.field.name] = await promise_1.default.solve(link);
|
|
269
276
|
}
|
|
277
|
+
let next = [];
|
|
278
|
+
if (meta.view) {
|
|
279
|
+
const schema = node.bucket.schema;
|
|
280
|
+
const otherBucketDep = schema.graph.links[meta.link].bucket;
|
|
281
|
+
const module = trx_node_1.TrxNode.getModule(trx);
|
|
282
|
+
const otherBucket = dependency_1.$Dependency.resolve(module.schema, otherBucketDep);
|
|
283
|
+
const view = otherBucket.views[meta.view];
|
|
284
|
+
const { __raw, ...v } = view.fields;
|
|
285
|
+
const link = node.bucket.schema.graph.links[meta.link];
|
|
286
|
+
let nextData;
|
|
287
|
+
if (link.many) {
|
|
288
|
+
const _links = links;
|
|
289
|
+
for (let i = 0; i < _links.length; i++) {
|
|
290
|
+
const target = node.data[i].target[node.field.name];
|
|
291
|
+
for (let j = 0; j < _links[i].length; j++) {
|
|
292
|
+
target.push(__raw ? { ..._links[i][j] } : {});
|
|
293
|
+
target[j].$v = meta.view;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
nextData = _links.map((ll, i) => ll.map((l, j) => ({ value: l, target: node.data[i].target[node.field.name][j] }))).flat(1);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
const _links = links;
|
|
300
|
+
for (let i = 0; i < _links.length; i++) {
|
|
301
|
+
const target = node.data[i].target[node.field.name];
|
|
302
|
+
if (__raw) {
|
|
303
|
+
Object.assign(target, _links[i]);
|
|
304
|
+
}
|
|
305
|
+
target.$v = meta.view;
|
|
306
|
+
}
|
|
307
|
+
nextData = _links.map((l, i) => ({
|
|
308
|
+
value: l, target: node.data[i].target[node.field.name]
|
|
309
|
+
}));
|
|
310
|
+
}
|
|
311
|
+
next = Object.values(v).map(field => ({
|
|
312
|
+
bucket: module.buckets[otherBucketDep.refName],
|
|
313
|
+
field,
|
|
314
|
+
data: nextData.map($ => ({
|
|
315
|
+
raw: $.value,
|
|
316
|
+
value: $.value,
|
|
317
|
+
index: [],
|
|
318
|
+
target: $.target
|
|
319
|
+
}))
|
|
320
|
+
}));
|
|
321
|
+
}
|
|
322
|
+
return next;
|
|
270
323
|
}
|
|
271
324
|
/**
|
|
272
325
|
* [drive]
|
|
273
326
|
*/
|
|
274
327
|
async parseDriveProp(trx, node) {
|
|
275
|
-
if (!
|
|
276
|
-
throw error_1.NesoiError.Bucket.Drive.NoAdapter({ bucket:
|
|
328
|
+
if (!node.bucket.drive) {
|
|
329
|
+
throw error_1.NesoiError.Bucket.Drive.NoAdapter({ bucket: node.bucket.schema.alias });
|
|
277
330
|
}
|
|
278
331
|
const meta = node.field.meta.drive;
|
|
279
332
|
for (const entry of node.data) {
|
|
@@ -281,12 +334,12 @@ class BucketView {
|
|
|
281
334
|
if (Array.isArray(value)) {
|
|
282
335
|
const public_urls = [];
|
|
283
336
|
for (const obj of value) {
|
|
284
|
-
public_urls.push(await
|
|
337
|
+
public_urls.push(await node.bucket.drive.public(obj));
|
|
285
338
|
}
|
|
286
339
|
entry.target[node.field.name] = public_urls;
|
|
287
340
|
}
|
|
288
341
|
else {
|
|
289
|
-
entry.target[node.field.name] = await
|
|
342
|
+
entry.target[node.field.name] = await node.bucket.drive.public(value);
|
|
290
343
|
}
|
|
291
344
|
}
|
|
292
345
|
}
|
|
@@ -64,6 +64,11 @@ export declare class BucketTrxNode<M extends $Module, $ extends $Bucket> {
|
|
|
64
64
|
* or `undefined` if the graph link doesn't resolve.
|
|
65
65
|
*/
|
|
66
66
|
readLink<LinkName extends keyof $['graph']['links'], Link extends $['graph']['links'][LinkName], Obj extends Link['#bucket']['#data']>(id: $['#data']['id'], link: LinkName): Promise<Link['#many'] extends true ? Obj[] : (Obj | undefined)>;
|
|
67
|
+
/**
|
|
68
|
+
* Returns one or more objects referenced by the graph link,
|
|
69
|
+
* or `undefined` if the graph link doesn't resolve.
|
|
70
|
+
*/
|
|
71
|
+
readManyLinks<LinkName extends keyof $['graph']['links'], Link extends $['graph']['links'][LinkName], Obj extends Link['#bucket']['#data']>(ids: $['#data']['id'][], link: LinkName): Promise<Link['#many'] extends true ? Obj[] : (Obj | undefined)>;
|
|
67
72
|
/**
|
|
68
73
|
* Returns one or more objects referenced by the graph link built with a view,
|
|
69
74
|
* or `undefined` if the graph link doesn't resolve.
|
|
@@ -133,6 +133,16 @@ class BucketTrxNode {
|
|
|
133
133
|
no_tenancy: !this.enableTenancy
|
|
134
134
|
}));
|
|
135
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Returns one or more objects referenced by the graph link,
|
|
138
|
+
* or `undefined` if the graph link doesn't resolve.
|
|
139
|
+
*/
|
|
140
|
+
async readManyLinks(ids, link) {
|
|
141
|
+
return this.wrap('readLinks', { ids, link }, trx => this.bucket.readManyLinks(trx, ids, link, {
|
|
142
|
+
silent: true,
|
|
143
|
+
no_tenancy: !this.enableTenancy
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
136
146
|
/**
|
|
137
147
|
* Returns one or more objects referenced by the graph link built with a view,
|
|
138
148
|
* or `undefined` if the graph link doesn't resolve.
|
|
@@ -14,8 +14,10 @@ export declare class BucketQueryTrxNode<M extends $Module, B extends $Bucket, V
|
|
|
14
14
|
private query;
|
|
15
15
|
private enableTenancy;
|
|
16
16
|
private view?;
|
|
17
|
+
private _params?;
|
|
17
18
|
constructor(trx: TrxNode<any, M, any>, bucket: Bucket<M, B>, query: NQL_AnyQuery, enableTenancy: boolean, view?: V | undefined);
|
|
18
19
|
merge($: NQL_Query<M, B>): void;
|
|
20
|
+
params(value: Record<string, any>): this;
|
|
19
21
|
first(): Promise<Obj | undefined>;
|
|
20
22
|
firstOrFail(): Promise<Obj>;
|
|
21
23
|
all(): Promise<Obj[]>;
|