@nocobase/database 0.7.4-alpha.7 → 0.7.6-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.
- package/lib/collection.d.ts +7 -2
- package/lib/collection.js +20 -8
- package/lib/database.d.ts +2 -2
- package/lib/database.js +30 -6
- package/lib/decorators/must-have-filter-decorator.d.ts +2 -0
- package/lib/decorators/must-have-filter-decorator.js +25 -0
- package/lib/{transaction-decorator.d.ts → decorators/transaction-decorator.d.ts} +0 -0
- package/lib/{transaction-decorator.js → decorators/transaction-decorator.js} +1 -4
- package/lib/errors/identifier-error.d.ts +3 -0
- package/lib/errors/identifier-error.js +16 -0
- package/lib/fields/belongs-to-field.js +9 -0
- package/lib/fields/belongs-to-many-field.js +10 -0
- package/lib/fields/date-field.d.ts +1 -1
- package/lib/fields/date-field.js +1 -1
- package/lib/fields/field.d.ts +1 -1
- package/lib/fields/field.js +2 -3
- package/lib/fields/formula-field.d.ts +5 -5
- package/lib/fields/formula-field.js +123 -110
- package/lib/fields/has-many-field.js +9 -0
- package/lib/fields/has-one-field.js +9 -0
- package/lib/fields/index.d.ts +3 -1
- package/lib/fields/index.js +34 -1
- package/lib/fields/number-field.d.ts +6 -0
- package/lib/fields/number-field.js +10 -1
- package/lib/fields/radio-field.d.ts +3 -1
- package/lib/fields/radio-field.js +14 -11
- package/lib/fields/sequence-field.d.ts +31 -0
- package/lib/fields/sequence-field.js +299 -0
- package/lib/fields/sort-field.d.ts +4 -4
- package/lib/fields/sort-field.js +93 -80
- package/lib/filter-parser.js +10 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +7 -0
- package/lib/magic-attribute-model.d.ts +1 -0
- package/lib/magic-attribute-model.js +207 -6
- package/lib/mock-database.js +1 -1
- package/lib/model.d.ts +5 -0
- package/lib/model.js +48 -6
- package/lib/operators/array.js +17 -9
- package/lib/operators/ne.d.ts +4 -0
- package/lib/operators/ne.js +3 -1
- package/lib/relation-repository/belongs-to-many-repository.js +6 -0
- package/lib/relation-repository/multiple-relation-repository.js +32 -9
- package/lib/relation-repository/relation-repository.js +7 -1
- package/lib/relation-repository/single-relation-repository.js +28 -0
- package/lib/repository.d.ts +6 -3
- package/lib/repository.js +42 -9
- package/lib/update-associations.js +48 -71
- package/lib/utils.d.ts +9 -0
- package/lib/utils.js +126 -0
- package/package.json +5 -3
- package/src/__tests__/collection.test.ts +47 -0
- package/src/__tests__/database.test.ts +2 -0
- package/src/__tests__/field-options/inddex.test.ts +43 -0
- package/src/__tests__/fields/array.test.ts +66 -0
- package/src/__tests__/fields/belongs-to-field.test.ts +35 -0
- package/src/__tests__/fields/belongs-to-many-field.test.ts +45 -0
- package/src/__tests__/fields/has-many-field.test.ts +22 -0
- package/src/__tests__/fields/has-one-field.test.ts +21 -0
- package/src/__tests__/fields/sequence-field.test.ts +455 -0
- package/src/__tests__/magic-attribute-model.test.ts +24 -0
- package/src/__tests__/model.changedWithAssociations.test.ts +46 -0
- package/src/__tests__/operator/ne.test.ts +12 -0
- package/src/__tests__/relation-repository/appends.test.ts +64 -0
- package/src/__tests__/relation-repository/belongs-to-many-repository.test.ts +23 -0
- package/src/__tests__/relation-repository/has-many-repository.test.ts +20 -0
- package/src/__tests__/relation-repository/hasone-repository.test.ts +68 -1
- package/src/__tests__/repository/find.test.ts +35 -0
- package/src/__tests__/repository/update.test.ts +35 -0
- package/src/__tests__/repository.test.ts +15 -0
- package/src/collection.ts +28 -13
- package/src/database.ts +18 -6
- package/src/decorators/must-have-filter-decorator.ts +17 -0
- package/src/{transaction-decorator.ts → decorators/transaction-decorator.ts} +1 -2
- package/src/errors/identifier-error.ts +6 -0
- package/src/fields/belongs-to-field.ts +9 -0
- package/src/fields/belongs-to-many-field.ts +15 -0
- package/src/fields/date-field.ts +1 -1
- package/src/fields/field.ts +3 -3
- package/src/fields/formula-field.ts +13 -13
- package/src/fields/has-many-field.ts +10 -0
- package/src/fields/has-one-field.ts +13 -0
- package/src/fields/index.ts +5 -2
- package/src/fields/number-field.ts +10 -0
- package/src/fields/radio-field.ts +22 -24
- package/src/fields/sequence-field.ts +200 -0
- package/src/fields/sort-field.ts +9 -9
- package/src/filter-parser.ts +6 -5
- package/src/index.ts +1 -1
- package/src/magic-attribute-model.ts +188 -6
- package/src/mock-database.ts +1 -1
- package/src/model.ts +34 -1
- package/src/operators/array.ts +17 -10
- package/src/operators/ne.ts +10 -6
- package/src/relation-repository/belongs-to-many-repository.ts +4 -0
- package/src/relation-repository/multiple-relation-repository.ts +26 -11
- package/src/relation-repository/relation-repository.ts +5 -1
- package/src/relation-repository/single-relation-repository.ts +27 -1
- package/src/repository.ts +40 -10
- package/src/update-associations.ts +41 -53
- package/src/utils.ts +71 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import moment from 'moment';
|
|
2
|
+
|
|
3
|
+
import { Database } from '../../database';
|
|
4
|
+
import { mockDatabase } from '..';
|
|
5
|
+
|
|
6
|
+
describe('string field', () => {
|
|
7
|
+
let db: Database;
|
|
8
|
+
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
db = mockDatabase();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(async () => {
|
|
14
|
+
await db.close();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('define', () => {
|
|
18
|
+
it('without any pattern will throw error', async () => {
|
|
19
|
+
expect(() => {
|
|
20
|
+
db.collection({
|
|
21
|
+
name: 'tests',
|
|
22
|
+
fields: [{ type: 'sequence', name: 'name' }],
|
|
23
|
+
});
|
|
24
|
+
}).toThrow();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('with empty pattern will throw error', async () => {
|
|
28
|
+
expect(() => {
|
|
29
|
+
db.collection({
|
|
30
|
+
name: 'tests',
|
|
31
|
+
fields: [{ type: 'sequence', name: 'name', patterns: [] }],
|
|
32
|
+
});
|
|
33
|
+
}).toThrow();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('string pattern', () => {
|
|
38
|
+
it('no options', async () => {
|
|
39
|
+
expect(() => {
|
|
40
|
+
db.collection({
|
|
41
|
+
name: 'tests',
|
|
42
|
+
fields: [{ type: 'sequence', name: 'name', patterns: [{ type: 'string' }] }],
|
|
43
|
+
});
|
|
44
|
+
}).toThrow();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('constant', async () => {
|
|
48
|
+
db.collection({
|
|
49
|
+
name: 'tests',
|
|
50
|
+
fields: [
|
|
51
|
+
{
|
|
52
|
+
type: 'sequence',
|
|
53
|
+
name: 'name',
|
|
54
|
+
patterns: [
|
|
55
|
+
{ type: 'string', options: { value: 'abc' } }
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
await db.sync();
|
|
61
|
+
|
|
62
|
+
const TestModel = db.getModel('tests');
|
|
63
|
+
const item1 = await TestModel.create();
|
|
64
|
+
expect(item1.get('name')).toBe('abc');
|
|
65
|
+
|
|
66
|
+
const item2 = await TestModel.create();
|
|
67
|
+
expect(item2.get('name')).toBe('abc');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('integer pattern', () => {
|
|
72
|
+
it('default start from 0, digits as 1, no cycle', async () => {
|
|
73
|
+
db.collection({
|
|
74
|
+
name: 'tests',
|
|
75
|
+
fields: [
|
|
76
|
+
{
|
|
77
|
+
type: 'sequence',
|
|
78
|
+
name: 'name',
|
|
79
|
+
patterns: [
|
|
80
|
+
{
|
|
81
|
+
type: 'integer'
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
});
|
|
87
|
+
await db.sync();
|
|
88
|
+
|
|
89
|
+
const TestModel = db.getModel('tests');
|
|
90
|
+
const item1 = await TestModel.create();
|
|
91
|
+
expect(item1.get('name')).toBe('0');
|
|
92
|
+
|
|
93
|
+
const item2 = await TestModel.create();
|
|
94
|
+
expect(item2.get('name')).toBe('1');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('start from 9', async () => {
|
|
98
|
+
db.collection({
|
|
99
|
+
name: 'tests',
|
|
100
|
+
fields: [
|
|
101
|
+
{
|
|
102
|
+
type: 'sequence',
|
|
103
|
+
name: 'name',
|
|
104
|
+
patterns: [
|
|
105
|
+
{
|
|
106
|
+
type: 'integer',
|
|
107
|
+
options: {
|
|
108
|
+
start: 9
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
});
|
|
115
|
+
await db.sync();
|
|
116
|
+
|
|
117
|
+
const TestModel = db.getModel('tests');
|
|
118
|
+
const item1 = await TestModel.create();
|
|
119
|
+
expect(item1.get('name')).toBe('9');
|
|
120
|
+
|
|
121
|
+
const item2 = await TestModel.create();
|
|
122
|
+
expect(item2.get('name')).toBe('9');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('start from 0, current set to 9', async () => {
|
|
126
|
+
const collection = db.collection({
|
|
127
|
+
name: 'tests',
|
|
128
|
+
fields: [
|
|
129
|
+
{
|
|
130
|
+
type: 'sequence',
|
|
131
|
+
name: 'name',
|
|
132
|
+
patterns: [
|
|
133
|
+
{
|
|
134
|
+
type: 'integer'
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
});
|
|
140
|
+
await db.sync();
|
|
141
|
+
const field = collection.getField('name');
|
|
142
|
+
// set current option in memory
|
|
143
|
+
field.options.patterns[0].options = { current: 9 };
|
|
144
|
+
|
|
145
|
+
const TestModel = db.getModel('tests');
|
|
146
|
+
const item1 = await TestModel.create();
|
|
147
|
+
expect(item1.get('name')).toBe('0');
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('digits more than 1, start from 9', async () => {
|
|
151
|
+
db.collection({
|
|
152
|
+
name: 'tests',
|
|
153
|
+
fields: [
|
|
154
|
+
{
|
|
155
|
+
type: 'sequence',
|
|
156
|
+
name: 'name',
|
|
157
|
+
patterns: [
|
|
158
|
+
{
|
|
159
|
+
type: 'integer',
|
|
160
|
+
options: {
|
|
161
|
+
digits: 2,
|
|
162
|
+
start: 9
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
],
|
|
168
|
+
});
|
|
169
|
+
await db.sync();
|
|
170
|
+
|
|
171
|
+
const TestModel = db.getModel('tests');
|
|
172
|
+
const item1 = await TestModel.create();
|
|
173
|
+
expect(item1.get('name')).toBe('09');
|
|
174
|
+
|
|
175
|
+
const item2 = await TestModel.create();
|
|
176
|
+
expect(item2.get('name')).toBe('10');
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('cycle by day', async () => {
|
|
180
|
+
db.collection({
|
|
181
|
+
name: 'tests',
|
|
182
|
+
fields: [
|
|
183
|
+
{
|
|
184
|
+
type: 'sequence',
|
|
185
|
+
name: 'name',
|
|
186
|
+
patterns: [
|
|
187
|
+
{
|
|
188
|
+
type: 'integer',
|
|
189
|
+
options: {
|
|
190
|
+
cycle: '0 0 * * * *'
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
});
|
|
197
|
+
await db.sync();
|
|
198
|
+
|
|
199
|
+
const now = new Date();
|
|
200
|
+
const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
|
|
201
|
+
|
|
202
|
+
const TestModel = db.getModel('tests');
|
|
203
|
+
const item1 = await TestModel.create({
|
|
204
|
+
createdAt: yesterday
|
|
205
|
+
});
|
|
206
|
+
expect(item1.get('name')).toBe('0');
|
|
207
|
+
|
|
208
|
+
const item2 = await TestModel.create({
|
|
209
|
+
createdAt: yesterday
|
|
210
|
+
});
|
|
211
|
+
expect(item2.get('name')).toBe('1');
|
|
212
|
+
|
|
213
|
+
const item3 = await TestModel.create();
|
|
214
|
+
expect(item3.get('name')).toBe('0');
|
|
215
|
+
|
|
216
|
+
const item4 = await TestModel.create();
|
|
217
|
+
expect(item4.get('name')).toBe('1');
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
describe('date pattern', () => {
|
|
222
|
+
it('default to current createdAt as YYYYMMDD', async () => {
|
|
223
|
+
db.collection({
|
|
224
|
+
name: 'tests',
|
|
225
|
+
fields: [
|
|
226
|
+
{
|
|
227
|
+
type: 'sequence',
|
|
228
|
+
name: 'name',
|
|
229
|
+
patterns: [
|
|
230
|
+
{ type: 'date' }
|
|
231
|
+
]
|
|
232
|
+
}
|
|
233
|
+
],
|
|
234
|
+
});
|
|
235
|
+
await db.sync();
|
|
236
|
+
|
|
237
|
+
const now = new Date();
|
|
238
|
+
const YYYYMMDD = moment(now).format('YYYYMMDD');
|
|
239
|
+
|
|
240
|
+
const TestModel = db.getModel('tests');
|
|
241
|
+
const item1 = await TestModel.create();
|
|
242
|
+
expect(item1.get('name')).toBe(YYYYMMDD);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('field option', async () => {
|
|
246
|
+
db.collection({
|
|
247
|
+
name: 'tests',
|
|
248
|
+
fields: [
|
|
249
|
+
{
|
|
250
|
+
type: 'sequence',
|
|
251
|
+
name: 'name',
|
|
252
|
+
patterns: [
|
|
253
|
+
{ type: 'date', options: { field: 'date' } }
|
|
254
|
+
]
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
type: 'date',
|
|
258
|
+
name: 'date'
|
|
259
|
+
}
|
|
260
|
+
],
|
|
261
|
+
});
|
|
262
|
+
await db.sync();
|
|
263
|
+
|
|
264
|
+
const date = new Date(2022, 7, 1);
|
|
265
|
+
const YYYYMMDD = moment(date).format('YYYYMMDD');
|
|
266
|
+
|
|
267
|
+
const TestModel = db.getModel('tests');
|
|
268
|
+
const item1 = await TestModel.create({
|
|
269
|
+
date
|
|
270
|
+
});
|
|
271
|
+
expect(item1.get('name')).toBe(YYYYMMDD);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('format option', async () => {
|
|
275
|
+
db.collection({
|
|
276
|
+
name: 'tests',
|
|
277
|
+
fields: [
|
|
278
|
+
{
|
|
279
|
+
type: 'sequence',
|
|
280
|
+
name: 'name',
|
|
281
|
+
patterns: [
|
|
282
|
+
{ type: 'date', options: { format: 'YYYY-MM-DD' } }
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
],
|
|
286
|
+
});
|
|
287
|
+
await db.sync();
|
|
288
|
+
|
|
289
|
+
const now = new Date();
|
|
290
|
+
const YYYYMMDD = moment(now).format('YYYY-MM-DD');
|
|
291
|
+
|
|
292
|
+
const TestModel = db.getModel('tests');
|
|
293
|
+
const item1 = await TestModel.create();
|
|
294
|
+
expect(item1.get('name')).toBe(YYYYMMDD);
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
describe('mixed pattern', () => {
|
|
299
|
+
it('all patterns', async () => {
|
|
300
|
+
db.collection({
|
|
301
|
+
name: 'tests',
|
|
302
|
+
fields: [
|
|
303
|
+
{
|
|
304
|
+
type: 'sequence',
|
|
305
|
+
name: 'name',
|
|
306
|
+
patterns: [
|
|
307
|
+
{ type: 'string', options: { value: 'A' } },
|
|
308
|
+
{ type: 'date' },
|
|
309
|
+
{ type: 'integer' }
|
|
310
|
+
]
|
|
311
|
+
}
|
|
312
|
+
],
|
|
313
|
+
});
|
|
314
|
+
await db.sync();
|
|
315
|
+
|
|
316
|
+
const now = new Date();
|
|
317
|
+
const YYYYMMDD = moment(now).format('YYYYMMDD');
|
|
318
|
+
|
|
319
|
+
const TestModel = db.getModel('tests');
|
|
320
|
+
const item1 = await TestModel.create();
|
|
321
|
+
expect(item1.get('name')).toBe(`A${YYYYMMDD}0`);
|
|
322
|
+
|
|
323
|
+
const item2 = await TestModel.create();
|
|
324
|
+
expect(item2.get('name')).toBe(`A${YYYYMMDD}1`);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it('changed after generated', async () => {
|
|
328
|
+
const testsCollection = db.collection({
|
|
329
|
+
name: 'tests',
|
|
330
|
+
fields: [
|
|
331
|
+
{
|
|
332
|
+
type: 'sequence',
|
|
333
|
+
name: 'name',
|
|
334
|
+
patterns: [
|
|
335
|
+
{ type: 'string', options: { value: 'A' } },
|
|
336
|
+
{ type: 'date' },
|
|
337
|
+
{ type: 'integer' }
|
|
338
|
+
]
|
|
339
|
+
}
|
|
340
|
+
],
|
|
341
|
+
});
|
|
342
|
+
await db.sync();
|
|
343
|
+
|
|
344
|
+
const now = new Date();
|
|
345
|
+
const YYYYMMDD = moment(now).format('YYYYMMDD');
|
|
346
|
+
|
|
347
|
+
const TestModel = db.getModel('tests');
|
|
348
|
+
const item1 = await TestModel.create();
|
|
349
|
+
expect(item1.get('name')).toBe(`A${YYYYMMDD}0`);
|
|
350
|
+
|
|
351
|
+
testsCollection.setField('name', {
|
|
352
|
+
type: 'sequence',
|
|
353
|
+
patterns: [
|
|
354
|
+
{ type: 'string', options: { value: 'A' } },
|
|
355
|
+
{ type: 'date' },
|
|
356
|
+
// change options but no difference with default
|
|
357
|
+
{ type: 'integer', options: { digits: 1 } }
|
|
358
|
+
]
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
const item2 = await TestModel.create();
|
|
362
|
+
expect(item2.get('name')).toBe(`A${YYYYMMDD}1`);
|
|
363
|
+
|
|
364
|
+
testsCollection.setField('name', {
|
|
365
|
+
type: 'sequence',
|
|
366
|
+
patterns: [
|
|
367
|
+
{ type: 'string', options: { value: 'A' } },
|
|
368
|
+
{ type: 'date' },
|
|
369
|
+
{ type: 'integer', options: { digits: 2 } }
|
|
370
|
+
]
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
const item3 = await TestModel.create();
|
|
374
|
+
expect(item3.get('name')).toBe(`A${YYYYMMDD}00`);
|
|
375
|
+
|
|
376
|
+
testsCollection.setField('name', {
|
|
377
|
+
type: 'sequence',
|
|
378
|
+
patterns: [
|
|
379
|
+
{ type: 'string', options: { value: 'a' } },
|
|
380
|
+
{ type: 'date' },
|
|
381
|
+
{ type: 'integer', options: { digits: 2 } }
|
|
382
|
+
]
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
const item4 = await TestModel.create();
|
|
386
|
+
expect(item4.get('name')).toBe(`a${YYYYMMDD}01`);
|
|
387
|
+
|
|
388
|
+
testsCollection.setField('name', {
|
|
389
|
+
type: 'sequence',
|
|
390
|
+
patterns: [
|
|
391
|
+
{ type: 'date' },
|
|
392
|
+
{ type: 'integer', options: { digits: 2 } }
|
|
393
|
+
]
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
const item5 = await TestModel.create();
|
|
397
|
+
expect(item5.get('name')).toBe(`${YYYYMMDD}00`);
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
describe('multiple serial fields', () => {
|
|
402
|
+
it('2 fields', async () => {
|
|
403
|
+
const testsCollection = db.collection({
|
|
404
|
+
name: 'tests',
|
|
405
|
+
fields: [
|
|
406
|
+
{
|
|
407
|
+
type: 'sequence',
|
|
408
|
+
name: 'name',
|
|
409
|
+
patterns: [
|
|
410
|
+
{ type: 'string', options: { value: 'A' } },
|
|
411
|
+
{ type: 'date' },
|
|
412
|
+
{ type: 'integer', options: { digits: 2, cycle: '0 0 * * *' } }
|
|
413
|
+
]
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
type: 'sequence',
|
|
417
|
+
name: 'code',
|
|
418
|
+
patterns: [
|
|
419
|
+
{ type: 'string', options: { value: 'C' } },
|
|
420
|
+
{ type: 'integer', options: { digits: 4 }}
|
|
421
|
+
]
|
|
422
|
+
}
|
|
423
|
+
]
|
|
424
|
+
});
|
|
425
|
+
await db.sync();
|
|
426
|
+
|
|
427
|
+
const now = new Date();
|
|
428
|
+
const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
|
|
429
|
+
const NOW = moment(now).format('YYYYMMDD');
|
|
430
|
+
const YESTERDAY = moment(yesterday).format('YYYYMMDD');
|
|
431
|
+
|
|
432
|
+
const TestModel = db.getModel('tests');
|
|
433
|
+
const item1 = await TestModel.create({ createdAt: yesterday });
|
|
434
|
+
expect(item1.get('name')).toBe(`A${YESTERDAY}00`);
|
|
435
|
+
expect(item1.get('code')).toBe(`C0000`);
|
|
436
|
+
|
|
437
|
+
const item2 = await TestModel.create();
|
|
438
|
+
expect(item2.get('name')).toBe(`A${NOW}00`);
|
|
439
|
+
expect(item2.get('code')).toBe(`C0001`);
|
|
440
|
+
|
|
441
|
+
testsCollection.setField('name', {
|
|
442
|
+
type: 'sequence',
|
|
443
|
+
patterns: [
|
|
444
|
+
{ type: 'string', options: { value: 'a' } },
|
|
445
|
+
{ type: 'date' },
|
|
446
|
+
{ type: 'integer', options: { digits: 1 } }
|
|
447
|
+
]
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
const item3 = await TestModel.create();
|
|
451
|
+
expect(item3.get('name')).toBe(`a${NOW}0`);
|
|
452
|
+
expect(item3.get('code')).toBe(`C0002`);
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
});
|
|
@@ -12,6 +12,30 @@ describe('magic-attribute-model', () => {
|
|
|
12
12
|
await db.close();
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
+
it('case 0', async () => {
|
|
16
|
+
db.registerModels({ MagicAttributeModel });
|
|
17
|
+
|
|
18
|
+
const Test = db.collection({
|
|
19
|
+
name: 'tests',
|
|
20
|
+
model: 'MagicAttributeModel',
|
|
21
|
+
fields: [
|
|
22
|
+
{ type: 'string', name: 'title' },
|
|
23
|
+
{ type: 'json', name: 'options' },
|
|
24
|
+
],
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
await db.sync();
|
|
28
|
+
|
|
29
|
+
const test = await Test.model.create({
|
|
30
|
+
title: 'aa',
|
|
31
|
+
'x-component-props': { key1: 'val1', arr1: [1, 2, 3], arr2: [4, 5] },
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test.set('x-component-props', { arr2: [1, 2, 3] });
|
|
35
|
+
|
|
36
|
+
expect(test.previous('options')['x-component-props']['arr2']).toEqual([4, 5]);
|
|
37
|
+
});
|
|
38
|
+
|
|
15
39
|
it('case 1', async () => {
|
|
16
40
|
db.registerModels({ MagicAttributeModel });
|
|
17
41
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import Database from '../database';
|
|
2
|
+
import { mockDatabase } from '../mock-database';
|
|
3
|
+
|
|
4
|
+
describe('changedWithAssociations', () => {
|
|
5
|
+
let db: Database;
|
|
6
|
+
|
|
7
|
+
beforeEach(async () => {
|
|
8
|
+
db = mockDatabase();
|
|
9
|
+
await db.clean({ drop: true });
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
afterEach(async () => {
|
|
13
|
+
await db.close();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('changedWithAssociations', async () => {
|
|
17
|
+
db.collection({
|
|
18
|
+
name: 'test',
|
|
19
|
+
fields: [
|
|
20
|
+
{
|
|
21
|
+
type: 'string',
|
|
22
|
+
name: 'n1',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
type: 'string',
|
|
26
|
+
name: 'n2',
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
});
|
|
30
|
+
let changed = [];
|
|
31
|
+
db.on('test.afterCreateWithAssociations', (model, options) => {
|
|
32
|
+
changed = model.changedWithAssociations();
|
|
33
|
+
});
|
|
34
|
+
db.on('test.afterUpdateWithAssociations', (model, options) => {
|
|
35
|
+
changed = model.changedWithAssociations();
|
|
36
|
+
});
|
|
37
|
+
await db.sync();
|
|
38
|
+
const r = db.getRepository('test');
|
|
39
|
+
const m = await r.create({ values: { n1: 'a' } });
|
|
40
|
+
expect(changed.includes('n1')).toBeTruthy();
|
|
41
|
+
expect(m.changedWithAssociations()).toBeFalsy();
|
|
42
|
+
await r.update({ filterByTk: m.id, values: { n1: 'b', n2: 'c' } });
|
|
43
|
+
expect(changed).toEqual(['n1', 'n2']);
|
|
44
|
+
expect(m.changedWithAssociations()).toBeFalsy();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -30,4 +30,16 @@ describe('ne operator', () => {
|
|
|
30
30
|
|
|
31
31
|
expect(results).toEqual(1);
|
|
32
32
|
});
|
|
33
|
+
|
|
34
|
+
it('compare with null', async () => {
|
|
35
|
+
await db.getRepository('tests').create({});
|
|
36
|
+
|
|
37
|
+
const results = await db.getRepository('tests').count({
|
|
38
|
+
filter: {
|
|
39
|
+
'name.$ne': null,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
expect(results).toBe(0);
|
|
44
|
+
});
|
|
33
45
|
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import Database, { BelongsToRepository, Collection, mockDatabase } from '@nocobase/database';
|
|
2
|
+
|
|
3
|
+
describe('appends', () => {
|
|
4
|
+
let db: Database;
|
|
5
|
+
|
|
6
|
+
let User: Collection;
|
|
7
|
+
let Post: Collection;
|
|
8
|
+
|
|
9
|
+
let A1: Collection;
|
|
10
|
+
let A2: Collection;
|
|
11
|
+
|
|
12
|
+
afterEach(async () => {
|
|
13
|
+
await db.close();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
db = mockDatabase();
|
|
18
|
+
|
|
19
|
+
User = db.collection({
|
|
20
|
+
name: 'users',
|
|
21
|
+
fields: [
|
|
22
|
+
{ type: 'string', name: 'name' },
|
|
23
|
+
{ type: 'hasMany', name: 'posts' },
|
|
24
|
+
],
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
Post = db.collection({
|
|
28
|
+
name: 'posts',
|
|
29
|
+
fields: [
|
|
30
|
+
{ type: 'string', name: 'title' },
|
|
31
|
+
{
|
|
32
|
+
type: 'belongsTo',
|
|
33
|
+
name: 'user',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
await db.sync();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should find with appends', async () => {
|
|
42
|
+
await User.repository.create({
|
|
43
|
+
values: {
|
|
44
|
+
name: 'u1',
|
|
45
|
+
posts: [
|
|
46
|
+
{
|
|
47
|
+
title: 'p1',
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const p1 = await Post.repository.findOne({});
|
|
54
|
+
|
|
55
|
+
const repository = new BelongsToRepository(Post, 'user', p1['id']);
|
|
56
|
+
|
|
57
|
+
const user = await repository.findOne({
|
|
58
|
+
appends: ['posts'],
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const data = user.toJSON();
|
|
62
|
+
expect(data['posts'][0]['title']).toEqual('p1');
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -235,6 +235,29 @@ describe('belongs to many', () => {
|
|
|
235
235
|
expect(findFilterResult[0].name).toEqual('t2');
|
|
236
236
|
});
|
|
237
237
|
|
|
238
|
+
test('create with array', async () => {
|
|
239
|
+
const p1 = await Post.repository.create({
|
|
240
|
+
values: {
|
|
241
|
+
title: 'p1',
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
const PostTagRepository = new BelongsToManyRepository(Post, 'tags', p1.id);
|
|
246
|
+
|
|
247
|
+
const results = await PostTagRepository.create({
|
|
248
|
+
values: [
|
|
249
|
+
{
|
|
250
|
+
name: 't1',
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: 't2',
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
expect(results.length).toEqual(2);
|
|
259
|
+
});
|
|
260
|
+
|
|
238
261
|
test('find and count', async () => {
|
|
239
262
|
const p1 = await Post.repository.create({
|
|
240
263
|
values: {
|
|
@@ -203,6 +203,26 @@ describe('has many repository', () => {
|
|
|
203
203
|
expect(post.userId).toEqual(u1.id);
|
|
204
204
|
});
|
|
205
205
|
|
|
206
|
+
test('create with array', async () => {
|
|
207
|
+
const u1 = await User.repository.create({
|
|
208
|
+
values: { name: 'u1' },
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const UserPostRepository = new HasManyRepository(User, 'posts', u1.id);
|
|
212
|
+
const posts = await UserPostRepository.create({
|
|
213
|
+
values: [
|
|
214
|
+
{
|
|
215
|
+
title: 't1',
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
title: 't2',
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
expect(posts.length).toEqual(2);
|
|
224
|
+
});
|
|
225
|
+
|
|
206
226
|
test('update', async () => {
|
|
207
227
|
const u1 = await User.repository.create({
|
|
208
228
|
values: { name: 'u1' },
|