@nocobase/database 0.7.4-alpha.4 → 0.7.5-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 (97) hide show
  1. package/lib/collection.d.ts +7 -2
  2. package/lib/collection.js +20 -8
  3. package/lib/database.d.ts +2 -2
  4. package/lib/database.js +6 -4
  5. package/lib/decorators/must-have-filter-decorator.d.ts +2 -0
  6. package/lib/decorators/must-have-filter-decorator.js +25 -0
  7. package/lib/{transaction-decorator.d.ts → decorators/transaction-decorator.d.ts} +0 -0
  8. package/lib/{transaction-decorator.js → decorators/transaction-decorator.js} +1 -4
  9. package/lib/errors/identifier-error.d.ts +3 -0
  10. package/lib/errors/identifier-error.js +16 -0
  11. package/lib/fields/belongs-to-field.js +9 -0
  12. package/lib/fields/belongs-to-many-field.js +10 -0
  13. package/lib/fields/date-field.d.ts +1 -1
  14. package/lib/fields/date-field.js +1 -1
  15. package/lib/fields/field.d.ts +1 -1
  16. package/lib/fields/field.js +2 -3
  17. package/lib/fields/formula-field.d.ts +5 -5
  18. package/lib/fields/formula-field.js +123 -110
  19. package/lib/fields/has-many-field.js +9 -0
  20. package/lib/fields/has-one-field.js +9 -0
  21. package/lib/fields/index.d.ts +3 -1
  22. package/lib/fields/index.js +34 -1
  23. package/lib/fields/number-field.d.ts +6 -0
  24. package/lib/fields/number-field.js +10 -1
  25. package/lib/fields/radio-field.d.ts +3 -1
  26. package/lib/fields/radio-field.js +14 -11
  27. package/lib/fields/sequence-field.d.ts +31 -0
  28. package/lib/fields/sequence-field.js +299 -0
  29. package/lib/fields/sort-field.d.ts +4 -4
  30. package/lib/fields/sort-field.js +93 -80
  31. package/lib/filter-parser.js +10 -2
  32. package/lib/index.d.ts +1 -1
  33. package/lib/index.js +7 -0
  34. package/lib/magic-attribute-model.d.ts +1 -0
  35. package/lib/magic-attribute-model.js +207 -6
  36. package/lib/mock-database.js +1 -1
  37. package/lib/operators/array.js +17 -9
  38. package/lib/operators/ne.d.ts +4 -0
  39. package/lib/operators/ne.js +3 -1
  40. package/lib/relation-repository/belongs-to-many-repository.js +6 -0
  41. package/lib/relation-repository/multiple-relation-repository.js +32 -9
  42. package/lib/relation-repository/relation-repository.js +7 -1
  43. package/lib/relation-repository/single-relation-repository.js +28 -0
  44. package/lib/repository.d.ts +5 -3
  45. package/lib/repository.js +40 -9
  46. package/lib/update-associations.js +48 -71
  47. package/lib/utils.d.ts +9 -0
  48. package/lib/utils.js +126 -0
  49. package/package.json +5 -3
  50. package/src/__tests__/collection.test.ts +47 -0
  51. package/src/__tests__/database.test.ts +2 -0
  52. package/src/__tests__/field-options/inddex.test.ts +43 -0
  53. package/src/__tests__/fields/array.test.ts +66 -0
  54. package/src/__tests__/fields/belongs-to-field.test.ts +35 -0
  55. package/src/__tests__/fields/belongs-to-many-field.test.ts +45 -0
  56. package/src/__tests__/fields/has-many-field.test.ts +22 -0
  57. package/src/__tests__/fields/has-one-field.test.ts +21 -0
  58. package/src/__tests__/fields/sequence-field.test.ts +455 -0
  59. package/src/__tests__/magic-attribute-model.test.ts +24 -0
  60. package/src/__tests__/operator/ne.test.ts +12 -0
  61. package/src/__tests__/relation-repository/appends.test.ts +64 -0
  62. package/src/__tests__/relation-repository/belongs-to-many-repository.test.ts +23 -0
  63. package/src/__tests__/relation-repository/has-many-repository.test.ts +20 -0
  64. package/src/__tests__/relation-repository/hasone-repository.test.ts +68 -1
  65. package/src/__tests__/repository/find.test.ts +35 -0
  66. package/src/__tests__/repository/update.test.ts +35 -0
  67. package/src/__tests__/repository.test.ts +15 -0
  68. package/src/collection.ts +28 -13
  69. package/src/database.ts +11 -7
  70. package/src/decorators/must-have-filter-decorator.ts +17 -0
  71. package/src/{transaction-decorator.ts → decorators/transaction-decorator.ts} +1 -2
  72. package/src/errors/identifier-error.ts +6 -0
  73. package/src/fields/belongs-to-field.ts +9 -0
  74. package/src/fields/belongs-to-many-field.ts +15 -0
  75. package/src/fields/date-field.ts +1 -1
  76. package/src/fields/field.ts +3 -3
  77. package/src/fields/formula-field.ts +13 -13
  78. package/src/fields/has-many-field.ts +10 -0
  79. package/src/fields/has-one-field.ts +13 -0
  80. package/src/fields/index.ts +5 -2
  81. package/src/fields/number-field.ts +10 -0
  82. package/src/fields/radio-field.ts +22 -24
  83. package/src/fields/sequence-field.ts +200 -0
  84. package/src/fields/sort-field.ts +9 -9
  85. package/src/filter-parser.ts +6 -5
  86. package/src/index.ts +1 -1
  87. package/src/magic-attribute-model.ts +188 -6
  88. package/src/mock-database.ts +1 -1
  89. package/src/operators/array.ts +17 -10
  90. package/src/operators/ne.ts +10 -6
  91. package/src/relation-repository/belongs-to-many-repository.ts +4 -0
  92. package/src/relation-repository/multiple-relation-repository.ts +26 -11
  93. package/src/relation-repository/relation-repository.ts +5 -1
  94. package/src/relation-repository/single-relation-repository.ts +27 -1
  95. package/src/repository.ts +37 -10
  96. package/src/update-associations.ts +41 -53
  97. package/src/utils.ts +71 -0
