@nocobase/database 0.9.4-alpha.1 → 0.9.4-alpha.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/filter-parser.js +15 -9
- package/package.json +4 -4
- package/src/__tests__/filter.test.ts +54 -0
- package/src/filter-parser.ts +17 -9
package/lib/filter-parser.js
CHANGED
|
@@ -158,11 +158,14 @@ class FilterParser {
|
|
|
158
158
|
const associationKeys = [];
|
|
159
159
|
associationKeys.push(firstKey);
|
|
160
160
|
debug('associationKeys %o', associationKeys);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
161
|
+
const existInclude = _lodash().default.get(include, firstKey);
|
|
162
|
+
if (!existInclude) {
|
|
163
|
+
// set sequelize include option
|
|
164
|
+
_lodash().default.set(include, firstKey, {
|
|
165
|
+
association: firstKey,
|
|
166
|
+
attributes: [] // out put empty fields by default
|
|
167
|
+
});
|
|
168
|
+
}
|
|
166
169
|
// association target model
|
|
167
170
|
let target = associations[firstKey].target;
|
|
168
171
|
debug('association target %o', target);
|
|
@@ -183,10 +186,13 @@ class FilterParser {
|
|
|
183
186
|
}
|
|
184
187
|
assoc.push(associationKey);
|
|
185
188
|
});
|
|
186
|
-
_lodash().default.
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
189
|
+
const existInclude = _lodash().default.get(include, assoc);
|
|
190
|
+
if (!existInclude) {
|
|
191
|
+
_lodash().default.set(include, assoc, {
|
|
192
|
+
association: attr,
|
|
193
|
+
attributes: []
|
|
194
|
+
});
|
|
195
|
+
}
|
|
190
196
|
target = target.associations[attr].target;
|
|
191
197
|
} else {
|
|
192
198
|
throw new Error(`${attr} neither ${firstKey}'s association nor ${firstKey}'s attribute`);
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/database",
|
|
3
|
-
"version": "0.9.4-alpha.
|
|
3
|
+
"version": "0.9.4-alpha.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@nocobase/logger": "0.9.4-alpha.
|
|
10
|
-
"@nocobase/utils": "0.9.4-alpha.
|
|
9
|
+
"@nocobase/logger": "0.9.4-alpha.2",
|
|
10
|
+
"@nocobase/utils": "0.9.4-alpha.2",
|
|
11
11
|
"async-mutex": "^0.3.2",
|
|
12
12
|
"cron-parser": "4.4.0",
|
|
13
13
|
"deepmerge": "^4.2.2",
|
|
@@ -28,5 +28,5 @@
|
|
|
28
28
|
"url": "git+https://github.com/nocobase/nocobase.git",
|
|
29
29
|
"directory": "packages/database"
|
|
30
30
|
},
|
|
31
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "2bc19a85bf9425aa220b6c467315c8087f333a7e"
|
|
32
32
|
}
|
|
@@ -14,6 +14,60 @@ describe('filter', () => {
|
|
|
14
14
|
await db.close();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
+
it('should filter by belongs to many association', async () => {
|
|
18
|
+
const A = db.collection({
|
|
19
|
+
name: 'a',
|
|
20
|
+
fields: [
|
|
21
|
+
{ type: 'string', name: 'name' },
|
|
22
|
+
{ type: 'hasMany', name: 'b', target: 'b' },
|
|
23
|
+
],
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const B = db.collection({
|
|
27
|
+
name: 'b',
|
|
28
|
+
fields: [
|
|
29
|
+
{ type: 'string', name: 'name' },
|
|
30
|
+
{ type: 'belongsTo', name: 'c', target: 'c' },
|
|
31
|
+
{ type: 'belongsTo', name: 'd', target: 'd' },
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const C = db.collection({
|
|
36
|
+
name: 'c',
|
|
37
|
+
fields: [{ type: 'string', name: 'name' }],
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const D = db.collection({
|
|
41
|
+
name: 'd',
|
|
42
|
+
fields: [{ type: 'string', name: 'name' }],
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
await db.sync();
|
|
46
|
+
|
|
47
|
+
const findArgs = {
|
|
48
|
+
filter: {
|
|
49
|
+
$and: [{ b: { c: { name: { $eq: 'c1' } } } }, { b: { d: { name: { $eq: 'd1' } } } }],
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const findOptions = A.repository.buildQueryOptions(findArgs);
|
|
54
|
+
|
|
55
|
+
const include = findOptions.include;
|
|
56
|
+
|
|
57
|
+
const associationB = include.find((i) => i.association === 'b');
|
|
58
|
+
expect(associationB).toBeDefined();
|
|
59
|
+
expect(associationB.include).toHaveLength(2);
|
|
60
|
+
|
|
61
|
+
let err;
|
|
62
|
+
try {
|
|
63
|
+
await A.repository.find({ ...findArgs });
|
|
64
|
+
} catch (e) {
|
|
65
|
+
err = e;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
expect(err).toBeUndefined();
|
|
69
|
+
});
|
|
70
|
+
|
|
17
71
|
it('should filter by hasMany association field', async () => {
|
|
18
72
|
const DeptCollection = db.collection({
|
|
19
73
|
name: 'depts',
|
package/src/filter-parser.ts
CHANGED
|
@@ -164,11 +164,15 @@ export default class FilterParser {
|
|
|
164
164
|
|
|
165
165
|
debug('associationKeys %o', associationKeys);
|
|
166
166
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
167
|
+
const existInclude = _.get(include, firstKey);
|
|
168
|
+
|
|
169
|
+
if (!existInclude) {
|
|
170
|
+
// set sequelize include option
|
|
171
|
+
_.set(include, firstKey, {
|
|
172
|
+
association: firstKey,
|
|
173
|
+
attributes: [], // out put empty fields by default
|
|
174
|
+
});
|
|
175
|
+
}
|
|
172
176
|
|
|
173
177
|
// association target model
|
|
174
178
|
let target = associations[firstKey].target;
|
|
@@ -192,10 +196,14 @@ export default class FilterParser {
|
|
|
192
196
|
assoc.push(associationKey);
|
|
193
197
|
});
|
|
194
198
|
|
|
195
|
-
_.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
+
const existInclude = _.get(include, assoc);
|
|
200
|
+
if (!existInclude) {
|
|
201
|
+
_.set(include, assoc, {
|
|
202
|
+
association: attr,
|
|
203
|
+
attributes: [],
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
199
207
|
target = target.associations[attr].target;
|
|
200
208
|
} else {
|
|
201
209
|
throw new Error(`${attr} neither ${firstKey}'s association nor ${firstKey}'s attribute`);
|