@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.
- package/lib/collection.d.ts +7 -2
- package/lib/collection.js +20 -8
- package/lib/database.d.ts +2 -2
- package/lib/database.js +6 -4
- 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/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 +5 -3
- package/lib/repository.js +40 -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__/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 +11 -7
- 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/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 +37 -10
- package/src/update-associations.ts +41 -53
- 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 =>
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
}));
|
package/lib/repository.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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 =>
|
|
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
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
165
|
-
|
|
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
|
-
|
|
179
|
-
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
|
|
204
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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": "
|
|
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
|
});
|