@@ -31,6 +31,8 @@ var _updateGuard = require("../update-guard");
31
31
 
32
32
  var _relationRepository = require("./relation-repository");
33
33
 
34
+ var _utils = require("../utils");
35
+
34
36
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
35
37
 
36
38
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -80,15 +82,36 @@ class MultipleRelationRepository extends _relationRepository.RelationRepository
80
82
  attributes: [_this.targetKey()],
81
83
  group: `${_this.targetModel.name}.${_this.targetKey()}`,
82
84
  transaction
83
- }))).map(row => row.get(_this.targetKey()));
84
- return yield sourceModel[getAccessor](_objectSpread(_objectSpread({}, (0, _lodash().omit)(findOptions, ['limit', 'offset'])), {}, {
85
- where: {
86
- [_this.targetKey()]: {
87
- [_sequelize().Op.in]: ids
88
- }
89
- },
90
- transaction
91
- }));
85
+ }))).map(row => {
86
+ return {
87
+ row,
88
+ pk: row.get(_this.targetKey())
89
+ };
90
+ });
91
+
92
+ if (ids.length == 0) {
93
+ return [];
94
+ }
95
+
96
+ return yield (0, _utils.handleAppendsQuery)({
97
+ templateModel: ids[0].row,
98
+ queryPromises: findOptions.include.map(include => {
99
+ return sourceModel[getAccessor](_objectSpread(_objectSpread({}, (0, _lodash().omit)(findOptions, ['limit', 'offset'])), {}, {
100
+ include: [include],
101
+ where: {
102
+ [_this.targetKey()]: {
103
+ [_sequelize().Op.in]: ids.map(id => id.pk)
104
+ }
105
+ },
106
+ transaction
107
+ })).then(rows => {
108
+ return {
109
+ rows,
110
+ include
111
+ };
112
+ });
113
+ })
114
+ });
92
115
  }
93
116
 
