@nocobase/database 0.9.1-alpha.1 → 0.9.2-alpha.1

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.
Files changed (173) hide show
  1. package/lib/collection-group-manager.d.ts +13 -0
  2. package/lib/collection-group-manager.js +91 -0
  3. package/lib/collection-importer.js +0 -24
  4. package/lib/collection.d.ts +26 -4
  5. package/lib/collection.js +190 -234
  6. package/lib/database-utils/index.js +3 -15
  7. package/lib/database.d.ts +9 -0
  8. package/lib/database.js +171 -299
  9. package/lib/decorators/must-have-filter-decorator.js +0 -7
  10. package/lib/decorators/transaction-decorator.js +5 -18
  11. package/lib/errors/identifier-error.js +0 -3
  12. package/lib/features/ReferencesMap.js +1 -14
  13. package/lib/features/referential-integrity-check.js +7 -21
  14. package/lib/field-repository/array-field-repository.js +5 -45
  15. package/lib/fields/array-field.js +0 -13
  16. package/lib/fields/belongs-to-field.js +24 -50
  17. package/lib/fields/belongs-to-many-field.js +29 -47
  18. package/lib/fields/boolean-field.js +0 -7
  19. package/lib/fields/context-field.js +2 -23
  20. package/lib/fields/date-field.d.ts +4 -0
  21. package/lib/fields/date-field.js +15 -7
  22. package/lib/fields/field.js +32 -85
  23. package/lib/fields/has-many-field.js +16 -49
  24. package/lib/fields/has-one-field.js +18 -52
  25. package/lib/fields/index.js +0 -44
  26. package/lib/fields/json-field.js +0 -12
  27. package/lib/fields/number-field.js +0 -23
  28. package/lib/fields/password-field.js +8 -35
  29. package/lib/fields/radio-field.js +0 -18
  30. package/lib/fields/relation-field.js +4 -16
  31. package/lib/fields/set-field.js +0 -8
  32. package/lib/fields/sort-field.js +84 -73
  33. package/lib/fields/string-field.js +0 -7
  34. package/lib/fields/text-field.js +0 -7
  35. package/lib/fields/time-field.js +0 -7
  36. package/lib/fields/uid-field.js +4 -22
  37. package/lib/fields/uuid-field.js +3 -12
  38. package/lib/fields/virtual-field.js +0 -7
  39. package/lib/filter-match.js +7 -22
  40. package/lib/filter-parser.js +38 -102
  41. package/lib/index.d.ts +3 -0
  42. package/lib/index.js +36 -42
  43. package/lib/inherited-collection.js +15 -62
  44. package/lib/inherited-map.js +7 -48
  45. package/lib/listeners/adjacency-list.d.ts +3 -0
  46. package/lib/listeners/adjacency-list.js +91 -0
  47. package/lib/listeners/index.d.ts +2 -0
  48. package/lib/listeners/index.js +12 -0
  49. package/lib/magic-attribute-model.js +58 -114
  50. package/lib/migration.js +7 -28
  51. package/lib/mock-database.d.ts +4 -4
  52. package/lib/mock-database.js +15 -18
  53. package/lib/model-hook.js +4 -35
  54. package/lib/model.js +12 -54
  55. package/lib/operators/array.js +2 -32
  56. package/lib/operators/association.js +0 -6
  57. package/lib/operators/boolean.js +0 -6
  58. package/lib/operators/child-collection.d.ts +2 -0
  59. package/lib/operators/child-collection.js +32 -0
  60. package/lib/operators/date.js +123 -60
  61. package/lib/operators/empty.js +3 -32
  62. package/lib/operators/eq.d.ts +2 -0
  63. package/lib/operators/eq.js +26 -0
  64. package/lib/operators/index.js +4 -7
  65. package/lib/operators/ne.js +5 -5
  66. package/lib/operators/notIn.js +0 -5
  67. package/lib/operators/string.js +0 -11
  68. package/lib/operators/utils.js +0 -6
  69. package/lib/options-parser.d.ts +1 -1
  70. package/lib/options-parser.js +47 -107
  71. package/lib/playground.js +0 -4
  72. package/lib/query-interface/mysql-query-interface.d.ts +18 -0
  73. package/lib/query-interface/mysql-query-interface.js +88 -0
  74. package/lib/query-interface/postgres-query-interface.d.ts +14 -0
  75. package/lib/query-interface/postgres-query-interface.js +99 -0
  76. package/lib/query-interface/query-interface-builder.d.ts +2 -0
  77. package/lib/query-interface/query-interface-builder.js +18 -0
  78. package/lib/query-interface/query-interface.d.ts +21 -0
  79. package/lib/query-interface/query-interface.js +48 -0
  80. package/lib/query-interface/sqlite-query-interface.d.ts +17 -0
  81. package/lib/query-interface/sqlite-query-interface.js +89 -0
  82. package/lib/relation-repository/belongs-to-many-repository.js +21 -78
  83. package/lib/relation-repository/belongs-to-repository.js +0 -3
  84. package/lib/relation-repository/hasmany-repository.js +8 -44
  85. package/lib/relation-repository/hasone-repository.js +0 -3
  86. package/lib/relation-repository/multiple-relation-repository.js +16 -68
  87. package/lib/relation-repository/relation-repository.js +5 -42
  88. package/lib/relation-repository/single-relation-repository.js +6 -43
  89. package/lib/repository.d.ts +1 -0
  90. package/lib/repository.js +36 -182
  91. package/lib/sql-parser/index.js +10527 -0
  92. package/lib/sql-parser/sql.pegjs +1297 -0
  93. package/lib/sync-runner.d.ts +1 -1
  94. package/lib/sync-runner.js +26 -64
  95. package/lib/update-associations.js +58 -157
  96. package/lib/update-guard.js +10 -49
  97. package/lib/utils.js +16 -54
  98. package/lib/value-parsers/array-value-parser.js +3 -21
  99. package/lib/value-parsers/base-value-parser.js +0 -13
  100. package/lib/value-parsers/boolean-value-parser.js +4 -10
  101. package/lib/value-parsers/date-value-parser.js +0 -23
  102. package/lib/value-parsers/index.js +0 -10
  103. package/lib/value-parsers/json-value-parser.js +0 -7
  104. package/lib/value-parsers/number-value-parser.js +0 -9
  105. package/lib/value-parsers/string-value-parser.js +3 -20
  106. package/lib/value-parsers/to-many-value-parser.js +1 -42
  107. package/lib/value-parsers/to-one-value-parser.js +0 -14
  108. package/lib/view/field-type-map.d.ts +47 -0
  109. package/lib/view/field-type-map.js +56 -0
  110. package/lib/view/view-inference.d.ts +31 -0
  111. package/lib/view/view-inference.js +92 -0
  112. package/lib/view-collection.d.ts +6 -0
  113. package/lib/view-collection.js +24 -0
  114. package/package.json +4 -3
  115. package/src/__tests__/collection.test.ts +44 -0
  116. package/src/__tests__/fields/date.test.ts +75 -0
  117. package/src/__tests__/fields/sort-field.test.ts +100 -0
  118. package/src/__tests__/filter.test.ts +60 -0
  119. package/src/__tests__/group.test.ts +50 -0
  120. package/src/__tests__/inhertits/collection-inherits.test.ts +114 -0
  121. package/src/__tests__/operator/date-operator.test.ts +244 -98
  122. package/src/__tests__/operator/eq.test.ts +76 -0
  123. package/src/__tests__/operator/ne.test.ts +19 -1
  124. package/src/__tests__/relation-repository/belongs-to-many-repository.test.ts +82 -0
  125. package/src/__tests__/repository/find.test.ts +33 -0
  126. package/src/__tests__/repository.test.ts +88 -0
  127. package/src/__tests__/sql-parser.test.ts +13 -0
  128. package/src/__tests__/tree.test.ts +217 -0
  129. package/src/__tests__/view/list-view.test.ts +34 -0
  130. package/src/__tests__/view/view-collection.test.ts +199 -0
  131. package/src/__tests__/view/view-inference.test.ts +145 -0
  132. package/src/__tests__/view/view-repository.test.ts +67 -0
  133. package/src/collection-group-manager.ts +94 -0
  134. package/src/collection.ts +126 -16
  135. package/src/database-utils/index.ts +1 -0
  136. package/src/database.ts +98 -17
  137. package/src/features/ReferencesMap.ts +3 -2
  138. package/src/fields/belongs-to-many-field.ts +23 -4
  139. package/src/fields/date-field.ts +18 -0
  140. package/src/fields/field.ts +17 -7
  141. package/src/fields/json-field.ts +1 -0
  142. package/src/fields/sort-field.ts +90 -29
  143. package/src/filter-parser.ts +2 -1
  144. package/src/index.ts +3 -1
  145. package/src/listeners/adjacency-list.ts +60 -0
  146. package/src/listeners/index.ts +7 -0
  147. package/src/mock-database.ts +14 -2
  148. package/src/model.ts +4 -0
  149. package/src/operators/child-collection.ts +24 -0
  150. package/src/operators/date.ts +108 -24
  151. package/src/operators/eq.ts +14 -0
  152. package/src/operators/index.ts +2 -0
  153. package/src/operators/ne.ts +12 -7
  154. package/src/options-parser.ts +25 -11
  155. package/src/query-interface/mysql-query-interface.ts +72 -0
  156. package/src/query-interface/postgres-query-interface.ts +103 -0
  157. package/src/query-interface/query-interface-builder.ts +14 -0
  158. package/src/query-interface/query-interface.ts +43 -0
  159. package/src/query-interface/sqlite-query-interface.ts +79 -0
  160. package/src/relation-repository/belongs-to-many-repository.ts +20 -1
  161. package/src/relation-repository/hasmany-repository.ts +5 -3
  162. package/src/relation-repository/multiple-relation-repository.ts +13 -1
  163. package/src/relation-repository/single-relation-repository.ts +2 -0
  164. package/src/repository.ts +6 -13
  165. package/src/sql-parser/index.js +10698 -0
  166. package/src/sql-parser/readme.md +2 -0
  167. package/src/sql-parser/sql.pegjs +1297 -0
  168. package/src/sync-runner.ts +27 -32
  169. package/src/update-associations.ts +26 -22
  170. package/src/utils.ts +4 -3
  171. package/src/view/field-type-map.ts +56 -0
  172. package/src/view/view-inference.ts +106 -0
  173. package/src/view-collection.ts +21 -0
