@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
package/lib/fields/sort-field.js
CHANGED
|
@@ -56,113 +56,126 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar
|
|
|
56
56
|
const sortFieldMutex = new (_asyncMutex().Mutex)();
|
|
57
57
|
|
|
58
58
|
class SortField extends _field.Field {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
59
|
+
constructor(...args) {
|
|
60
|
+
var _this;
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
super(...args);
|
|
63
|
+
_this = this;
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
this.setSortValue = /*#__PURE__*/function () {
|
|
66
|
+
var _ref = _asyncToGenerator(function* (instance, options) {
|
|
67
|
+
const _this$options = _this.options,
|
|
68
|
+
name = _this$options.name,
|
|
69
|
+
scopeKey = _this$options.scopeKey;
|
|
70
|
+
const model = _this.context.collection.model;
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
if ((0, _lodash().isNumber)(instance.get(name)) && instance._previousDataValues[scopeKey] == instance[scopeKey]) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
const where = {};
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
if (scopeKey) {
|
|
79
|
+
const value = instance.get(scopeKey);
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
if (value !== undefined && value !== null) {
|
|
82
|
+
where[scopeKey] = value;
|
|
83
|
+
}
|
|
83
84
|
}
|
|
84
|
-
}
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
yield sortFieldMutex.runExclusive( /*#__PURE__*/_asyncToGenerator(function* () {
|
|
87
|
+
const max = yield model.max(name, _objectSpread(_objectSpread({}, options), {}, {
|
|
88
|
+
where
|
|
89
|
+
}));
|
|
90
|
+
const newValue = (max || 0) + 1;
|
|
91
|
+
instance.set(name, newValue);
|
|
89
92
|
}));
|
|
90
|
-
|
|
91
|
-
instance.set(name, newValue);
|
|
92
|
-
}));
|
|
93
|
-
})();
|
|
94
|
-
}
|
|
93
|
+
});
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
return function (_x, _x2) {
|
|
96
|
+
return _ref.apply(this, arguments);
|
|
97
|
+
};
|
|
98
|
+
}();
|
|
98
99
|
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
this.onScopeChange = /*#__PURE__*/function () {
|
|
101
|
+
var _ref3 = _asyncToGenerator(function* (instance, options) {
|
|
102
|
+
const scopeKey = _this.options.scopeKey;
|
|
101
103
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
104
|
+
if (scopeKey && !instance.isNewRecord && instance._previousDataValues[scopeKey] != instance[scopeKey]) {
|
|
105
|
+
yield _this.setSortValue(instance, options);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
return function (_x3, _x4) {
|
|
110
|
+
return _ref3.apply(this, arguments);
|
|
111
|
+
};
|
|
112
|
+
}();
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
transaction
|
|
116
|
-
});
|
|
117
|
-
const emptyCount = yield _this3.collection.repository.count({
|
|
118
|
-
filter: {
|
|
119
|
-
[_this3.name]: null
|
|
120
|
-
},
|
|
114
|
+
this.initRecordsSortValue = /*#__PURE__*/function () {
|
|
115
|
+
var _ref4 = _asyncToGenerator(function* ({
|
|
121
116
|
transaction
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
117
|
+
}) {
|
|
118
|
+
const totalCount = yield _this.collection.repository.count({
|
|
119
|
+
transaction
|
|
120
|
+
});
|
|
121
|
+
const emptyCount = yield _this.collection.repository.count({
|
|
122
|
+
filter: {
|
|
123
|
+
[_this.name]: null
|
|
124
|
+
},
|
|
127
125
|
transaction
|
|
128
126
|
});
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
127
|
+
|
|
128
|
+
if (emptyCount === totalCount && emptyCount > 0) {
|
|
129
|
+
const records = yield _this.collection.repository.find({
|
|
130
|
+
order: [_this.collection.model.primaryKeyAttribute],
|
|
131
|
+
transaction
|
|
132
|
+
});
|
|
133
|
+
let start = 1;
|
|
134
|
+
|
|
135
|
+
var _iterator = _createForOfIteratorHelper(records),
|
|
136
|
+
_step;
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
140
|
+
const record = _step.value;
|
|
141
|
+
yield record.update({
|
|
142
|
+
sort: start
|
|
143
|
+
}, {
|
|
144
|
+
transaction,
|
|
145
|
+
silent: true
|
|
146
|
+
});
|
|
147
|
+
start += 1;
|
|
148
|
+
}
|
|
149
|
+
} catch (err) {
|
|
150
|
+
_iterator.e(err);
|
|
151
|
+
} finally {
|
|
152
|
+
_iterator.f();
|
|
144
153
|
}
|
|
145
|
-
} catch (err) {
|
|
146
|
-
_iterator.e(err);
|
|
147
|
-
} finally {
|
|
148
|
-
_iterator.f();
|
|
149
154
|
}
|
|
150
|
-
}
|
|
151
|
-
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
return function (_x5) {
|
|
158
|
+
return _ref4.apply(this, arguments);
|
|
159
|
+
};
|
|
160
|
+
}();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
get dataType() {
|
|
164
|
+
return _sequelize().DataTypes.INTEGER;
|
|
152
165
|
}
|
|
153
166
|
|
|
154
167
|
bind() {
|
|
155
168
|
super.bind();
|
|
156
|
-
this.on('afterSync', this.initRecordsSortValue
|
|
157
|
-
this.on('beforeUpdate', this.onScopeChange
|
|
158
|
-
this.on('beforeCreate', this.setSortValue
|
|
169
|
+
this.on('afterSync', this.initRecordsSortValue);
|
|
170
|
+
this.on('beforeUpdate', this.onScopeChange);
|
|
171
|
+
this.on('beforeCreate', this.setSortValue);
|
|
159
172
|
}
|
|
160
173
|
|
|
161
174
|
unbind() {
|
|
162
175
|
super.unbind();
|
|
163
|
-
this.off('beforeUpdate', this.onScopeChange
|
|
164
|
-
this.off('beforeCreate', this.setSortValue
|
|
165
|
-
this.off('afterSync', this.initRecordsSortValue
|
|
176
|
+
this.off('beforeUpdate', this.onScopeChange);
|
|
177
|
+
this.off('beforeCreate', this.setSortValue);
|
|
178
|
+
this.off('afterSync', this.initRecordsSortValue);
|
|
166
179
|
}
|
|
167
180
|
|
|
168
181
|
}
|
package/lib/filter-parser.js
CHANGED
|
@@ -161,11 +161,17 @@ class FilterParser {
|
|
|
161
161
|
|
|
162
162
|
const queryValue = _lodash().default.get((0, _flat().unflatten)(originalFiler), skipPrefix);
|
|
163
163
|
|
|
164
|
+
const _this$getFieldNameFro = this.getFieldNameFromQueryPath(skipPrefix),
|
|
165
|
+
_this$getFieldNameFro2 = _slicedToArray(_this$getFieldNameFro, 2),
|
|
166
|
+
fieldName = _this$getFieldNameFro2[0],
|
|
167
|
+
fullName = _this$getFieldNameFro2[1];
|
|
168
|
+
|
|
164
169
|
value = opKey(queryValue, {
|
|
165
170
|
app: this.context.app,
|
|
166
171
|
db: this.database,
|
|
167
172
|
path: skipPrefix,
|
|
168
|
-
|
|
173
|
+
fullName,
|
|
174
|
+
fieldName,
|
|
169
175
|
model: this.model
|
|
170
176
|
});
|
|
171
177
|
break;
|
|
@@ -272,6 +278,7 @@ class FilterParser {
|
|
|
272
278
|
getFieldNameFromQueryPath(queryPath) {
|
|
273
279
|
const paths = queryPath.split('.');
|
|
274
280
|
let fieldName;
|
|
281
|
+
let fullPaths = [];
|
|
275
282
|
|
|
276
283
|
var _iterator = _createForOfIteratorHelper(paths),
|
|
277
284
|
_step;
|
|
@@ -284,6 +291,7 @@ class FilterParser {
|
|
|
284
291
|
continue;
|
|
285
292
|
}
|
|
286
293
|
|
|
294
|
+
fullPaths.push(path);
|
|
287
295
|
fieldName = path;
|
|
288
296
|
}
|
|
289
297
|
} catch (err) {
|
|
@@ -292,7 +300,7 @@ class FilterParser {
|
|
|
292
300
|
_iterator.f();
|
|
293
301
|
}
|
|
294
302
|
|
|
295
|
-
return fieldName;
|
|
303
|
+
return [fieldName, fullPaths.join('.')];
|
|
296
304
|
}
|
|
297
305
|
|
|
298
306
|
}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -4,8 +4,15 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
var _exportNames = {
|
|
7
|
+
DataTypes: true,
|
|
7
8
|
Op: true
|
|
8
9
|
};
|
|
10
|
+
Object.defineProperty(exports, "DataTypes", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function get() {
|
|
13
|
+
return _sequelize().DataTypes;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
9
16
|
Object.defineProperty(exports, "Op", {
|
|
10
17
|
enumerable: true,
|
|
11
18
|
get: function get() {
|
|
@@ -2,6 +2,7 @@ import { Model } from './model';
|
|
|
2
2
|
export declare class MagicAttributeModel extends Model {
|
|
3
3
|
get magicAttribute(): string;
|
|
4
4
|
set(key: any, value?: any, options?: any): this;
|
|
5
|
+
setV1(key?: any, value?: any, options?: any): this;
|
|
5
6
|
get(key?: any, value?: any): any;
|
|
6
7
|
update(values?: any, options?: any): Promise<this>;
|
|
7
8
|
}
|
|
@@ -25,6 +25,16 @@ function _lodash() {
|
|
|
25
25
|
return data;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
function _sequelize() {
|
|
29
|
+
const data = require("sequelize");
|
|
30
|
+
|
|
31
|
+
_sequelize = function _sequelize() {
|
|
32
|
+
return data;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return data;
|
|
36
|
+
}
|
|
37
|
+
|
|
28
38
|
var _model = require("./model");
|
|
29
39
|
|
|
30
40
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -33,6 +43,8 @@ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try
|
|
|
33
43
|
|
|
34
44
|
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); }); }; }
|
|
35
45
|
|
|
46
|
+
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(_e2) { throw _e2; }, 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(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
47
|
+
|
|
36
48
|
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; }
|
|
37
49
|
|
|
38
50
|
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; }
|
|
@@ -51,6 +63,8 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
|
|
|
51
63
|
|
|
52
64
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
53
65
|
|
|
66
|
+
const Dottie = require('dottie');
|
|
67
|
+
|
|
54
68
|
class MagicAttributeModel extends _model.Model {
|
|
55
69
|
get magicAttribute() {
|
|
56
70
|
const db = this.constructor.database;
|
|
@@ -65,30 +79,217 @@ class MagicAttributeModel extends _model.Model {
|
|
|
65
79
|
column = _key$split2[0];
|
|
66
80
|
|
|
67
81
|
if (this.constructor.hasAlias(column)) {
|
|
68
|
-
return
|
|
82
|
+
return this.setV1(key, value, options);
|
|
69
83
|
}
|
|
70
84
|
|
|
71
85
|
if (this.constructor.rawAttributes[column]) {
|
|
72
|
-
return
|
|
86
|
+
return this.setV1(key, value, options);
|
|
73
87
|
}
|
|
74
88
|
|
|
75
89
|
if (_lodash().default.isPlainObject(value)) {
|
|
76
90
|
const opts = super.get(this.magicAttribute) || {};
|
|
77
|
-
return
|
|
91
|
+
return this.setV1(`${this.magicAttribute}.${key}`, (0, _utils().merge)(opts === null || opts === void 0 ? void 0 : opts[key], value), options);
|
|
78
92
|
}
|
|
79
93
|
|
|
80
|
-
return
|
|
94
|
+
return this.setV1(`${this.magicAttribute}.${key}`, value, options);
|
|
81
95
|
} else {
|
|
82
96
|
if (!key) {
|
|
83
97
|
return;
|
|
84
98
|
}
|
|
85
99
|
|
|
86
100
|
Object.keys(key).forEach(k => {
|
|
87
|
-
this.
|
|
101
|
+
this.setV1(k, key[k], options);
|
|
88
102
|
});
|
|
89
103
|
}
|
|
90
104
|
|
|
91
|
-
return
|
|
105
|
+
return this.setV1(key, value, options);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
setV1(key, value, options) {
|
|
109
|
+
let values;
|
|
110
|
+
let originalValue;
|
|
111
|
+
|
|
112
|
+
if (typeof key === 'object' && key !== null) {
|
|
113
|
+
values = key;
|
|
114
|
+
options = value || {};
|
|
115
|
+
|
|
116
|
+
if (options.reset) {
|
|
117
|
+
// @ts-ignore
|
|
118
|
+
this.dataValues = {};
|
|
119
|
+
|
|
120
|
+
for (const key in values) {
|
|
121
|
+
this.changed(key, false);
|
|
122
|
+
}
|
|
123
|
+
} // If raw, and we're not dealing with includes or special attributes, just set it straight on the dataValues object
|
|
124
|
+
// @ts-ignore
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if (options.raw && // @ts-ignore
|
|
128
|
+
!(this._options && this._options.include) && !(options && options.attributes) && // @ts-ignore
|
|
129
|
+
!this.constructor._hasDateAttributes && // @ts-ignore
|
|
130
|
+
!this.constructor._hasBooleanAttributes) {
|
|
131
|
+
// @ts-ignore
|
|
132
|
+
if (Object.keys(this.dataValues).length) {
|
|
133
|
+
// @ts-ignore
|
|
134
|
+
Object.assign(this.dataValues, values);
|
|
135
|
+
} else {
|
|
136
|
+
// @ts-ignore
|
|
137
|
+
this.dataValues = values;
|
|
138
|
+
} // If raw, .changed() shouldn't be true
|
|
139
|
+
// @ts-ignore
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
this._previousDataValues = _objectSpread({}, this.dataValues);
|
|
143
|
+
} else {
|
|
144
|
+
// Loop and call set
|
|
145
|
+
if (options.attributes) {
|
|
146
|
+
const setKeys = data => {
|
|
147
|
+
var _iterator = _createForOfIteratorHelper(data),
|
|
148
|
+
_step;
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
152
|
+
const k = _step.value;
|
|
153
|
+
|
|
154
|
+
if (values[k] === undefined) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
this.set(k, values[k], options);
|
|
159
|
+
}
|
|
160
|
+
} catch (err) {
|
|
161
|
+
_iterator.e(err);
|
|
162
|
+
} finally {
|
|
163
|
+
_iterator.f();
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
setKeys(options.attributes); // @ts-ignore
|
|
168
|
+
|
|
169
|
+
if (this.constructor._hasVirtualAttributes) {
|
|
170
|
+
// @ts-ignore
|
|
171
|
+
setKeys(this.constructor._virtualAttributes);
|
|
172
|
+
} // @ts-ignore
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
if (this._options.includeNames) {
|
|
176
|
+
// @ts-ignore
|
|
177
|
+
setKeys(this._options.includeNames);
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
for (const key in values) {
|
|
181
|
+
this.set(key, values[key], options);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (options.raw) {
|
|
186
|
+
// If raw, .changed() shouldn't be true
|
|
187
|
+
// @ts-ignore
|
|
188
|
+
this._previousDataValues = _objectSpread({}, this.dataValues);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return this;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (!options) options = {};
|
|
196
|
+
|
|
197
|
+
if (!options.raw) {
|
|
198
|
+
// @ts-ignore
|
|
199
|
+
originalValue = this.dataValues[key];
|
|
200
|
+
} // If not raw, and there's a custom setter
|
|
201
|
+
// @ts-ignore
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
if (!options.raw && this._customSetters[key]) {
|
|
205
|
+
// @ts-ignore
|
|
206
|
+
this._customSetters[key].call(this, value, key); // custom setter should have changed value, get that changed value
|
|
207
|
+
// TODO: v5 make setters return new value instead of changing internal store
|
|
208
|
+
// @ts-ignore
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
const newValue = this.dataValues[key];
|
|
212
|
+
|
|
213
|
+
if (!_lodash().default.isEqual(newValue, originalValue)) {
|
|
214
|
+
// @ts-ignore
|
|
215
|
+
this._previousDataValues[key] = originalValue;
|
|
216
|
+
this.changed(key, true);
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
// Check if we have included models, and if this key matches the include model names/aliases
|
|
220
|
+
// @ts-ignore
|
|
221
|
+
if (this._options && this._options.include && this._options.includeNames.includes(key)) {
|
|
222
|
+
// Pass it on to the include handler
|
|
223
|
+
// @ts-ignore
|
|
224
|
+
this._setInclude(key, value, options);
|
|
225
|
+
|
|
226
|
+
return this;
|
|
227
|
+
} // Bunch of stuff we won't do when it's raw
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
if (!options.raw) {
|
|
231
|
+
// If attribute is not in model definition, return
|
|
232
|
+
// @ts-ignore
|
|
233
|
+
if (!this._isAttribute(key)) {
|
|
234
|
+
// @ts-ignore
|
|
235
|
+
if (key.includes('.') && this.constructor._jsonAttributes.has(key.split('.')[0])) {
|
|
236
|
+
// @ts-ignore
|
|
237
|
+
const previousNestedValue = Dottie.get(this.dataValues, key);
|
|
238
|
+
|
|
239
|
+
if (!_lodash().default.isEqual(previousNestedValue, value)) {
|
|
240
|
+
// @ts-ignore
|
|
241
|
+
this._previousDataValues = _lodash().default.cloneDeep(this._previousDataValues); // @ts-ignore
|
|
242
|
+
|
|
243
|
+
Dottie.set(this.dataValues, key, value);
|
|
244
|
+
this.changed(key.split('.')[0], true);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return this;
|
|
249
|
+
} // If attempting to set primary key and primary key is already defined, return
|
|
250
|
+
// @ts-ignore
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
if (this.constructor._hasPrimaryKeys && originalValue && this.constructor._isPrimaryKey(key)) {
|
|
254
|
+
return this;
|
|
255
|
+
} // If attempting to set read only attributes, return
|
|
256
|
+
// @ts-ignore
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
if (!this.isNewRecord && // @ts-ignore
|
|
260
|
+
this.constructor._hasReadOnlyAttributes && // @ts-ignore
|
|
261
|
+
this.constructor._readOnlyAttributes.has(key)) {
|
|
262
|
+
return this;
|
|
263
|
+
}
|
|
264
|
+
} // If there's a data type sanitizer
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
if (!(value instanceof _sequelize().Utils.SequelizeMethod) && // @ts-ignore
|
|
268
|
+
Object.prototype.hasOwnProperty.call(this.constructor._dataTypeSanitizers, key)) {
|
|
269
|
+
// @ts-ignore
|
|
270
|
+
value = this.constructor._dataTypeSanitizers[key].call(this, value, options);
|
|
271
|
+
} // Set when the value has changed and not raw
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
if (!options.raw && ( // True when sequelize method
|
|
275
|
+
value instanceof _sequelize().Utils.SequelizeMethod || // Check for data type type comparators
|
|
276
|
+
// @ts-ignore
|
|
277
|
+
!(value instanceof _sequelize().Utils.SequelizeMethod) && // @ts-ignore
|
|
278
|
+
this.constructor._dataTypeChanges[key] && // @ts-ignore
|
|
279
|
+
this.constructor._dataTypeChanges[key].call(this, value, originalValue, options) || // Check default
|
|
280
|
+
// @ts-ignore
|
|
281
|
+
!this.constructor._dataTypeChanges[key] && !_lodash().default.isEqual(value, originalValue))) {
|
|
282
|
+
// @ts-ignore
|
|
283
|
+
this._previousDataValues[key] = originalValue;
|
|
284
|
+
this.changed(key, true);
|
|
285
|
+
} // set data value
|
|
286
|
+
// @ts-ignore
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
this.dataValues[key] = value;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return this;
|
|
92
293
|
}
|
|
93
294
|
|
|
94
295
|
get(key, value) {
|
package/lib/mock-database.js
CHANGED
|
@@ -55,7 +55,7 @@ function getConfigByEnv() {
|
|
|
55
55
|
database: process.env.DB_DATABASE,
|
|
56
56
|
host: process.env.DB_HOST,
|
|
57
57
|
port: process.env.DB_PORT,
|
|
58
|
-
dialect: process.env.DB_DIALECT,
|
|
58
|
+
dialect: process.env.DB_DIALECT || 'sqlite',
|
|
59
59
|
logging: process.env.DB_LOGGING === 'on' ? console.log : false,
|
|
60
60
|
storage: process.env.DB_STORAGE && process.env.DB_STORAGE !== ':memory:' ? (0, _path().resolve)(process.cwd(), process.env.DB_STORAGE) : ':memory:',
|
|
61
61
|
define: {
|
package/lib/operators/array.js
CHANGED
|
@@ -29,8 +29,9 @@ const escape = (value, ctx) => {
|
|
|
29
29
|
|
|
30
30
|
const sqliteExistQuery = (value, ctx) => {
|
|
31
31
|
const fieldName = getFieldName(ctx);
|
|
32
|
+
const name = ctx.fullName === fieldName ? `"${ctx.model.name}"."${fieldName}"` : `"${fieldName}"`;
|
|
32
33
|
const sqlArray = `(${value.map(v => `'${v}'`).join(', ')})`;
|
|
33
|
-
const subQuery = `exists (select * from json_each(${
|
|
34
|
+
const subQuery = `exists (select * from json_each(${name}) where json_each.value in ${sqlArray})`;
|
|
34
35
|
return subQuery;
|
|
35
36
|
};
|
|
36
37
|
|
|
@@ -65,7 +66,8 @@ var _default = {
|
|
|
65
66
|
value = escape(JSON.stringify(value.sort()), ctx);
|
|
66
67
|
|
|
67
68
|
if ((0, _utils.isMySQL)(ctx)) {
|
|
68
|
-
|
|
69
|
+
const name = ctx.fullName === fieldName ? `\`${ctx.model.name}\`.\`${fieldName}\`` : `\`${fieldName}\``;
|
|
70
|
+
return _sequelize().Sequelize.literal(`JSON_CONTAINS(${name}, ${value}) AND JSON_CONTAINS(${value}, ${name})`);
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
return {
|
|
@@ -78,11 +80,13 @@ var _default = {
|
|
|
78
80
|
value = escape(JSON.stringify(value), ctx);
|
|
79
81
|
|
|
80
82
|
if ((0, _utils.isPg)(ctx)) {
|
|
81
|
-
|
|
83
|
+
const name = ctx.fullName === fieldName ? `"${ctx.model.name}"."${fieldName}"` : `"${fieldName}"`;
|
|
84
|
+
return _sequelize().Sequelize.literal(`not (${name} <@ ${value}::JSONB and ${name} @> ${value}::JSONB)`);
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
if ((0, _utils.isMySQL)(ctx)) {
|
|
85
|
-
|
|
88
|
+
const name = ctx.fullName === fieldName ? `\`${ctx.model.name}\`.\`${fieldName}\`` : `\`${fieldName}\``;
|
|
89
|
+
return _sequelize().Sequelize.literal(`not (JSON_CONTAINS(${name}, ${value}) AND JSON_CONTAINS(${value}, ${name}))`);
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
return {
|
|
@@ -94,12 +98,14 @@ var _default = {
|
|
|
94
98
|
const fieldName = getFieldName(ctx);
|
|
95
99
|
|
|
96
100
|
if ((0, _utils.isPg)(ctx)) {
|
|
97
|
-
|
|
101
|
+
const name = ctx.fullName === fieldName ? `"${ctx.model.name}"."${fieldName}"` : `"${fieldName}"`;
|
|
102
|
+
return _sequelize().Sequelize.literal(`${name} ?| ${escape(value.map(i => `${i}`), ctx)}`);
|
|
98
103
|
}
|
|
99
104
|
|
|
100
105
|
if ((0, _utils.isMySQL)(ctx)) {
|
|
101
106
|
value = escape(JSON.stringify(value), ctx);
|
|
102
|
-
|
|
107
|
+
const name = ctx.fullName === fieldName ? `\`${ctx.model.name}\`.\`${fieldName}\`` : `\`${fieldName}\``;
|
|
108
|
+
return _sequelize().Sequelize.literal(`JSON_OVERLAPS(${name}, ${value})`);
|
|
103
109
|
}
|
|
104
110
|
|
|
105
111
|
const subQuery = sqliteExistQuery(value, ctx);
|
|
@@ -110,13 +116,15 @@ var _default = {
|
|
|
110
116
|
let where;
|
|
111
117
|
|
|
112
118
|
if ((0, _utils.isPg)(ctx)) {
|
|
113
|
-
const fieldName = getFieldName(ctx);
|
|
119
|
+
const fieldName = getFieldName(ctx);
|
|
120
|
+
const name = ctx.fullName === fieldName ? `"${ctx.model.name}"."${fieldName}"` : `"${fieldName}"`; // pg single quote
|
|
114
121
|
|
|
115
|
-
where = _sequelize().Sequelize.literal(`not (${
|
|
122
|
+
where = _sequelize().Sequelize.literal(`not (${name} ?| ${escape(value.map(i => `${i}`), ctx)})`);
|
|
116
123
|
} else if ((0, _utils.isMySQL)(ctx)) {
|
|
117
124
|
const fieldName = getFieldName(ctx);
|
|
118
125
|
value = escape(JSON.stringify(value), ctx);
|
|
119
|
-
|
|
126
|
+
const name = ctx.fullName === fieldName ? `\`${ctx.model.name}\`.\`${fieldName}\`` : `\`${fieldName}\``;
|
|
127
|
+
where = _sequelize().Sequelize.literal(`NOT JSON_OVERLAPS(${name}, ${value})`);
|
|
120
128
|
} else {
|
|
121
129
|
const subQuery = sqliteExistQuery(value, ctx);
|
|
122
130
|
where = _sequelize().Sequelize.literal(`not ${subQuery}`);
|
package/lib/operators/ne.d.ts
CHANGED
package/lib/operators/ne.js
CHANGED
|
@@ -68,6 +68,12 @@ class BelongsToManyRepository extends _multipleRelationRepository.MultipleRelati
|
|
|
68
68
|
var _this = this;
|
|
69
69
|
|
|
70
70
|
return _asyncToGenerator(function* () {
|
|
71
|
+
if (Array.isArray(options.values)) {
|
|
72
|
+
return Promise.all(options.values.map(record => _this.create(_objectSpread(_objectSpread({}, options), {}, {
|
|
73
|
+
values: record
|
|
74
|
+
}))));
|
|
75
|
+
}
|
|
76
|
+
|
|
71
77
|
const transaction = yield _this.getTransaction(options);
|
|
72
78
|
|
|
73
79
|
const createAccessor = _this.accessors().create;
|