94
117
  return yield sourceModel[getAccessor](_objectSpread(_objectSpread({}, findOptions), {}, {
@@ -19,7 +19,7 @@ var _filterParser = _interopRequireDefault(require("../filter-parser"));
19
19
 
20
20
  var _optionsParser = require("../options-parser");
21
21
 
22
- var _transactionDecorator = require("../transaction-decorator");
22
+ var _transactionDecorator = require("../decorators/transaction-decorator");
23
23
 
24
24
  var _updateAssociations = require("../update-associations");
25
25
 
@@ -87,6 +87,12 @@ class RelationRepository {
87
87
  var _this = this;
88
88
 
89
89
  return _asyncToGenerator(function* () {
90
+ if (Array.isArray(options.values)) {
91
+ return Promise.all(options.values.map(record => _this.create(_objectSpread(_objectSpread({}, options), {}, {
92
+ values: record
93
+ }))));
94
+ }
95
+
90
96
  const createAccessor = _this.accessors().create;
91
97
 
92
98
  const guard = _updateGuard.UpdateGuard.fromOptions(_this.targetModel, options);
@@ -19,6 +19,8 @@ var _updateAssociations = require("../update-associations");
19
19
 
20
20
  var _relationRepository = require("./relation-repository");
21
21
 
22
+ var _utils = require("../utils");
23
+
22
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
25
 
24
26
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
@@ -69,6 +71,8 @@ class SingleRelationRepository extends _relationRepository.RelationRepository {
69
71
  var _this3 = this;
70
72
 
71
73
  return _asyncToGenerator(function* () {
74
+ var _findOptions$include;
75
+
72
76
  const transaction = yield _this3.getTransaction(options);
73
77
 
74
78
  const findOptions = _this3.buildQueryOptions(_objectSpread({}, options));
@@ -76,6 +80,30 @@ class SingleRelationRepository extends _relationRepository.RelationRepository {
76
80
  const getAccessor = _this3.accessors().get;
77
81
 
78
82
  const sourceModel = yield _this3.getSourceModel(transaction);
83
+
84
+ if ((findOptions === null || findOptions === void 0 ? void 0 : (_findOptions$include = findOptions.include) === null || _findOptions$include === void 0 ? void 0 : _findOptions$include.length) > 0) {
85
+ const templateModel = yield sourceModel[getAccessor](_objectSpread(_objectSpread({}, findOptions), {}, {
86
+ includeIgnoreAttributes: false,
87
+ transaction,
88
+ attributes: [_this3.targetKey()],
89
+ group: `${_this3.targetModel.name}.${_this3.targetKey()}`
90
+ }));
91
+ const results = yield (0, _utils.handleAppendsQuery)({
92
+ templateModel,
93
+ queryPromises: findOptions.include.map(include => {
94
+ return sourceModel[getAccessor](_objectSpread(_objectSpread({}, findOptions), {}, {
95
+ include: [include]
96
+ })).then(row => {
97
+ return {
98
+ rows: [row],
99
+ include
100
+ };
101
+ });
102
+ })
103
+ });
104
+ return results[0];
105
+ }
106
+
79
107
  return yield sourceModel[getAccessor](_objectSpread(_objectSpread({}, findOptions), {}, {
80
108
  transaction
81
109
  }));
@@ -60,7 +60,7 @@ interface FindAndCountOptions extends Omit<SequelizeAndCountOptions, 'where' | '
60
60
  sort?: Sort;
61
61
  }
62
62
  export interface CreateOptions extends SequelizeCreateOptions {
63
- values?: Values;
63
+ values?: Values | Values[];
64
64
  whitelist?: WhiteList;
65
65
  blacklist?: BlackList;
66
66
  updateAssociationValues?: AssociationKeysToBeUpdate;
@@ -130,7 +130,7 @@ export declare class Repository<TModelAttributes extends {} = any, TCreationAttr
130
130
  * @param values
131
131
  * @param options
132
132
  */
133
- create<M extends Model>(options: CreateOptions): Promise<M>;
133
+ create(options: CreateOptions): Promise<any>;
134
134
  /**
135
135
  * Save Many instances to database
136
136
  *
@@ -144,7 +144,9 @@ export declare class Repository<TModelAttributes extends {} = any, TCreationAttr
144
144
  * @param values
145
145
  * @param options
146
146
  */
147
- update(options: UpdateOptions): Promise<Model<any, any>[]>;
147
+ update(options: UpdateOptions & {
148
+ forceUpdate?: boolean;
149
+ }): Promise<Model<any, any>[]>;
148
150
  destroy(options?: TargetKey | TargetKey[] | DestroyOptions): any;
149
151
  /**
150
152
  * @param association target association
package/lib/repository.js CHANGED
@@ -25,6 +25,10 @@ function _sequelize() {
25
25
  return data;
26
26
  }
27
27
 
28
+ var _mustHaveFilterDecorator = _interopRequireDefault(require("./decorators/must-have-filter-decorator"));
29
+
30
+ var _transactionDecorator = require("./decorators/transaction-decorator");
31
+
28
32
  var _filterParser = _interopRequireDefault(require("./filter-parser"));
29
33
 
30
34
  var _optionsParser = require("./options-parser");
@@ -37,12 +41,12 @@ var _hasmanyRepository = require("./relation-repository/hasmany-repository");
37
41
 
38
42
  var _hasoneRepository = require("./relation-repository/hasone-repository");
39
43
 
40
- var _transactionDecorator = require("./transaction-decorator");
41
-
42
44
  var _updateAssociations = require("./update-associations");
43
45
 
44
46
  var _updateGuard = require("./update-guard");
45
47
 
48
+ var _utils = require("./utils");
49
+
46
50
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
47
51
 
48
52
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -163,16 +167,37 @@ class Repository {
163
167
  attributes: [primaryKeyField],
164
168
  group: `${model.name}.${primaryKeyField}`,
165
169
  transaction
166
- }))).map(row => row.get(primaryKeyField));
170
+ }))).map(row => {
171
+ return {
172
+ row,
173
+ pk: row.get(primaryKeyField)
174
+ };
175
+ });
176
+
177
+ if (ids.length == 0) {
178
+ return [];
179
+ }
180
+
167
181
  const where = {
168
182
  [primaryKeyField]: {
169
- [_sequelize().Op.in]: ids
183
+ [_sequelize().Op.in]: ids.map(id => id['pk'])
170
184
  }
171
185
  };
172
- return yield model.findAll(_objectSpread(_objectSpread({}, (0, _lodash().omit)(opts, ['limit', 'offset'])), {}, {
173
- where,
174
- transaction
175
- }));
186
+ return yield (0, _utils.handleAppendsQuery)({
187
+ queryPromises: opts.include.map(include => {
188
+ return model.findAll(_objectSpread(_objectSpread({}, (0, _lodash().omit)(opts, ['limit', 'offset'])), {}, {
189
+ include: include,
190
+ where,
191
+ transaction
192
+ })).then(rows => {
193
+ return {
194
+ rows,
195
+ include
196
+ };
197
+ });
198
+ }),
199
+ templateModel: ids[0].row
200
+ });
176
201
  }
177
202
 
178
203
  return yield model.findAll(_objectSpread(_objectSpread({}, opts), {}, {
@@ -237,6 +262,12 @@ class Repository {
237
262
  var _this5 = this;
238
263
 
239
264
  return _asyncToGenerator(function* () {
265
+ if (Array.isArray(options.values)) {
266
+ return _this5.createMany(_objectSpread(_objectSpread({}, options), {}, {
267
+ records: options.values
268
+ }));
269
+ }
270
+
240
271
  const transaction = yield _this5.getTransaction(options);
241
272
 
242
273
  const guard = _updateGuard.UpdateGuard.fromOptions(_this5.model, _objectSpread(_objectSpread({}, options), {}, {
@@ -474,7 +505,7 @@ __decorate([transaction()], Repository.prototype, "create", null);
474
505
 
475
506
  __decorate([transaction()], Repository.prototype, "createMany", null);
476
507
 
477
- __decorate([transaction()], Repository.prototype, "update", null);
508
+ __decorate([transaction(), (0, _mustHaveFilterDecorator.default)()], Repository.prototype, "update", null);
478
509
 
479
510
  __decorate([transaction((args, transaction) => {
480
511
  return {
@@ -161,47 +161,55 @@ function _updateAssociations() {
161
161
 
162
162
  const keys = Object.keys(values);
163
163
 
164
- for (var _i2 = 0, _Object$keys = Object.keys(modelAssociations(instance)); _i2 < _Object$keys.length; _i2++) {
165
- const key = _Object$keys[_i2];
166
-
167
- if (keys.includes(key)) {
168
- yield updateAssociation(instance, key, values[key], _objectSpread(_objectSpread({}, options), {}, {
169
- transaction
170
- }));
171
- }
172
- } // update through table values
164
+ try {
165
+ for (var _i2 = 0, _Object$keys = Object.keys(modelAssociations(instance)); _i2 < _Object$keys.length; _i2++) {
166
+ const key = _Object$keys[_i2];
173
167
 
168
+ if (keys.includes(key)) {
169
+ yield updateAssociation(instance, key, values[key], _objectSpread(_objectSpread({}, options), {}, {
170
+ transaction
171
+ }));
172
+ }
173
+ } // update through table values
174
174
 
175
- var _iterator2 = _createForOfIteratorHelper(belongsToManyAssociations(instance)),
176
- _step2;
177
175
 
178
- try {
179
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
180
- const belongsToMany = _step2.value;
181
- // @ts-ignore
182
- const throughModel = belongsToMany.through.model;
183
- const throughModelName = throughModel.name;
176
+ var _iterator2 = _createForOfIteratorHelper(belongsToManyAssociations(instance)),
177
+ _step2;
184
178
 
185
- if (values[throughModelName] && options.sourceModel) {
186
- const where = {
187
- [belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),
188
- [belongsToMany.otherKey]: options.sourceModel.get(belongsToMany.targetKey)
189
- };
190
- yield throughModel.update(values[throughModel.name], {
191
- where,
192
- context: options.context,
193
- transaction
194
- });
179
+ try {
180
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
181
+ const belongsToMany = _step2.value;
182
+ // @ts-ignore
183
+ const throughModel = belongsToMany.through.model;
184
+ const throughModelName = throughModel.name;
185
+
186
+ if (values[throughModelName] && options.sourceModel) {
187
+ const where = {
188
+ [belongsToMany.foreignKey]: instance.get(belongsToMany.sourceKey),
189
+ [belongsToMany.otherKey]: options.sourceModel.get(belongsToMany.targetKey)
190
+ };
191
+ yield throughModel.update(values[throughModel.name], {
192
+ where,
193
+ context: options.context,
194
+ transaction
195
+ });
196
+ }
195
197
  }
198
+ } catch (err) {
199
+ _iterator2.e(err);
200
+ } finally {
201
+ _iterator2.f();
196
202
  }
197
- } catch (err) {
198
- _iterator2.e(err);
199
- } finally {
200
- _iterator2.f();
201
- }
202
203
 
203
- if (newTransaction) {
204
- yield transaction.commit();
204
+ if (newTransaction) {
205
+ yield transaction.commit();
206
+ }
207
+ } catch (error) {
208
+ if (newTransaction) {
209
+ yield transaction.rollback();
210
+ }
211
+
212
+ throw error;
205
213
  }
206
214
  });
207
215
  return _updateAssociations.apply(this, arguments);
@@ -294,11 +302,14 @@ function _updateSingleAssociation() {
294
302
  return false;
295
303
  }
296
304
 
305
+ if (Array.isArray(value)) {
306
+ throw new Error(`The value of '${key}' cannot be in array format`);
307
+ }
308
+
297
309
  const context = options.context,
298
310
  _options$updateAssoci = options.updateAssociationValues,
299
311
  updateAssociationValues = _options$updateAssoci === void 0 ? [] : _options$updateAssoci,
300
- _options$transaction = options.transaction,
301
- transaction = _options$transaction === void 0 ? yield model.sequelize.transaction() : _options$transaction;
312
+ transaction = options.transaction;
302
313
  const keys = getKeysByPrefix(updateAssociationValues, key);
303
314
 
304
315
  try {
@@ -311,11 +322,6 @@ function _updateSingleAssociation() {
311
322
  transaction
312
323
  });
313
324
  model.setDataValue(key, null);
314
-
315
- if (!options.transaction) {
316
- yield transaction.commit();
317
- }
318
-
319
325
  return true;
320
326
  });
321
327
 
@@ -333,11 +339,6 @@ function _updateSingleAssociation() {
333
339
  context,
334
340
  transaction
335
341
  });
336
-
337
- if (!options.transaction) {
338
- yield transaction.commit();
339
- }
340
-
341
342
  return true;
342
343
  }
343
344
 
@@ -347,11 +348,6 @@ function _updateSingleAssociation() {
347
348
  transaction
348
349
  });
349
350
  model.setDataValue(key, value);
350
-
351
- if (!options.transaction) {
352
- yield transaction.commit();
353
- }
354
-
355
351
  return true;
356
352
  }
357
353
 
@@ -394,11 +390,6 @@ function _updateSingleAssociation() {
394
390
  updateAssociationValues: keys
395
391
  }));
396
392
  model.setDataValue(key, instance);
397
-
398
- if (!options.transaction) {
399
- yield transaction.commit();
400
- }
401
-
402
393
  return true;
403
394
  }
404
395
  }
@@ -417,15 +408,7 @@ function _updateSingleAssociation() {
417
408
  if (association.targetKey) {
418
409
  model.setDataValue(association.foreignKey, instance[dataKey]);
419
410
  }
420
-
421
- if (!options.transaction) {
422
- yield transaction.commit();
423
- }
424
411
  } catch (error) {
425
- if (!options.transaction) {
426
- yield transaction.rollback();
427
- }
428
-
429
412
  throw error;
430
413
  }
431
414
  });
@@ -451,8 +434,7 @@ function _updateMultipleAssociation() {
451
434
  const context = options.context,
452
435
  _options$updateAssoci2 = options.updateAssociationValues,
453
436
  updateAssociationValues = _options$updateAssoci2 === void 0 ? [] : _options$updateAssoci2,
454
- _options$transaction2 = options.transaction,
455
- transaction = _options$transaction2 === void 0 ? yield model.sequelize.transaction() : _options$transaction2;
437
+ transaction = options.transaction;
456
438
  const keys = getKeysByPrefix(updateAssociationValues, key);
457
439
 
458
440
  try {
@@ -565,12 +547,7 @@ function _updateMultipleAssociation() {
565
547
  }
566
548
 
567
549
  model.setDataValue(key, list1.concat(list3));
568
-
569
- if (!options.transaction) {
570
- yield transaction.commit();
571
- }
572
550
  } catch (error) {
573
- yield transaction.rollback();
574
551
  throw error;
575
552
  }
576
553
  });
package/lib/utils.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { Model } from './model';
2
+ declare type HandleAppendsQueryOptions = {
3
+ templateModel: any;
4
+ queryPromises: Array<any>;
5
+ };
6
+ export declare function handleAppendsQuery(options: HandleAppendsQueryOptions): Promise<Model<any, any>[]>;
7
+ export declare function md5(value: string): string;
8
+ export declare function checkIdentifier(value: string): void;
9
+ export {};
package/lib/utils.js ADDED
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.checkIdentifier = checkIdentifier;
7
+ exports.handleAppendsQuery = handleAppendsQuery;
8
+ exports.md5 = md5;
9
+
10
+ function _crypto() {
11
+ const data = _interopRequireDefault(require("crypto"));
12
+
13
+ _crypto = function _crypto() {
14
+ return data;
15
+ };
16
+
17
+ return data;
18
+ }
19
+
20
+ var _identifierError = require("./errors/identifier-error");
21
+
22
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
+
24
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
25
+
26
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
27
+
28
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
29
+
30
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
31
+
32
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
33
+
34
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
35
+
36
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
37
+
38
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
39
+
40
+ function handleAppendsQuery(_x) {
41
+ return _handleAppendsQuery.apply(this, arguments);
42
+ }
43
+
44
+ function _handleAppendsQuery() {
45
+ _handleAppendsQuery = _asyncToGenerator(function* (options) {
46
+ const templateModel = options.templateModel,
47
+ queryPromises = options.queryPromises;
48
+ const primaryKey = templateModel.constructor.primaryKeyAttribute;
49
+ const results = yield Promise.all(queryPromises);
50
+ let rows;
51
+
52
+ var _iterator = _createForOfIteratorHelper(results),
53
+ _step;
54
+
55
+ try {
56
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
57
+ const appendedResult = _step.value;
58
+
59
+ if (!rows) {
60
+ rows = appendedResult.rows;
61
+
62
+ if (rows.length == 0) {
63
+ return [];
64
+ }
65
+
66
+ const modelOptions = templateModel['_options'];
67
+
68
+ var _iterator2 = _createForOfIteratorHelper(rows),
69
+ _step2;
70
+
71
+ try {
72
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
73
+ const row = _step2.value;
74
+ row['_options'] = _objectSpread(_objectSpread({}, row['_options']), {}, {
75
+ include: modelOptions['include'],
76
+ includeNames: modelOptions['includeNames'],
77
+ includeMap: modelOptions['includeMap']
78
+ });
79
+ }
80
+ } catch (err) {
81
+ _iterator2.e(err);
82
+ } finally {
83
+ _iterator2.f();
84
+ }
85
+
86
+ continue;
87
+ }
88
+
89
+ for (let i = 0; i < appendedResult.rows.length; i++) {
90
+ const appendingRow = appendedResult.rows[i];
91
+ const key = appendedResult.include.association;
92
+ const val = appendingRow.get(key);
93
+ const rowKey = appendingRow.get(primaryKey);
94
+ const targetIndex = rows.findIndex(row => row.get(primaryKey) === rowKey);
95
+
96
+ if (targetIndex === -1) {
97
+ throw new Error('target row not found');
98
+ }
99
+
100
+ rows[targetIndex].set(key, val, {
101
+ raw: true
102
+ });
103
+ }
104
+ }
105
+ } catch (err) {
106
+ _iterator.e(err);
107
+ } finally {
108
+ _iterator.f();
109
+ }
110
+
111
+ return rows;
112
+ });
113
+ return _handleAppendsQuery.apply(this, arguments);
114
+ }
115
+
116
+ function md5(value) {
117
+ return _crypto().default.createHash('md5').update(value).digest('hex');
118
+ }
119
+
120
+ const MAX_IDENTIFIER_LENGTH = 63;
121
+
122
+ function checkIdentifier(value) {
123
+ if (value.length > MAX_IDENTIFIER_LENGTH) {
124
+ throw new _identifierError.IdentifierError(`Identifier ${value} is too long`);
125
+ }
126
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/database",
3
- "version": "0.7.4-alpha.4",
3
+ "version": "0.7.5-alpha.1",
4
4
  "description": "",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -12,12 +12,14 @@
12
12
  }
13
13
  ],
14
14
  "dependencies": {
15
- "@nocobase/utils": "0.7.4-alpha.4",
15
+ "@nocobase/utils": "0.7.5-alpha.1",
16
16
  "async-mutex": "^0.3.2",
17
+ "cron-parser": "4.4.0",
17
18
  "deepmerge": "^4.2.2",
18
19
  "flat": "^5.0.2",
19
20
  "glob": "^7.1.6",
20
21
  "mathjs": "^10.6.1",
22
+ "moment": "2.x",
21
23
  "semver": "^7.3.7",
22
24
  "sequelize": "^6.9.0",
23
25
  "umzug": "^3.1.1"
@@ -30,5 +32,5 @@
30
32
  "url": "git+https://github.com/nocobase/nocobase.git",
31
33
  "directory": "packages/database"
32
34
  },
33
- "gitHead": "726c06b721b217a6aa5c1421b899d1315e552b57"
35
+ "gitHead": "f6eb27b68185bb0c0b4c2cfca1df84205a9b9173"
34
36
  }
@@ -1,6 +1,7 @@
1
1
  import { Collection } from '../collection';
2
2
  import { Database } from '../database';
3
3
  import { mockDatabase } from './index';
4
+ import { IdentifierError } from '../errors/identifier-error';
4
5
 
5
6
  describe('collection', () => {
6
7
  let db: Database;
@@ -258,4 +259,50 @@ describe('collection sync', () => {
258
259
  expect(tableFields['postId']).toBeDefined();
259
260
  expect(tableFields['tagId']).toBeDefined();
260
261
  });
262
+
263
+ test('limit table name length', async () => {
264
+ const longName =
265
+ 'this_is_a_very_long_table_name_that_should_be_truncated_this_is_a_very_long_table_name_that_should_be_truncated';
266
+
267
+ let error;
268
+
269
+ try {
270
+ const collection = new Collection(
271
+ {
272
+ name: longName,
273
+ fields: [{ type: 'string', name: 'test' }],
274
+ },
275
+ {
276
+ database: db,
277
+ },
278
+ );
279
+ } catch (e) {
280
+ error = e;
281
+ }
282
+
283
+ expect(error).toBeInstanceOf(IdentifierError);
284
+ });
285
+
286
+ test('limit field name length', async () => {
287
+ const longFieldName =
288
+ 'this_is_a_very_long_field_name_that_should_be_truncated_this_is_a_very_long_field_name_that_should_be_truncated';
289
+
290
+ let error;
291
+
292
+ try {
293
+ const collection = new Collection(
294
+ {
295
+ name: 'test',
296
+ fields: [{ type: 'string', name: longFieldName }],
297
+ },
298
+ {
299
+ database: db,
300
+ },
301
+ );
302
+ } catch (e) {
303
+ error = e;
304
+ }
305
+
306
+ expect(error).toBeInstanceOf(IdentifierError);
307
+ });
261
308
  });
@@ -268,8 +268,10 @@ describe('database', () => {
268
268
  });
269
269
 
270
270
  await Test.sync();
271
+ expect(Test.model.prototype).toBeInstanceOf(CustomModel);
271
272
 
272
273
  const test = await Test.model.create<any>();
274
+ expect(test).toBeInstanceOf(CustomModel);
273
275
  test.customMethod();
274
276
  expect(test.get('abc')).toBe('abc');
275
277
  });