@@ -1,24 +1,26 @@
1
- import { mockDatabase } from '../index';
2
- import { Collection } from '../../collection';
3
1
  import Database from '../../database';
2
+ import { Repository } from '../../repository';
3
+ import { mockDatabase } from '../index';
4
4
 
5
5
  describe('date operator test', () => {
6
6
  let db: Database;
7
7
 
8
- let User: Collection;
8
+ let repository: Repository;
9
9
 
10
10
  afterEach(async () => {
11
11
  await db.close();
12
12
  });
13
13
 
14
14
  beforeEach(async () => {
15
- db = mockDatabase();
16
-
17
- User = db.collection({
18
- name: 'users',
15
+ db = mockDatabase({
16
+ timezone: '+00:00',
17
+ });
18
+ await db.clean({ drop: true });
19
+ const Test = db.collection({
20
+ name: 'tests',
19
21
  fields: [
20
22
  {
21
- name: 'birthday',
23
+ name: 'date1',
22
24
  type: 'date',
23
25
  },
24
26
  {
@@ -27,139 +29,283 @@ describe('date operator test', () => {
27
29
  },
28
30
  ],
29
31
  });
30
-
31
- await db.sync({ force: true, alter: { drop: false } });
32
+ repository = Test.repository;
33
+ await db.sync();
32
34
  });
33
35
 
34
36
  test('$dateOn', async () => {
35
- const u0 = await User.repository.create({
36
- values: {
37
- birthday: '1990-01-02 12:03:02',
38
- name: 'u0',
39
- },
37
+ await repository.create({
38
+ values: [
39
+ {
40
+ date1: '2023-01-01T00:00:00.000Z',
41
+ name: 'u0',
42
+ },
43
+ {
44
+ date1: '2023-01-01T00:00:00.001Z',
45
+ name: 'u1',
46
+ },
47
+ {
48
+ date1: '2022-12-31T16:00:00.000Z',
49
+ name: 'u2',
50
+ },
51
+ {
52
+ date1: '2022-12-31T16:00:00.001Z',
53
+ name: 'u3',
54
+ },
55
+ ],
40
56
  });
41
-
42
- const user1 = await User.repository.create({
43
- values: {
44
- birthday: '1990-01-01 12:03:02',
45
- name: 'user1',
57
+ let count: number;
58
+ count = await repository.count({
59
+ filter: {
60
+ 'date1.$dateOn': '2023',
46
61
  },
47
62
  });
48
-
49
- const user = await User.repository.findOne({
50
- filter: { 'birthday.$dateOn': '1990-01-01' },
63
+ expect(count).toBe(2);
64
+ count = await repository.count({
65
+ filter: {
66
+ 'date1.$dateOn': '2023+08:00',
67
+ },
51
68
  });
52
-
53
- expect(user.get('id')).toEqual(user1.get('id'));
69
+ expect(count).toBe(4);
54
70
  });
55
71
 
56
72
  test('$dateNotOn', async () => {
57
- const u0 = await User.repository.create({
58
- values: {
59
- birthday: '1990-01-02 12:03:02',
60
- name: 'u0',
61
- },
73
+ await repository.create({
74
+ values: [
75
+ {
76
+ date1: '2023-01-01T00:00:00.000Z',
77
+ name: 'u0',
78
+ },
79
+ {
80
+ date1: '2023-01-01T00:00:00.001Z',
81
+ name: 'u1',
82
+ },
83
+ {
84
+ date1: '2022-12-31T16:00:00.000Z',
85
+ name: 'u2',
86
+ },
87
+ {
88
+ date1: '2022-12-31T16:00:00.001Z',
89
+ name: 'u3',
90
+ },
91
+ ],
62
92
  });
63
-
64
- const user1 = await User.repository.create({
65
- values: {
66
- birthday: '1990-01-01 12:03:02',
67
- name: 'user1',
93
+ let count: number;
94
+ count = await repository.count({
95
+ filter: {
96
+ 'date1.$dateNotOn': '2023',
68
97
  },
69
98
  });
70
-
71
- const user = await User.repository.findOne({
72
- filter: { 'birthday.$dateNotOn': '1990-01-01' },
99
+ expect(count).toBe(2);
100
+ count = await repository.count({
101
+ filter: {
102
+ 'date1.$dateNotOn': '2023+08:00',
103
+ },
73
104
  });
74
-
75
- expect(user.get('id')).toEqual(u0.get('id'));
105
+ expect(count).toBe(0);
76
106
  });
77
107
 
78
108
  test('$dateBefore', async () => {
79
- const u0 = await User.repository.create({
80
- values: {
81
- birthday: '1990-05-01 12:03:02',
82
- name: 'u0',
83
- },
109
+ await repository.create({
110
+ values: [
111
+ {
112
+ date1: '2023-01-01T00:00:00.000Z',
113
+ name: 'u0',
114
+ },
115
+ {
116
+ date1: '2023-01-01T00:00:00.001Z',
117
+ name: 'u1',
118
+ },
119
+ {
120
+ date1: '2022-12-31T16:00:00.000Z',
121
+ name: 'u2',
122
+ },
123
+ {
124
+ date1: '2022-12-31T16:00:00.001Z',
125
+ name: 'u3',
126
+ },
127
+ {
128
+ date1: '2022-12-30T15:59:59.999Z',
129
+ name: 'u4',
130
+ },
131
+ ],
84
132
  });
85
-
86
- const user1 = await User.repository.create({
87
- values: {
88
- birthday: '1990-01-01 12:03:02',
89
- name: 'user1',
133
+ let count: number;
134
+ count = await repository.count({
135
+ filter: {
136
+ 'date1.$dateBefore': '2023',
90
137
  },
91
138
  });
92
-
93
- const user = await User.repository.findOne({
94
- filter: { 'birthday.$dateBefore': '1990-04-01' },
139
+ expect(count).toBe(3);
140
+ count = await repository.count({
141
+ filter: {
142
+ 'date1.$dateBefore': '2023+08:00',
143
+ },
95
144
  });
96
-
97
- expect(user.get('id')).toEqual(user1.get('id'));
145
+ expect(count).toBe(1);
98
146
  });
99
147
 
100
148
  test('$dateNotBefore', async () => {
101
- const u0 = await User.repository.create({
102
- values: {
103
- birthday: '1990-05-01 12:03:02',
104
- name: 'u0',
105
- },
149
+ await repository.create({
150
+ values: [
151
+ {
152
+ date1: '2023-01-01T00:00:00.000Z',
153
+ name: 'u0',
154
+ },
155
+ {
156
+ date1: '2023-01-01T00:00:00.001Z',
157
+ name: 'u1',
158
+ },
159
+ {
160
+ date1: '2022-12-31T16:00:00.000Z',
161
+ name: 'u2',
162
+ },
163
+ {
164
+ date1: '2022-12-31T16:00:00.001Z',
165
+ name: 'u3',
166
+ },
167
+ {
168
+ date1: '2022-12-30T15:59:59.999Z',
169
+ name: 'u4',
170
+ },
171
+ ],
106
172
  });
107
-
108
- const user1 = await User.repository.create({
109
- values: {
110
- birthday: '1990-01-01 12:03:02',
111
- name: 'user1',
173
+ let count: number;
174
+ count = await repository.count({
175
+ filter: {
176
+ 'date1.$dateNotBefore': '2023',
112
177
  },
113
178
  });
114
-
115
- const user = await User.repository.findOne({
116
- filter: { 'birthday.$dateNotBefore': '1990-04-01' },
179
+ expect(count).toBe(2);
180
+ count = await repository.count({
181
+ filter: {
182
+ 'date1.$dateNotBefore': '2023+08:00',
183
+ },
117
184
  });
118
-
119
- expect(user.get('id')).toEqual(u0.get('id'));
185
+ expect(count).toBe(4);
120
186
  });
121
187
 
122
188
  test('$dateAfter', async () => {
123
- const u0 = await User.repository.create({
124
- values: {
125
- birthday: '1990-05-01 12:03:02',
126
- name: 'u0',
127
- },
189
+ await repository.create({
190
+ values: [
191
+ {
192
+ date1: '2023-01-01T00:00:00.000Z',
193
+ name: 'u0',
194
+ },
195
+ {
196
+ date1: '2023-01-01T00:00:00.001Z',
197
+ name: 'u1',
198
+ },
199
+ {
200
+ date1: '2022-12-31T16:00:00.000Z',
201
+ name: 'u2',
202
+ },
203
+ {
204
+ date1: '2022-12-31T16:00:00.001Z',
205
+ name: 'u3',
206
+ },
207
+ {
208
+ date1: '2022-12-30T15:59:59.999Z',
209
+ name: 'u4',
210
+ },
211
+ ],
128
212
  });
129
-
130
- const user1 = await User.repository.create({
131
- values: {
132
- birthday: '1990-01-01 12:03:02',
133
- name: 'user1',
213
+ let count: number;
214
+ count = await repository.count({
215
+ filter: {
216
+ 'date1.$dateAfter': '2022',
134
217
  },
135
218
  });
136
-
137
- const user = await User.repository.findOne({
138
- filter: { 'birthday.$dateAfter': '1990-04-01' },
219
+ expect(count).toBe(2);
220
+ count = await repository.count({
221
+ filter: {
222
+ 'date1.$dateAfter': '2022+08:00',
223
+ },
139
224
  });
140
-
141
- expect(user.get('id')).toEqual(u0.get('id'));
225
+ expect(count).toBe(4);
142
226
  });
143
227
 
144
228
  test('$dateNotAfter', async () => {
145
- const u0 = await User.repository.create({
146
- values: {
147
- birthday: '1990-05-01 12:03:02',
148
- name: 'u0',
229
+ await repository.create({
230
+ values: [
231
+ {
232
+ date1: '2023-01-01T00:00:00.000Z',
233
+ name: 'u0',
234
+ },
235
+ {
236
+ date1: '2023-01-01T00:00:00.001Z',
237
+ name: 'u1',
238
+ },
239
+ {
240
+ date1: '2022-12-31T16:00:00.000Z',
241
+ name: 'u2',
242
+ },
243
+ {
244
+ date1: '2022-12-31T16:00:00.001Z',
245
+ name: 'u3',
246
+ },
247
+ {
248
+ date1: '2022-12-30T15:59:59.999Z',
249
+ name: 'u4',
250
+ },
251
+ ],
252
+ });
253
+ let count: number;
254
+ count = await repository.count({
255
+ filter: {
256
+ 'date1.$dateNotAfter': '2022',
149
257
  },
150
258
  });
151
-
152
- const user1 = await User.repository.create({
153
- values: {
154
- birthday: '1990-01-01 12:03:02',
155
- name: 'user1',
259
+ expect(count).toBe(3);
260
+ count = await repository.count({
261
+ filter: {
262
+ 'date1.$dateNotAfter': '2022+08:00',
156
263
  },
157
264
  });
265
+ expect(count).toBe(1);
266
+ });
158
267
 
159
- const user = await User.repository.findOne({
160
- filter: { 'birthday.$dateNotAfter': '1990-04-01' },
268
+ test('$dateBetween', async () => {
269
+ await repository.create({
270
+ values: [
271
+ {
272
+ date1: '2023-01-01T00:00:00.000Z',
273
+ name: 'u0',
274
+ },
275
+ {
276
+ date1: '2023-01-05T16:00:00.000Z',
277
+ name: 'u1',
278
+ },
279
+ {
280
+ date1: '2022-12-31T16:00:00.000Z',
281
+ name: 'u2',
282
+ },
283
+ {
284
+ date1: '2022-12-31T16:00:00.001Z',
285
+ name: 'u3',
286
+ },
287
+ {
288
+ date1: '2022-12-30T15:59:59.999Z',
289
+ name: 'u4',
290
+ },
291
+ {
292
+ date1: '2023-01-04T16:00:00.000Z',
293
+ name: 'u1',
294
+ },
295
+ ],
161
296
  });
162
-
163
- expect(user.get('id')).toEqual(user1.get('id'));
297
+ let count: number;
298
+ count = await repository.count({
299
+ filter: {
300
+ 'date1.$dateBetween': '[2023-01-01,2023-01-05]',
301
+ },
302
+ });
303
+ expect(count).toBe(3);
304
+ count = await repository.count({
305
+ filter: {
306
+ 'date1.$dateBetween': '[2023-01-01,2023-01-05]+08:00',
307
+ },
308
+ });
309
+ expect(count).toBe(4);
164
310
  });
165
311
  });
@@ -0,0 +1,76 @@
1
+ import Database from '../../database';
2
+ import { mockDatabase } from '../index';
3
+
4
+ describe('eq operator', () => {
5
+ let db: Database;
6
+ let Test;
7
+
8
+ beforeEach(async () => {
9
+ db = mockDatabase({});
10
+
11
+ Test = db.collection({
12
+ name: 'tests',
13
+ fields: [{ type: 'string', name: 'name' }],
14
+ });
15
+
16
+ await db.sync();
17
+ });
18
+
19
+ afterEach(async () => {
20
+ await db.close();
21
+ });
22
+
23
+ it('should eq with array', async () => {
24
+ await db.getRepository('tests').create({
25
+ values: [
26
+ { name: '123' },
27
+ { name: '234' },
28
+ { name: '345' },
29
+ ]
30
+ });
31
+
32
+ const results = await db.getRepository('tests').count({
33
+ filter: {
34
+ 'name.$eq': ['123', '234'],
35
+ },
36
+ });
37
+
38
+ expect(results).toEqual(2);
39
+ });
40
+
41
+ it('should eq with array', async () => {
42
+ await db.getRepository('tests').create({
43
+ values: [
44
+ { name: '123' },
45
+ { name: '234' },
46
+ { name: '345' },
47
+ ]
48
+ });
49
+
50
+ const results = await db.getRepository('tests').count({
51
+ filter: {
52
+ 'name.$eq': '123',
53
+ },
54
+ });
55
+
56
+ expect(results).toEqual(1);
57
+ });
58
+
59
+ it('should eq with array', async () => {
60
+ await db.getRepository('tests').create({
61
+ values: [
62
+ { name: '123' },
63
+ { name: '234' },
64
+ { name: '345' },
65
+ ]
66
+ });
67
+
68
+ const results = await db.getRepository('tests').count({
69
+ filter: {
70
+ 'name.$eq': '456',
71
+ },
72
+ });
73
+
74
+ expect(results).toEqual(0);
75
+ });
76
+ });
@@ -1,5 +1,5 @@
1
- import { mockDatabase } from '../index';
2
1
  import Database from '../../database';
2
+ import { mockDatabase } from '../index';
3
3
 
4
4
  describe('ne operator', () => {
5
5
  let db: Database;
@@ -42,4 +42,22 @@ describe('ne operator', () => {
42
42
 
43
43
  expect(results).toBe(0);
44
44
  });
45
+
46
+ it('should ne with array', async () => {
47
+ await db.getRepository('tests').create({
48
+ values: [
49
+ { name: '123' },
50
+ { name: '234' },
51
+ { name: '345' },
52
+ ]
53
+ });
54
+
55
+ const results = await db.getRepository('tests').count({
56
+ filter: {
57
+ 'name.$ne': ['123', '234'],
58
+ },
59
+ });
60
+
61
+ expect(results).toEqual(1);
62
+ });
45
63
  });
@@ -3,6 +3,88 @@ import Database from '../../database';
3
3
  import { BelongsToManyRepository } from '../../relation-repository/belongs-to-many-repository';
4
4
  import { mockDatabase } from '../index';
5
5
 
6
+ describe('belongs to many with collection that has no id key', () => {
7
+ let db: Database;
8
+ beforeEach(async () => {
9
+ db = mockDatabase();
10
+
11
+ await db.clean({ drop: true });
12
+ });
13
+
14
+ afterEach(async () => {
15
+ await db.close();
16
+ });
17
+
18
+ it('should set relation', async () => {
19
+ const A = db.collection({
20
+ name: 'a',
21
+ autoGenId: false,
22
+ fields: [
23
+ {
24
+ type: 'string',
25
+ name: 'name',
26
+ primaryKey: true,
27
+ },
28
+ {
29
+ type: 'belongsToMany',
30
+ name: 'bs',
31
+ target: 'b',
32
+ through: 'asbs',
33
+ sourceKey: 'name',
34
+ foreignKey: 'aName',
35
+ otherKey: 'bName',
36
+ targetKey: 'name',
37
+ },
38
+ ],
39
+ });
40
+
41
+ const B = db.collection({
42
+ name: 'b',
43
+ autoGenId: false,
44
+ fields: [
45
+ {
46
+ type: 'string',
47
+ name: 'key',
48
+ primaryKey: true,
49
+ },
50
+ {
51
+ type: 'string',
52
+ name: 'name',
53
+ unique: true,
54
+ },
55
+ {
56
+ type: 'belongsToMany',
57
+ name: 'as',
58
+ target: 'a',
59
+ through: 'asbs',
60
+ sourceKey: 'name',
61
+ foreignKey: 'bName',
62
+ otherKey: 'aName',
63
+ targetKey: 'name',
64
+ },
65
+ ],
66
+ });
67
+
68
+ await db.sync();
69
+ const a = await A.repository.create({
70
+ values: {
71
+ name: 'a1',
72
+ },
73
+ });
74
+ const b = await B.repository.create({
75
+ values: {
76
+ key: 'b1_key',
77
+ name: 'b1',
78
+ },
79
+ });
80
+
81
+ const a1bsRepository = await A.repository.relation<BelongsToManyRepository>('bs').of('a1');
82
+ expect(await a1bsRepository.find()).toHaveLength(0);
83
+ await a1bsRepository.toggle('b1');
84
+ expect(await a1bsRepository.find()).toHaveLength(1);
85
+ });
86
+ });
87
+
6
88
  describe('belongs to many with target key', function () {
7
89
  let db: Database;
8
90
  let Tag: Collection;
@@ -9,6 +9,7 @@ describe('repository find', () => {
9
9
  let Post: Collection;
10
10
  let Comment: Collection;
11
11
  let Tag: Collection;
12
+ let Profile: Collection;
12
13
 
13
14
  let A1: Collection;
14
15
  let A2: Collection;
@@ -26,6 +27,7 @@ describe('repository find', () => {
26
27
  { type: 'string', name: 'name' },
27
28
  { type: 'integer', name: 'age' },
28
29
  { type: 'hasMany', name: 'posts' },
30
+ { type: 'hasOne', name: 'profile' },
29
31
  { type: 'belongsToMany', name: 'a1' },
30
32
  { type: 'belongsToMany', name: 'a2' },
31
33
  ],
@@ -41,6 +43,15 @@ describe('repository find', () => {
41
43
  fields: [{ type: 'string', name: 'name' }],
42
44
  });
43
45
 
46
+ Profile = db.collection({
47
+ name: 'profiles',
48
+ fields: [
49
+ { type: 'integer', name: 'salary' },
50
+ { type: 'belongsTo', name: 'user' },
51
+ { type: 'string', name: 'description' },
52
+ ],
53
+ });
54
+
44
55
  Post = db.collection({
45
56
  name: 'posts',
46
57
  fields: [
@@ -90,6 +101,7 @@ describe('repository find', () => {
90
101
  posts: [{ title: 'u1t1', comments: [{ content: 'u1t1c1' }], abc1: [{ name: 't1' }] }],
91
102
  a1: [{ name: 'u1a11' }, { name: 'u1a12' }],
92
103
  a2: [{ name: 'u1a21' }, { name: 'u1a22' }],
104
+ profile: { salary: 1000 },
93
105
  },
94
106
  {
95
107
  name: 'u2',
@@ -97,16 +109,37 @@ describe('repository find', () => {
97
109
  posts: [{ title: 'u2t1', comments: [{ content: 'u2t1c1' }] }],
98
110
  a1: [{ name: 'u2a11' }, { name: 'u2a12' }],
99
111
  a2: [{ name: 'u2a21' }, { name: 'u2a22' }],
112
+ profile: { salary: 2000 },
100
113
  },
101
114
  {
102
115
  name: 'u3',
103
116
  age: 30,
104
117
  posts: [{ title: 'u3t1', comments: [{ content: 'u3t1c1' }] }],
118
+ profile: { salary: 3000 },
105
119
  },
106
120
  ],
107
121
  });
108
122
  });
109
123
 
124
+ it('should only output filed in fields args', async () => {
125
+ const resp = await User.model.findOne({
126
+ attributes: [],
127
+ include: [
128
+ {
129
+ association: 'profile',
130
+ attributes: ['salary'],
131
+ },
132
+ ],
133
+ });
134
+
135
+ const users = await User.repository.find({
136
+ fields: ['profile', 'profile.salary', 'profile.id'],
137
+ });
138
+
139
+ const firstUser = users[0].toJSON();
140
+ expect(Object.keys(firstUser)).toEqual(['profile']);
141
+ });
142
+
110
143
  it('append with associations', async () => {
111
144
  const users = await User.repository.findAndCount({
112
145
  appends: ['posts', 'posts.comments'],