@nocobase/database 0.8.0-alpha.8 → 0.8.1-alpha.3
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 -3
- package/lib/collection.js +126 -22
- package/lib/database.d.ts +13 -7
- package/lib/database.js +39 -8
- package/lib/decorators/must-have-filter-decorator.js +4 -0
- package/lib/decorators/transaction-decorator.js +1 -0
- package/lib/features/ReferencesMap.js +14 -9
- package/lib/field-repository/array-field-repository.d.ts +28 -0
- package/lib/field-repository/array-field-repository.js +208 -0
- package/lib/fields/array-field.d.ts +1 -1
- package/lib/fields/array-field.js +15 -11
- package/lib/fields/belongs-to-field.d.ts +9 -1
- package/lib/fields/belongs-to-field.js +21 -7
- package/lib/fields/belongs-to-many-field.d.ts +4 -0
- package/lib/fields/belongs-to-many-field.js +24 -0
- package/lib/fields/field.d.ts +3 -2
- package/lib/fields/field.js +19 -13
- package/lib/fields/has-many-field.d.ts +2 -1
- package/lib/fields/has-many-field.js +18 -10
- package/lib/fields/has-one-field.d.ts +1 -0
- package/lib/fields/has-one-field.js +22 -10
- package/lib/fields/index.d.ts +3 -3
- package/lib/fields/index.js +14 -34
- package/lib/fields/relation-field.d.ts +2 -1
- package/lib/fields/relation-field.js +16 -0
- package/lib/fields/set-field.d.ts +10 -0
- package/lib/fields/set-field.js +35 -0
- package/lib/fields/sort-field.d.ts +1 -1
- package/lib/fields/sort-field.js +1 -1
- package/lib/filter-match.d.ts +1 -0
- package/lib/filter-match.js +84 -0
- package/lib/filter-parser.d.ts +2 -2
- package/lib/index.d.ts +5 -1
- package/lib/index.js +56 -0
- package/lib/inherited-collection.d.ts +13 -0
- package/lib/inherited-collection.js +210 -0
- package/lib/inherited-map.d.ts +21 -0
- package/lib/inherited-map.js +203 -0
- package/lib/model-hook.d.ts +1 -1
- package/lib/model.d.ts +1 -0
- package/lib/model.js +47 -0
- package/lib/operators/array.d.ts +1 -25
- package/lib/operators/association.d.ts +1 -9
- package/lib/operators/boolean.d.ts +1 -12
- package/lib/operators/date.d.ts +1 -33
- package/lib/operators/empty.d.ts +2 -25
- package/lib/operators/ne.d.ts +1 -13
- package/lib/operators/notIn.d.ts +1 -9
- package/lib/options-parser.d.ts +3 -2
- package/lib/options-parser.js +16 -1
- package/lib/relation-repository/relation-repository.d.ts +2 -2
- package/lib/relation-repository/single-relation-repository.js +2 -2
- package/lib/repository.d.ts +18 -10
- package/lib/repository.js +172 -38
- package/lib/sync-runner.d.ts +4 -0
- package/lib/sync-runner.js +181 -0
- package/lib/types.d.ts +2 -2
- package/lib/update-associations.d.ts +1 -0
- package/lib/update-associations.js +21 -2
- package/lib/update-guard.d.ts +3 -3
- package/lib/utils.js +5 -0
- package/package.json +4 -4
- package/src/__tests__/bigint.test.ts +48 -0
- package/src/__tests__/collection.test.ts +48 -13
- package/src/__tests__/database.test.ts +10 -0
- package/src/__tests__/field-repository/array-field-repository.test.ts +94 -0
- package/src/__tests__/fields/set.test.ts +37 -0
- package/src/__tests__/filter-match.test.ts +52 -0
- package/src/__tests__/inhertits/collection-inherits-sync.test.ts +38 -0
- package/src/__tests__/inhertits/collection-inherits.test.ts +994 -0
- package/src/__tests__/inhertits/helper.ts +3 -0
- package/src/__tests__/inhertits/inherited-map.test.ts +27 -0
- package/src/__tests__/relation-repository/belongs-to-many-repository.test.ts +2 -0
- package/src/__tests__/relation-repository/has-many-repository.test.ts +1 -1
- package/src/__tests__/repository/destroy.test.ts +122 -1
- package/src/__tests__/repository/update-many.test.ts +57 -0
- package/src/__tests__/update-association-values.test.ts +232 -0
- package/src/__tests__/update-associations.test.ts +6 -1
- package/src/collection.ts +90 -8
- package/src/database.ts +53 -14
- package/src/decorators/must-have-filter-decorator.ts +4 -0
- package/src/decorators/transaction-decorator.ts +1 -0
- package/src/features/ReferencesMap.ts +20 -9
- package/src/features/referential-integrity-check.ts +1 -0
- package/src/field-repository/array-field-repository.ts +155 -0
- package/src/fields/array-field.ts +4 -4
- package/src/fields/belongs-to-field.ts +26 -10
- package/src/fields/belongs-to-many-field.ts +34 -0
- package/src/fields/field.ts +26 -13
- package/src/fields/has-many-field.ts +17 -9
- package/src/fields/has-one-field.ts +23 -9
- package/src/fields/index.ts +5 -5
- package/src/fields/relation-field.ts +16 -0
- package/src/fields/set-field.ts +25 -0
- package/src/fields/sort-field.ts +5 -4
- package/src/filter-match.ts +49 -0
- package/src/filter-parser.ts +2 -2
- package/src/index.ts +5 -2
- package/src/inherited-collection.ts +112 -0
- package/src/inherited-map.ts +97 -0
- package/src/model-hook.ts +2 -3
- package/src/model.ts +43 -3
- package/src/operators/array.ts +1 -1
- package/src/operators/association.ts +1 -1
- package/src/operators/boolean.ts +1 -1
- package/src/operators/date.ts +1 -1
- package/src/operators/empty.ts +1 -1
- package/src/operators/ne.ts +1 -1
- package/src/operators/notIn.ts +2 -1
- package/src/options-parser.ts +20 -4
- package/src/relation-repository/relation-repository.ts +2 -2
- package/src/relation-repository/single-relation-repository.ts +2 -2
- package/src/repository.ts +144 -30
- package/src/sync-runner.ts +162 -0
- package/src/types.ts +2 -2
- package/src/update-associations.ts +23 -7
- package/src/update-guard.ts +3 -3
- package/src/utils.ts +5 -1
- package/lib/fields/sequence-field.d.ts +0 -31
- package/lib/fields/sequence-field.js +0 -299
- package/src/__tests__/fields/sequence-field.test.ts +0 -455
- package/src/fields/sequence-field.ts +0 -200
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ArrayFieldRepository = void 0;
|
|
7
|
+
|
|
8
|
+
function _lodash() {
|
|
9
|
+
const data = _interopRequireDefault(require("lodash"));
|
|
10
|
+
|
|
11
|
+
_lodash = function _lodash() {
|
|
12
|
+
return data;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
var _transactionDecorator = require("../decorators/transaction-decorator");
|
|
19
|
+
|
|
20
|
+
var _fields = require("../fields");
|
|
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 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); } }
|
|
31
|
+
|
|
32
|
+
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); }); }; }
|
|
33
|
+
|
|
34
|
+
var __decorate = void 0 && (void 0).__decorate || function (decorators, target, key, desc) {
|
|
35
|
+
var c = arguments.length,
|
|
36
|
+
r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
|
|
37
|
+
d;
|
|
38
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
39
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const transaction = (0, _transactionDecorator.transactionWrapperBuilder)(function () {
|
|
43
|
+
return this.collection.model.sequelize.transaction();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
class ArrayFieldRepository {
|
|
47
|
+
constructor(collection, fieldName, targetValue) {
|
|
48
|
+
this.collection = void 0;
|
|
49
|
+
this.fieldName = void 0;
|
|
50
|
+
this.targetValue = void 0;
|
|
51
|
+
this.collection = collection;
|
|
52
|
+
this.fieldName = fieldName;
|
|
53
|
+
this.targetValue = targetValue;
|
|
54
|
+
const field = collection.getField(fieldName);
|
|
55
|
+
|
|
56
|
+
if (!(field instanceof _fields.ArrayField)) {
|
|
57
|
+
throw new Error('Field must be of type Array');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get(options) {
|
|
62
|
+
var _this = this;
|
|
63
|
+
|
|
64
|
+
return _asyncToGenerator(function* () {
|
|
65
|
+
const instance = yield _this.getInstance(options);
|
|
66
|
+
return instance.get(_this.fieldName);
|
|
67
|
+
})();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
find(options) {
|
|
71
|
+
var _this2 = this;
|
|
72
|
+
|
|
73
|
+
return _asyncToGenerator(function* () {
|
|
74
|
+
return yield _this2.get(options);
|
|
75
|
+
})();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
set(options) {
|
|
79
|
+
var _this3 = this;
|
|
80
|
+
|
|
81
|
+
return _asyncToGenerator(function* () {
|
|
82
|
+
const transaction = options.transaction;
|
|
83
|
+
const instance = yield _this3.getInstance({
|
|
84
|
+
transaction
|
|
85
|
+
});
|
|
86
|
+
instance.set(_this3.fieldName, _lodash().default.castArray(options.values));
|
|
87
|
+
yield instance.save({
|
|
88
|
+
transaction
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (options.hooks !== false) {
|
|
92
|
+
yield _this3.emitAfterSave(instance, options);
|
|
93
|
+
}
|
|
94
|
+
})();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
emitAfterSave(instance, options) {
|
|
98
|
+
var _this4 = this;
|
|
99
|
+
|
|
100
|
+
return _asyncToGenerator(function* () {
|
|
101
|
+
yield _this4.collection.db.emitAsync(`${_this4.collection.name}.afterSaveWithAssociations`, instance, _objectSpread({}, options));
|
|
102
|
+
instance.clearChangedWithAssociations();
|
|
103
|
+
})();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
toggle(options) {
|
|
107
|
+
var _this5 = this;
|
|
108
|
+
|
|
109
|
+
return _asyncToGenerator(function* () {
|
|
110
|
+
const transaction = options.transaction;
|
|
111
|
+
const instance = yield _this5.getInstance({
|
|
112
|
+
transaction
|
|
113
|
+
});
|
|
114
|
+
const oldValue = instance.get(_this5.fieldName) || [];
|
|
115
|
+
const newValue = oldValue.includes(options.value) ? _lodash().default.without(oldValue, options.value) : [...oldValue, options.value];
|
|
116
|
+
instance.set(_this5.fieldName, newValue);
|
|
117
|
+
yield instance.save({
|
|
118
|
+
transaction
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
if (options.hooks !== false) {
|
|
122
|
+
yield _this5.emitAfterSave(instance, options);
|
|
123
|
+
}
|
|
124
|
+
})();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
add(options) {
|
|
128
|
+
var _this6 = this;
|
|
129
|
+
|
|
130
|
+
return _asyncToGenerator(function* () {
|
|
131
|
+
const transaction = options.transaction;
|
|
132
|
+
const instance = yield _this6.getInstance({
|
|
133
|
+
transaction
|
|
134
|
+
});
|
|
135
|
+
const oldValue = instance.get(_this6.fieldName) || [];
|
|
136
|
+
const newValue = [...oldValue, ..._lodash().default.castArray(options.values)];
|
|
137
|
+
instance.set(_this6.fieldName, newValue);
|
|
138
|
+
yield instance.save({
|
|
139
|
+
transaction
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
if (options.hooks !== false) {
|
|
143
|
+
yield _this6.emitAfterSave(instance, options);
|
|
144
|
+
}
|
|
145
|
+
})();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
remove(options) {
|
|
149
|
+
var _this7 = this;
|
|
150
|
+
|
|
151
|
+
return _asyncToGenerator(function* () {
|
|
152
|
+
const transaction = options.transaction;
|
|
153
|
+
const instance = yield _this7.getInstance({
|
|
154
|
+
transaction
|
|
155
|
+
});
|
|
156
|
+
const oldValue = instance.get(_this7.fieldName) || [];
|
|
157
|
+
instance.set(_this7.fieldName, _lodash().default.without(oldValue, ..._lodash().default.castArray(options.values)));
|
|
158
|
+
yield instance.save({
|
|
159
|
+
transaction
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
if (options.hooks !== false) {
|
|
163
|
+
yield _this7.emitAfterSave(instance, options);
|
|
164
|
+
}
|
|
165
|
+
})();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
getInstance(options) {
|
|
169
|
+
return this.collection.repository.findOne({
|
|
170
|
+
filterByTk: this.targetValue
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
exports.ArrayFieldRepository = ArrayFieldRepository;
|
|
177
|
+
|
|
178
|
+
__decorate([transaction()], ArrayFieldRepository.prototype, "get", null);
|
|
179
|
+
|
|
180
|
+
__decorate([transaction()], ArrayFieldRepository.prototype, "find", null);
|
|
181
|
+
|
|
182
|
+
__decorate([transaction((args, transaction) => {
|
|
183
|
+
return {
|
|
184
|
+
values: args[0],
|
|
185
|
+
transaction
|
|
186
|
+
};
|
|
187
|
+
})], ArrayFieldRepository.prototype, "set", null);
|
|
188
|
+
|
|
189
|
+
__decorate([transaction((args, transaction) => {
|
|
190
|
+
return {
|
|
191
|
+
value: args[0],
|
|
192
|
+
transaction
|
|
193
|
+
};
|
|
194
|
+
})], ArrayFieldRepository.prototype, "toggle", null);
|
|
195
|
+
|
|
196
|
+
__decorate([transaction((args, transaction) => {
|
|
197
|
+
return {
|
|
198
|
+
values: args[0],
|
|
199
|
+
transaction
|
|
200
|
+
};
|
|
201
|
+
})], ArrayFieldRepository.prototype, "add", null);
|
|
202
|
+
|
|
203
|
+
__decorate([transaction((args, transaction) => {
|
|
204
|
+
return {
|
|
205
|
+
values: args[0],
|
|
206
|
+
transaction
|
|
207
|
+
};
|
|
208
|
+
})], ArrayFieldRepository.prototype, "remove", null);
|
|
@@ -2,7 +2,7 @@ import { BaseColumnFieldOptions, Field } from './field';
|
|
|
2
2
|
import { DataTypes } from 'sequelize';
|
|
3
3
|
export declare class ArrayField extends Field {
|
|
4
4
|
get dataType(): DataTypes.AbstractDataTypeConstructor;
|
|
5
|
-
sortValue(model: any)
|
|
5
|
+
sortValue: (model: any) => void;
|
|
6
6
|
bind(): void;
|
|
7
7
|
unbind(): void;
|
|
8
8
|
}
|
|
@@ -18,6 +18,19 @@ function _sequelize() {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
class ArrayField extends _field.Field {
|
|
21
|
+
constructor(...args) {
|
|
22
|
+
super(...args);
|
|
23
|
+
|
|
24
|
+
this.sortValue = model => {
|
|
25
|
+
const oldValue = model.get(this.options.name);
|
|
26
|
+
|
|
27
|
+
if (oldValue) {
|
|
28
|
+
const newValue = oldValue.sort();
|
|
29
|
+
model.set(this.options.name, newValue);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
21
34
|
get dataType() {
|
|
22
35
|
if (this.database.sequelize.getDialect() === 'postgres') {
|
|
23
36
|
return _sequelize().DataTypes.JSONB;
|
|
@@ -26,23 +39,14 @@ class ArrayField extends _field.Field {
|
|
|
26
39
|
return _sequelize().DataTypes.JSON;
|
|
27
40
|
}
|
|
28
41
|
|
|
29
|
-
sortValue(model) {
|
|
30
|
-
const oldValue = model.get(this.options.name);
|
|
31
|
-
|
|
32
|
-
if (oldValue) {
|
|
33
|
-
const newValue = oldValue.sort();
|
|
34
|
-
model.set(this.options.name, newValue);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
42
|
bind() {
|
|
39
43
|
super.bind();
|
|
40
|
-
this.on('beforeSave', this.sortValue
|
|
44
|
+
this.on('beforeSave', this.sortValue);
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
unbind() {
|
|
44
48
|
super.unbind();
|
|
45
|
-
this.off('beforeSave', this.sortValue
|
|
49
|
+
this.off('beforeSave', this.sortValue);
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
}
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { BelongsToOptions as SequelizeBelongsToOptions } from 'sequelize';
|
|
2
|
-
import { BaseRelationFieldOptions, RelationField } from './relation-field';
|
|
3
2
|
import { Reference } from '../features/ReferencesMap';
|
|
3
|
+
import { BaseRelationFieldOptions, RelationField } from './relation-field';
|
|
4
4
|
export declare class BelongsToField extends RelationField {
|
|
5
|
+
get dataType(): string;
|
|
5
6
|
static type: string;
|
|
6
7
|
get target(): any;
|
|
8
|
+
static toReference(db: any, association: any, onDelete: any): {
|
|
9
|
+
sourceCollectionName: any;
|
|
10
|
+
sourceField: any;
|
|
11
|
+
targetField: any;
|
|
12
|
+
targetCollectionName: any;
|
|
13
|
+
onDelete: any;
|
|
14
|
+
};
|
|
7
15
|
reference(association: any): Reference;
|
|
8
16
|
bind(): boolean;
|
|
9
17
|
unbind(): void;
|
|
@@ -36,6 +36,10 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
36
36
|
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; }
|
|
37
37
|
|
|
38
38
|
class BelongsToField extends _relationField.RelationField {
|
|
39
|
+
get dataType() {
|
|
40
|
+
return 'BelongsTo';
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
get target() {
|
|
40
44
|
const _this$options = this.options,
|
|
41
45
|
target = _this$options.target,
|
|
@@ -43,17 +47,21 @@ class BelongsToField extends _relationField.RelationField {
|
|
|
43
47
|
return target || _sequelize().Utils.pluralize(name);
|
|
44
48
|
}
|
|
45
49
|
|
|
46
|
-
|
|
50
|
+
static toReference(db, association, onDelete) {
|
|
47
51
|
const targetKey = association.targetKey;
|
|
48
52
|
return {
|
|
49
|
-
sourceCollectionName:
|
|
53
|
+
sourceCollectionName: db.modelCollection.get(association.source).name,
|
|
50
54
|
sourceField: association.foreignKey,
|
|
51
55
|
targetField: targetKey,
|
|
52
|
-
targetCollectionName:
|
|
53
|
-
onDelete:
|
|
56
|
+
targetCollectionName: db.modelCollection.get(association.target).name,
|
|
57
|
+
onDelete: onDelete
|
|
54
58
|
};
|
|
55
59
|
}
|
|
56
60
|
|
|
61
|
+
reference(association) {
|
|
62
|
+
return BelongsToField.toReference(this.database, association, this.options.onDelete);
|
|
63
|
+
}
|
|
64
|
+
|
|
57
65
|
bind() {
|
|
58
66
|
const _this$context = this.context,
|
|
59
67
|
database = _this$context.database,
|
|
@@ -111,16 +119,22 @@ class BelongsToField extends _relationField.RelationField {
|
|
|
111
119
|
const tcoll = database.collections.get(this.target);
|
|
112
120
|
const foreignKey = this.options.foreignKey;
|
|
113
121
|
const field1 = collection.getField(foreignKey);
|
|
114
|
-
const field2 = tcoll.findField(field => {
|
|
122
|
+
const field2 = tcoll ? tcoll.findField(field => {
|
|
115
123
|
return field.type === 'hasMany' && field.foreignKey === foreignKey;
|
|
116
|
-
});
|
|
124
|
+
}) : null;
|
|
117
125
|
|
|
118
126
|
if (!field1 && !field2) {
|
|
119
127
|
collection.model.removeAttribute(foreignKey);
|
|
120
128
|
}
|
|
121
129
|
|
|
122
130
|
const association = collection.model.associations[this.name];
|
|
123
|
-
|
|
131
|
+
|
|
132
|
+
if (association) {
|
|
133
|
+
const reference = this.reference(association);
|
|
134
|
+
this.database.referenceMap.removeReference(reference);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
this.clearAccessors(); // 删掉 model 的关联字段
|
|
124
138
|
|
|
125
139
|
delete collection.model.associations[this.name]; // @ts-ignore
|
|
126
140
|
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { BelongsToManyOptions as SequelizeBelongsToManyOptions } from 'sequelize';
|
|
2
|
+
import { Reference } from '../features/ReferencesMap';
|
|
2
3
|
import { MultipleRelationFieldOptions, RelationField } from './relation-field';
|
|
3
4
|
export declare class BelongsToManyField extends RelationField {
|
|
5
|
+
get dataType(): string;
|
|
4
6
|
get through(): any;
|
|
5
7
|
get otherKey(): any;
|
|
8
|
+
references(association: any): Reference[];
|
|
6
9
|
bind(): boolean;
|
|
7
10
|
unbind(): void;
|
|
8
11
|
}
|
|
9
12
|
export interface BelongsToManyFieldOptions extends MultipleRelationFieldOptions, Omit<SequelizeBelongsToManyOptions, 'through'> {
|
|
10
13
|
type: 'belongsToMany';
|
|
14
|
+
target?: string;
|
|
11
15
|
through?: string;
|
|
12
16
|
}
|
|
@@ -27,6 +27,8 @@ function _sequelize() {
|
|
|
27
27
|
|
|
28
28
|
var _utils = require("../utils");
|
|
29
29
|
|
|
30
|
+
var _belongsToField = require("./belongs-to-field");
|
|
31
|
+
|
|
30
32
|
var _relationField = require("./relation-field");
|
|
31
33
|
|
|
32
34
|
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; }
|
|
@@ -36,6 +38,10 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
36
38
|
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; }
|
|
37
39
|
|
|
38
40
|
class BelongsToManyField extends _relationField.RelationField {
|
|
41
|
+
get dataType() {
|
|
42
|
+
return 'BelongsToMany';
|
|
43
|
+
}
|
|
44
|
+
|
|
39
45
|
get through() {
|
|
40
46
|
return this.options.through || _sequelize().Utils.camelize([this.context.collection.model.name, this.target].map(name => name.toLowerCase()).sort().join('_'));
|
|
41
47
|
}
|
|
@@ -44,6 +50,12 @@ class BelongsToManyField extends _relationField.RelationField {
|
|
|
44
50
|
return this.options.otherKey;
|
|
45
51
|
}
|
|
46
52
|
|
|
53
|
+
references(association) {
|
|
54
|
+
const db = this.context.database;
|
|
55
|
+
const onDelete = this.options.onDelete || 'CASCADE';
|
|
56
|
+
return [_belongsToField.BelongsToField.toReference(db, association.toSource, onDelete), _belongsToField.BelongsToField.toReference(db, association.toTarget, onDelete)];
|
|
57
|
+
}
|
|
58
|
+
|
|
47
59
|
bind() {
|
|
48
60
|
const _this$context = this.context,
|
|
49
61
|
database = _this$context.database,
|
|
@@ -70,6 +82,10 @@ class BelongsToManyField extends _relationField.RelationField {
|
|
|
70
82
|
});
|
|
71
83
|
}
|
|
72
84
|
|
|
85
|
+
if (!this.options.onDelete) {
|
|
86
|
+
this.options.onDelete = 'CASCADE';
|
|
87
|
+
}
|
|
88
|
+
|
|
73
89
|
const association = collection.model.belongsToMany(Target, _objectSpread(_objectSpread({
|
|
74
90
|
constraints: false
|
|
75
91
|
}, (0, _lodash().omit)(this.options, ['name', 'type', 'target'])), {}, {
|
|
@@ -105,6 +121,7 @@ class BelongsToManyField extends _relationField.RelationField {
|
|
|
105
121
|
|
|
106
122
|
Through.addIndex([this.options.foreignKey]);
|
|
107
123
|
Through.addIndex([this.options.otherKey]);
|
|
124
|
+
this.references(association).forEach(reference => this.database.referenceMap.addReference(reference));
|
|
108
125
|
return true;
|
|
109
126
|
}
|
|
110
127
|
|
|
@@ -116,6 +133,13 @@ class BelongsToManyField extends _relationField.RelationField {
|
|
|
116
133
|
|
|
117
134
|
database.removePendingField(this); // 删掉 model 的关联字段
|
|
118
135
|
|
|
136
|
+
const association = collection.model.associations[this.name];
|
|
137
|
+
|
|
138
|
+
if (association) {
|
|
139
|
+
this.references(association).forEach(reference => this.database.referenceMap.removeReference(reference));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
this.clearAccessors();
|
|
119
143
|
delete collection.model.associations[this.name];
|
|
120
144
|
}
|
|
121
145
|
|
package/lib/fields/field.d.ts
CHANGED
|
@@ -21,10 +21,10 @@ export declare abstract class Field {
|
|
|
21
21
|
database: Database;
|
|
22
22
|
collection: Collection;
|
|
23
23
|
[key: string]: any;
|
|
24
|
+
constructor(options?: any, context?: FieldContext);
|
|
24
25
|
get name(): any;
|
|
25
26
|
get type(): any;
|
|
26
|
-
get dataType(): any;
|
|
27
|
-
constructor(options?: any, context?: FieldContext);
|
|
27
|
+
abstract get dataType(): any;
|
|
28
28
|
sync(syncOptions: SyncOptions): Promise<void>;
|
|
29
29
|
init(): void;
|
|
30
30
|
on(eventName: ModelEventTypes, listener: (...args: any[]) => void): this;
|
|
@@ -38,4 +38,5 @@ export declare abstract class Field {
|
|
|
38
38
|
unbind(): void;
|
|
39
39
|
toSequelize(): any;
|
|
40
40
|
isSqlite(): boolean;
|
|
41
|
+
typeToString(): any;
|
|
41
42
|
}
|
package/lib/fields/field.js
CHANGED
|
@@ -40,18 +40,6 @@ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try
|
|
|
40
40
|
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); }); }; }
|
|
41
41
|
|
|
42
42
|
class Field {
|
|
43
|
-
get name() {
|
|
44
|
-
return this.options.name;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
get type() {
|
|
48
|
-
return this.options.type;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
get dataType() {
|
|
52
|
-
return this.options.dataType;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
43
|
constructor(options, context) {
|
|
56
44
|
this.options = void 0;
|
|
57
45
|
this.context = void 0;
|
|
@@ -64,6 +52,14 @@ class Field {
|
|
|
64
52
|
this.init();
|
|
65
53
|
}
|
|
66
54
|
|
|
55
|
+
get name() {
|
|
56
|
+
return this.options.name;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
get type() {
|
|
60
|
+
return this.options.type;
|
|
61
|
+
}
|
|
62
|
+
|
|
67
63
|
sync(syncOptions) {
|
|
68
64
|
var _this = this;
|
|
69
65
|
|
|
@@ -103,13 +99,19 @@ class Field {
|
|
|
103
99
|
var _this2 = this;
|
|
104
100
|
|
|
105
101
|
return _asyncToGenerator(function* () {
|
|
106
|
-
|
|
102
|
+
const attribute = _this2.collection.model.rawAttributes[_this2.name];
|
|
103
|
+
|
|
104
|
+
if (!attribute) {
|
|
107
105
|
_this2.remove(); // console.log('field is not attribute');
|
|
108
106
|
|
|
109
107
|
|
|
110
108
|
return;
|
|
111
109
|
}
|
|
112
110
|
|
|
111
|
+
if (_this2.collection.isInherited() && _this2.collection.parentFields().has(_this2.name)) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
113
115
|
if (_this2.collection.model._virtualAttributes.has(_this2.name)) {
|
|
114
116
|
_this2.remove(); // console.log('field is virtual attribute');
|
|
115
117
|
|
|
@@ -240,6 +242,10 @@ class Field {
|
|
|
240
242
|
return this.database.sequelize.getDialect() === 'sqlite';
|
|
241
243
|
}
|
|
242
244
|
|
|
245
|
+
typeToString() {
|
|
246
|
+
return this.dataType.toString();
|
|
247
|
+
}
|
|
248
|
+
|
|
243
249
|
}
|
|
244
250
|
|
|
245
251
|
exports.Field = Field;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AssociationScope, DataType, ForeignKeyOptions, HasManyOptions, HasManyOptions as SequelizeHasManyOptions } from 'sequelize';
|
|
2
|
-
import { MultipleRelationFieldOptions, RelationField } from './relation-field';
|
|
3
2
|
import { Reference } from '../features/ReferencesMap';
|
|
3
|
+
import { MultipleRelationFieldOptions, RelationField } from './relation-field';
|
|
4
4
|
export interface HasManyFieldOptions extends HasManyOptions {
|
|
5
5
|
/**
|
|
6
6
|
* The name of the field to use as the key for the association in the source table. Defaults to the primary
|
|
@@ -55,6 +55,7 @@ export interface HasManyFieldOptions extends HasManyOptions {
|
|
|
55
55
|
hooks?: boolean;
|
|
56
56
|
}
|
|
57
57
|
export declare class HasManyField extends RelationField {
|
|
58
|
+
get dataType(): any;
|
|
58
59
|
get foreignKey(): any;
|
|
59
60
|
reference(association: any): Reference;
|
|
60
61
|
bind(): boolean;
|
|
@@ -36,6 +36,10 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
36
36
|
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; }
|
|
37
37
|
|
|
38
38
|
class HasManyField extends _relationField.RelationField {
|
|
39
|
+
get dataType() {
|
|
40
|
+
return 'HasMany';
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
get foreignKey() {
|
|
40
44
|
if (this.options.foreignKey) {
|
|
41
45
|
return this.options.foreignKey;
|
|
@@ -122,25 +126,29 @@ class HasManyField extends _relationField.RelationField {
|
|
|
122
126
|
database.removePendingField(this); // 如果关系表内没有显式的创建外键字段,删除关系时,外键也删除掉
|
|
123
127
|
|
|
124
128
|
const tcoll = database.getCollection(this.target);
|
|
125
|
-
const foreignKey = this.options.foreignKey;
|
|
126
|
-
const field = tcoll.findField(field => {
|
|
127
|
-
if (field.name === foreignKey) {
|
|
128
|
-
return true;
|
|
129
|
-
}
|
|
130
129
|
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
if (tcoll) {
|
|
131
|
+
const foreignKey = this.options.foreignKey;
|
|
132
|
+
const field = tcoll.findField(field => {
|
|
133
|
+
if (field.name === foreignKey) {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
133
136
|
|
|
134
|
-
|
|
135
|
-
|
|
137
|
+
return field.type === 'belongsTo' && field.foreignKey === foreignKey;
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
if (!field) {
|
|
141
|
+
tcoll.model.removeAttribute(foreignKey);
|
|
142
|
+
}
|
|
136
143
|
}
|
|
137
144
|
|
|
138
145
|
const association = collection.model.associations[this.name];
|
|
139
146
|
|
|
140
147
|
if (association) {
|
|
141
148
|
this.database.referenceMap.removeReference(this.reference(association));
|
|
142
|
-
}
|
|
149
|
+
}
|
|
143
150
|
|
|
151
|
+
this.clearAccessors(); // 删掉 model 的关联字段
|
|
144
152
|
|
|
145
153
|
delete collection.model.associations[this.name]; // @ts-ignore
|
|
146
154
|
|
|
@@ -36,6 +36,10 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
36
36
|
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; }
|
|
37
37
|
|
|
38
38
|
class HasOneField extends _relationField.RelationField {
|
|
39
|
+
get dataType() {
|
|
40
|
+
return 'HasOne';
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
get target() {
|
|
40
44
|
const _this$options = this.options,
|
|
41
45
|
target = _this$options.target,
|
|
@@ -123,21 +127,29 @@ class HasOneField extends _relationField.RelationField {
|
|
|
123
127
|
database.removePendingField(this); // 如果关系表内没有显式的创建外键字段,删除关系时,外键也删除掉
|
|
124
128
|
|
|
125
129
|
const tcoll = database.collections.get(this.target);
|
|
126
|
-
const foreignKey = this.options.foreignKey;
|
|
127
|
-
const field = tcoll.findField(field => {
|
|
128
|
-
if (field.name === foreignKey) {
|
|
129
|
-
return true;
|
|
130
|
-
}
|
|
131
130
|
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
if (tcoll && !this.options.inherit) {
|
|
132
|
+
const foreignKey = this.options.foreignKey;
|
|
133
|
+
const field = tcoll.findField(field => {
|
|
134
|
+
if (field.name === foreignKey) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return field.type === 'belongsTo' && field.foreignKey === foreignKey;
|
|
139
|
+
});
|
|
134
140
|
|
|
135
|
-
|
|
136
|
-
|
|
141
|
+
if (!field) {
|
|
142
|
+
tcoll.model.removeAttribute(foreignKey);
|
|
143
|
+
}
|
|
137
144
|
}
|
|
138
145
|
|
|
139
146
|
const association = collection.model.associations[this.name];
|
|
140
|
-
|
|
147
|
+
|
|
148
|
+
if (association) {
|
|
149
|
+
this.database.referenceMap.removeReference(this.reference(association));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.clearAccessors(); // 删掉 model 的关联字段
|
|
141
153
|
|
|
142
154
|
delete collection.model.associations[this.name]; // @ts-ignore
|
|
143
155
|
|
package/lib/fields/index.d.ts
CHANGED
|
@@ -19,8 +19,9 @@ import { UidFieldOptions } from './uid-field';
|
|
|
19
19
|
import { UUIDFieldOptions } from './uuid-field';
|
|
20
20
|
import { VirtualFieldOptions } from './virtual-field';
|
|
21
21
|
import { FormulaFieldOptions } from './formula-field';
|
|
22
|
-
import {
|
|
22
|
+
import { SetFieldOptions } from './set-field';
|
|
23
23
|
export * from './array-field';
|
|
24
|
+
export * from './set-field';
|
|
24
25
|
export * from './belongs-to-field';
|
|
25
26
|
export * from './belongs-to-many-field';
|
|
26
27
|
export * from './boolean-field';
|
|
@@ -42,5 +43,4 @@ export * from './uid-field';
|
|
|
42
43
|
export * from './uuid-field';
|
|
43
44
|
export * from './virtual-field';
|
|
44
45
|
export * from './formula-field';
|
|
45
|
-
export
|
|
46
|
-
export declare type FieldOptions = BaseFieldOptions | StringFieldOptions | IntegerFieldOptions | FloatFieldOptions | DecimalFieldOptions | DoubleFieldOptions | RealFieldOptions | JsonFieldOptions | JsonbFieldOptions | BooleanFieldOptions | RadioFieldOptions | SortFieldOptions | TextFieldOptions | VirtualFieldOptions | FormulaFieldOptions | ArrayFieldOptions | TimeFieldOptions | DateFieldOptions | UidFieldOptions | UUIDFieldOptions | PasswordFieldOptions | ContextFieldOptions | BelongsToFieldOptions | HasOneFieldOptions | HasManyFieldOptions | BelongsToManyFieldOptions | SequenceFieldOptions;
|
|
46
|
+
export declare type FieldOptions = BaseFieldOptions | StringFieldOptions | IntegerFieldOptions | FloatFieldOptions | DecimalFieldOptions | DoubleFieldOptions | RealFieldOptions | JsonFieldOptions | JsonbFieldOptions | BooleanFieldOptions | RadioFieldOptions | SortFieldOptions | TextFieldOptions | VirtualFieldOptions | FormulaFieldOptions | ArrayFieldOptions | SetFieldOptions | TimeFieldOptions | DateFieldOptions | UidFieldOptions | UUIDFieldOptions | PasswordFieldOptions | ContextFieldOptions | BelongsToFieldOptions | HasOneFieldOptions | HasManyFieldOptions | BelongsToManyFieldOptions;
|