@nocobase/database 1.3.44-beta → 1.4.0-alpha.0
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 +5 -2
- package/lib/collection.js +70 -2
- package/lib/database.d.ts +13 -23
- package/lib/database.js +28 -42
- package/lib/dialects/base-dialect.d.ts +20 -0
- package/lib/dialects/base-dialect.js +75 -0
- package/lib/dialects/index.d.ts +9 -0
- package/lib/dialects/index.js +30 -0
- package/lib/dialects/mariadb-dialect.d.ts +17 -0
- package/lib/dialects/mariadb-dialect.js +54 -0
- package/lib/dialects/mysql-dialect.d.ts +17 -0
- package/lib/dialects/mysql-dialect.js +54 -0
- package/lib/dialects/postgres-dialect.d.ts +18 -0
- package/lib/dialects/postgres-dialect.js +77 -0
- package/lib/dialects/sqlite-dialect.d.ts +17 -0
- package/lib/dialects/sqlite-dialect.js +51 -0
- package/lib/features/referential-integrity-check.js +1 -1
- package/lib/fields/date-field.d.ts +7 -2
- package/lib/fields/date-field.js +89 -0
- package/lib/fields/date-only-field.d.ts +15 -0
- package/lib/fields/date-only-field.js +45 -0
- package/lib/fields/datetime-field.d.ts +15 -0
- package/lib/fields/datetime-field.js +41 -0
- package/lib/fields/datetime-no-tz-field.d.ts +24 -0
- package/lib/fields/datetime-no-tz-field.js +128 -0
- package/lib/fields/datetime-tz-field.d.ts +15 -0
- package/lib/fields/datetime-tz-field.js +41 -0
- package/lib/fields/field.d.ts +1 -1
- package/lib/fields/field.js +3 -2
- package/lib/fields/index.d.ts +10 -1
- package/lib/fields/index.js +11 -1
- package/lib/fields/unix-timestamp-field.d.ts +22 -0
- package/lib/fields/unix-timestamp-field.js +94 -0
- package/lib/helpers.d.ts +2 -1
- package/lib/helpers.js +16 -49
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/lib/interfaces/boolean-interface.js +5 -1
- package/lib/interfaces/multiple-select-interface.js +7 -1
- package/lib/interfaces/select-interface.js +7 -1
- package/lib/interfaces/to-one-interface.js +3 -3
- package/lib/model.d.ts +1 -0
- package/lib/model.js +12 -0
- package/lib/operators/date.js +66 -24
- package/lib/options-parser.d.ts +1 -0
- package/lib/options-parser.js +36 -10
- package/lib/query-interface/query-interface-builder.js +3 -0
- package/lib/relation-repository/hasmany-repository.js +8 -11
- package/lib/relation-repository/multiple-relation-repository.d.ts +1 -0
- package/lib/relation-repository/multiple-relation-repository.js +11 -3
- package/lib/relation-repository/relation-repository.d.ts +6 -3
- package/lib/relation-repository/relation-repository.js +27 -4
- package/lib/repository.d.ts +5 -2
- package/lib/repository.js +27 -16
- package/lib/update-associations.d.ts +2 -1
- package/lib/update-associations.js +4 -3
- package/lib/view/field-type-map.d.ts +2 -2
- package/lib/view/field-type-map.js +17 -17
- package/package.json +4 -4
package/lib/options-parser.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export declare class OptionsParser {
|
|
|
26
26
|
static appendInheritInspectAttribute(include: any, collection: any): any;
|
|
27
27
|
isAssociation(key: string): boolean;
|
|
28
28
|
isAssociationPath(path: string): boolean;
|
|
29
|
+
filterByTkToWhereOption(): {};
|
|
29
30
|
toSequelizeParams(): any;
|
|
30
31
|
/**
|
|
31
32
|
* parser sort options
|
package/lib/options-parser.js
CHANGED
|
@@ -90,17 +90,34 @@ const _OptionsParser = class _OptionsParser {
|
|
|
90
90
|
isAssociationPath(path) {
|
|
91
91
|
return this.isAssociation(path.split(".")[0]);
|
|
92
92
|
}
|
|
93
|
+
filterByTkToWhereOption() {
|
|
94
|
+
var _a;
|
|
95
|
+
const filterByTkOption = (_a = this.options) == null ? void 0 : _a.filterByTk;
|
|
96
|
+
if (!filterByTkOption) {
|
|
97
|
+
return {};
|
|
98
|
+
}
|
|
99
|
+
if (import_lodash.default.isPlainObject(this.options.filterByTk)) {
|
|
100
|
+
const where = {};
|
|
101
|
+
for (const [key, value] of Object.entries(filterByTkOption)) {
|
|
102
|
+
where[key] = value;
|
|
103
|
+
}
|
|
104
|
+
return where;
|
|
105
|
+
}
|
|
106
|
+
const filterTargetKey = this.context.targetKey || this.collection.filterTargetKey;
|
|
107
|
+
if (Array.isArray(filterTargetKey)) {
|
|
108
|
+
throw new Error("multi filter target key value must be object");
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
[filterTargetKey]: filterByTkOption
|
|
112
|
+
};
|
|
113
|
+
}
|
|
93
114
|
toSequelizeParams() {
|
|
94
115
|
var _a, _b;
|
|
95
116
|
const queryParams = this.filterParser.toSequelizeParams();
|
|
96
117
|
if ((_a = this.options) == null ? void 0 : _a.filterByTk) {
|
|
118
|
+
const filterByTkWhere = this.filterByTkToWhereOption();
|
|
97
119
|
queryParams.where = {
|
|
98
|
-
[import_sequelize.Op.and]: [
|
|
99
|
-
queryParams.where,
|
|
100
|
-
{
|
|
101
|
-
[this.context.targetKey || this.collection.filterTargetKey]: this.options.filterByTk
|
|
102
|
-
}
|
|
103
|
-
]
|
|
120
|
+
[import_sequelize.Op.and]: [queryParams.where, filterByTkWhere]
|
|
104
121
|
};
|
|
105
122
|
}
|
|
106
123
|
if ((_b = this.options) == null ? void 0 : _b.include) {
|
|
@@ -123,12 +140,18 @@ const _OptionsParser = class _OptionsParser {
|
|
|
123
140
|
sort = sort.split(",");
|
|
124
141
|
}
|
|
125
142
|
let defaultSortField = this.model.primaryKeyAttribute;
|
|
126
|
-
if (
|
|
143
|
+
if (Array.isArray(this.collection.filterTargetKey)) {
|
|
144
|
+
defaultSortField = this.collection.filterTargetKey;
|
|
145
|
+
}
|
|
146
|
+
if (!defaultSortField && this.collection.filterTargetKey && !Array.isArray(this.collection.filterTargetKey)) {
|
|
127
147
|
defaultSortField = this.collection.filterTargetKey;
|
|
128
148
|
}
|
|
129
149
|
if (defaultSortField && !((_b = this.options) == null ? void 0 : _b.group)) {
|
|
130
|
-
|
|
131
|
-
|
|
150
|
+
defaultSortField = import_lodash.default.castArray(defaultSortField);
|
|
151
|
+
for (const key of defaultSortField) {
|
|
152
|
+
if (!sort.includes(key)) {
|
|
153
|
+
sort.push(key);
|
|
154
|
+
}
|
|
132
155
|
}
|
|
133
156
|
}
|
|
134
157
|
const orderParams = [];
|
|
@@ -151,7 +174,10 @@ const _OptionsParser = class _OptionsParser {
|
|
|
151
174
|
}
|
|
152
175
|
sortField.push(direction);
|
|
153
176
|
if (this.database.isMySQLCompatibleDialect()) {
|
|
154
|
-
|
|
177
|
+
const fieldName = sortField[0];
|
|
178
|
+
if (this.model.fieldRawAttributesMap[fieldName]) {
|
|
179
|
+
orderParams.push([import_sequelize.Sequelize.fn("ISNULL", import_sequelize.Sequelize.col(`${this.model.name}.${sortField[0]}`))]);
|
|
180
|
+
}
|
|
155
181
|
}
|
|
156
182
|
orderParams.push(sortField);
|
|
157
183
|
}
|
|
@@ -50,6 +50,9 @@ function buildQueryInterface(db) {
|
|
|
50
50
|
postgres: import_postgres_query_interface.default,
|
|
51
51
|
sqlite: import_sqlite_query_interface.default
|
|
52
52
|
};
|
|
53
|
+
if (db.isPostgresCompatibleDialect()) {
|
|
54
|
+
return new import_postgres_query_interface.default(db);
|
|
55
|
+
}
|
|
53
56
|
const dialect = db.options.dialect;
|
|
54
57
|
if (!map[dialect]) {
|
|
55
58
|
return null;
|
|
@@ -45,29 +45,26 @@ var import_relation_repository = require("./relation-repository");
|
|
|
45
45
|
const _HasManyRepository = class _HasManyRepository extends import_multiple_relation_repository.MultipleRelationRepository {
|
|
46
46
|
async find(options) {
|
|
47
47
|
const targetRepository = this.targetCollection.repository;
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
const targetFilterOptions = await this.targetRepositoryFilterOptionsBySourceValue();
|
|
49
|
+
const findOptionsOmit = ["where", "values", "attributes"];
|
|
50
|
+
if ((options == null ? void 0 : options.filterByTk) && !this.isMultiTargetKey(options.filterByTk)) {
|
|
51
|
+
targetFilterOptions[this.associationField.targetKey] = options.filterByTk;
|
|
52
|
+
findOptionsOmit.push("filterByTk");
|
|
53
53
|
}
|
|
54
54
|
const findOptions = {
|
|
55
|
-
...(0, import_lodash.omit)(options,
|
|
55
|
+
...(0, import_lodash.omit)(options, findOptionsOmit),
|
|
56
56
|
filter: {
|
|
57
|
-
$and: [options.filter || {},
|
|
57
|
+
$and: [(options == null ? void 0 : options.filter) || {}, targetFilterOptions]
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
60
|
return await targetRepository.find(findOptions);
|
|
61
61
|
}
|
|
62
62
|
async aggregate(options) {
|
|
63
63
|
const targetRepository = this.targetCollection.repository;
|
|
64
|
-
const addFilter = {
|
|
65
|
-
[this.association.foreignKey]: this.sourceKeyValue
|
|
66
|
-
};
|
|
67
64
|
const aggOptions = {
|
|
68
65
|
...options,
|
|
69
66
|
filter: {
|
|
70
|
-
$and: [options.filter || {},
|
|
67
|
+
$and: [options.filter || {}, await this.targetRepositoryFilterOptionsBySourceValue()]
|
|
71
68
|
}
|
|
72
69
|
};
|
|
73
70
|
return await targetRepository.aggregate(aggOptions);
|
|
@@ -14,6 +14,7 @@ export interface AssociatedOptions extends Transactionable {
|
|
|
14
14
|
tk?: TK;
|
|
15
15
|
}
|
|
16
16
|
export declare abstract class MultipleRelationRepository extends RelationRepository {
|
|
17
|
+
targetRepositoryFilterOptionsBySourceValue(): Promise<any>;
|
|
17
18
|
find(options?: FindOptions): Promise<any>;
|
|
18
19
|
findAndCount(options?: FindAndCountOptions): Promise<[any[], number]>;
|
|
19
20
|
count(options?: CountOptions): Promise<number>;
|
|
@@ -55,6 +55,16 @@ var import_update_associations = require("../update-associations");
|
|
|
55
55
|
var import_update_guard = require("../update-guard");
|
|
56
56
|
var import_relation_repository = require("./relation-repository");
|
|
57
57
|
const _MultipleRelationRepository = class _MultipleRelationRepository extends import_relation_repository.RelationRepository {
|
|
58
|
+
async targetRepositoryFilterOptionsBySourceValue() {
|
|
59
|
+
let filterForeignKeyValue = this.sourceKeyValue;
|
|
60
|
+
if (this.isMultiTargetKey()) {
|
|
61
|
+
const sourceModel = await this.getSourceModel();
|
|
62
|
+
filterForeignKeyValue = sourceModel.get(this.association.sourceKey);
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
[this.association.foreignKey]: filterForeignKeyValue
|
|
66
|
+
};
|
|
67
|
+
}
|
|
58
68
|
async find(options) {
|
|
59
69
|
const targetRepository = this.targetCollection.repository;
|
|
60
70
|
const association = this.association;
|
|
@@ -68,9 +78,7 @@ const _MultipleRelationRepository = class _MultipleRelationRepository extends im
|
|
|
68
78
|
const appendFilter = {
|
|
69
79
|
isPivotFilter: true,
|
|
70
80
|
association: pivotAssoc,
|
|
71
|
-
where:
|
|
72
|
-
[association.foreignKey]: this.sourceKeyValue
|
|
73
|
-
}
|
|
81
|
+
where: await this.targetRepositoryFilterOptionsBySourceValue()
|
|
74
82
|
};
|
|
75
83
|
return targetRepository.find({
|
|
76
84
|
include: [appendFilter],
|
|
@@ -11,7 +11,7 @@ import { Collection } from '../collection';
|
|
|
11
11
|
import Database from '../database';
|
|
12
12
|
import { RelationField } from '../fields/relation-field';
|
|
13
13
|
import { Model } from '../model';
|
|
14
|
-
import { CreateOptions, Filter, FindOptions } from '../repository';
|
|
14
|
+
import { CreateOptions, Filter, FindOptions, TargetKey } from '../repository';
|
|
15
15
|
export declare const transaction: (transactionInjector?: any) => (target: any, name: any, descriptor: any) => any;
|
|
16
16
|
export declare abstract class RelationRepository {
|
|
17
17
|
sourceCollection: Collection;
|
|
@@ -20,11 +20,14 @@ export declare abstract class RelationRepository {
|
|
|
20
20
|
targetCollection: Collection;
|
|
21
21
|
associationName: string;
|
|
22
22
|
associationField: RelationField;
|
|
23
|
-
sourceKeyValue:
|
|
23
|
+
sourceKeyValue: TargetKey;
|
|
24
24
|
sourceInstance: Model;
|
|
25
25
|
db: Database;
|
|
26
26
|
database: Database;
|
|
27
|
-
constructor(sourceCollection: Collection, association: string, sourceKeyValue:
|
|
27
|
+
constructor(sourceCollection: Collection, association: string, sourceKeyValue: TargetKey);
|
|
28
|
+
decodeMultiTargetKey(str: string): any;
|
|
29
|
+
setSourceKeyValue(sourceKeyValue: TargetKey): void;
|
|
30
|
+
isMultiTargetKey(value?: any): boolean;
|
|
28
31
|
get collection(): Collection<any, any>;
|
|
29
32
|
abstract find(options?: FindOptions): Promise<any>;
|
|
30
33
|
chunk(options: FindOptions & {
|
|
@@ -73,13 +73,27 @@ const _RelationRepository = class _RelationRepository {
|
|
|
73
73
|
this.db = sourceCollection.context.database;
|
|
74
74
|
this.database = this.db;
|
|
75
75
|
this.sourceCollection = sourceCollection;
|
|
76
|
-
this.sourceKeyValue
|
|
76
|
+
this.setSourceKeyValue(sourceKeyValue);
|
|
77
77
|
this.associationName = association;
|
|
78
78
|
this.association = this.sourceCollection.model.associations[association];
|
|
79
79
|
this.associationField = this.sourceCollection.getField(association);
|
|
80
80
|
this.targetModel = this.association.target;
|
|
81
81
|
this.targetCollection = this.sourceCollection.context.database.modelCollection.get(this.targetModel);
|
|
82
82
|
}
|
|
83
|
+
decodeMultiTargetKey(str) {
|
|
84
|
+
try {
|
|
85
|
+
const decoded = decodeURIComponent(str);
|
|
86
|
+
return JSON.parse(decoded);
|
|
87
|
+
} catch (e) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
setSourceKeyValue(sourceKeyValue) {
|
|
92
|
+
this.sourceKeyValue = typeof sourceKeyValue === "string" ? this.decodeMultiTargetKey(sourceKeyValue) || sourceKeyValue : sourceKeyValue;
|
|
93
|
+
}
|
|
94
|
+
isMultiTargetKey(value) {
|
|
95
|
+
return import_lodash.default.isPlainObject(value || this.sourceKeyValue);
|
|
96
|
+
}
|
|
83
97
|
get collection() {
|
|
84
98
|
return this.db.getCollection(this.targetModel.name);
|
|
85
99
|
}
|
|
@@ -109,7 +123,7 @@ const _RelationRepository = class _RelationRepository {
|
|
|
109
123
|
}
|
|
110
124
|
convertTk(options) {
|
|
111
125
|
let tk = options;
|
|
112
|
-
if (typeof options === "object" &&
|
|
126
|
+
if (typeof options === "object" && "tk" in options) {
|
|
113
127
|
tk = options["tk"];
|
|
114
128
|
}
|
|
115
129
|
return tk;
|
|
@@ -119,7 +133,10 @@ const _RelationRepository = class _RelationRepository {
|
|
|
119
133
|
if (typeof tk === "string") {
|
|
120
134
|
tk = tk.split(",");
|
|
121
135
|
}
|
|
122
|
-
|
|
136
|
+
if (tk) {
|
|
137
|
+
return import_lodash.default.castArray(tk);
|
|
138
|
+
}
|
|
139
|
+
return [];
|
|
123
140
|
}
|
|
124
141
|
targetKey() {
|
|
125
142
|
return this.associationField.targetKey;
|
|
@@ -147,7 +164,13 @@ const _RelationRepository = class _RelationRepository {
|
|
|
147
164
|
}
|
|
148
165
|
async getSourceModel(transaction2) {
|
|
149
166
|
if (!this.sourceInstance) {
|
|
150
|
-
this.sourceInstance = await this.sourceCollection.
|
|
167
|
+
this.sourceInstance = this.isMultiTargetKey() ? await this.sourceCollection.repository.findOne({
|
|
168
|
+
filter: {
|
|
169
|
+
// @ts-ignore
|
|
170
|
+
...this.sourceKeyValue
|
|
171
|
+
},
|
|
172
|
+
transaction: transaction2
|
|
173
|
+
}) : await this.sourceCollection.model.findOne({
|
|
151
174
|
where: {
|
|
152
175
|
[this.associationField.sourceKey]: this.sourceKeyValue
|
|
153
176
|
},
|
package/lib/repository.d.ts
CHANGED
|
@@ -26,7 +26,9 @@ export { Transactionable } from 'sequelize';
|
|
|
26
26
|
export interface FilterAble {
|
|
27
27
|
filter: Filter;
|
|
28
28
|
}
|
|
29
|
-
export type
|
|
29
|
+
export type BaseTargetKey = string | number;
|
|
30
|
+
export type MultiTargetKey = Record<string, BaseTargetKey>;
|
|
31
|
+
export type TargetKey = BaseTargetKey | MultiTargetKey;
|
|
30
32
|
export type TK = TargetKey | TargetKey[];
|
|
31
33
|
type FieldValue = string | number | bigint | boolean | Date | Buffer | null | FieldValue[] | FilterWithOperator;
|
|
32
34
|
type Operators = keyof typeof operators & keyof WhereOperators;
|
|
@@ -116,7 +118,7 @@ declare class RelationRepositoryBuilder<R extends RelationRepository> {
|
|
|
116
118
|
BelongsToArray: typeof BelongsToArrayRepository;
|
|
117
119
|
};
|
|
118
120
|
constructor(collection: Collection, associationName: string);
|
|
119
|
-
of(id:
|
|
121
|
+
of(id: TargetKey): R;
|
|
120
122
|
protected builder(): {
|
|
121
123
|
HasOne: typeof HasOneRepository;
|
|
122
124
|
BelongsTo: typeof BelongsToRepository;
|
|
@@ -171,6 +173,7 @@ export declare class Repository<TModelAttributes extends {} = any, TCreationAttr
|
|
|
171
173
|
*
|
|
172
174
|
*/
|
|
173
175
|
findById(id: string | number): Promise<Model<any, any>>;
|
|
176
|
+
findByTargetKey(targetKey: TargetKey): Promise<any>;
|
|
174
177
|
/**
|
|
175
178
|
* Find one record from database
|
|
176
179
|
*
|
package/lib/repository.js
CHANGED
|
@@ -175,27 +175,24 @@ const _Repository = class _Repository {
|
|
|
175
175
|
};
|
|
176
176
|
}
|
|
177
177
|
if (countOptions == null ? void 0 : countOptions.filterByTk) {
|
|
178
|
+
const optionParser = new import_options_parser.OptionsParser(options, {
|
|
179
|
+
collection: this.collection
|
|
180
|
+
});
|
|
178
181
|
options["where"] = {
|
|
179
|
-
[import_sequelize.Op.and]: [
|
|
180
|
-
options["where"] || {},
|
|
181
|
-
{
|
|
182
|
-
[this.collection.filterTargetKey]: options.filterByTk
|
|
183
|
-
}
|
|
184
|
-
]
|
|
182
|
+
[import_sequelize.Op.and]: [options["where"] || {}, optionParser.filterByTkToWhereOption()]
|
|
185
183
|
};
|
|
186
184
|
}
|
|
187
185
|
const queryOptions = {
|
|
188
186
|
...options,
|
|
189
|
-
distinct: Boolean(this.collection.model.primaryKeyAttribute)
|
|
187
|
+
distinct: Boolean(this.collection.model.primaryKeyAttribute) && !this.collection.isMultiFilterTargetKey()
|
|
190
188
|
};
|
|
191
189
|
if (((_a = queryOptions.include) == null ? void 0 : _a.length) === 0) {
|
|
192
190
|
delete queryOptions.include;
|
|
193
191
|
}
|
|
194
|
-
|
|
192
|
+
return await this.collection.model.count({
|
|
195
193
|
...queryOptions,
|
|
196
194
|
transaction: transaction2
|
|
197
195
|
});
|
|
198
|
-
return count;
|
|
199
196
|
}
|
|
200
197
|
async aggregate(options) {
|
|
201
198
|
var _a;
|
|
@@ -325,6 +322,9 @@ const _Repository = class _Repository {
|
|
|
325
322
|
findById(id) {
|
|
326
323
|
return this.collection.model.findByPk(id);
|
|
327
324
|
}
|
|
325
|
+
findByTargetKey(targetKey) {
|
|
326
|
+
return this.findOne({ filterByTk: targetKey });
|
|
327
|
+
}
|
|
328
328
|
/**
|
|
329
329
|
* Find one record from database
|
|
330
330
|
*
|
|
@@ -374,7 +374,7 @@ const _Repository = class _Repository {
|
|
|
374
374
|
action: "create",
|
|
375
375
|
underscored: this.collection.options.underscored
|
|
376
376
|
});
|
|
377
|
-
const values = guard.sanitize(options.values || {});
|
|
377
|
+
const values = this.model.callSetters(guard.sanitize(options.values || {}), options);
|
|
378
378
|
const instance = await this.model.create(values, {
|
|
379
379
|
...options,
|
|
380
380
|
transaction: transaction2
|
|
@@ -418,7 +418,7 @@ const _Repository = class _Repository {
|
|
|
418
418
|
}
|
|
419
419
|
const transaction2 = await this.getTransaction(options);
|
|
420
420
|
const guard = import_update_guard.UpdateGuard.fromOptions(this.model, { ...options, underscored: this.collection.options.underscored });
|
|
421
|
-
const values = guard.sanitize(options.values);
|
|
421
|
+
const values = this.model.callSetters(guard.sanitize(options.values || {}), options);
|
|
422
422
|
if (options.individualHooks === false) {
|
|
423
423
|
const { model: Model2 } = this.collection;
|
|
424
424
|
const primaryKeyField = Model2.primaryKeyField || Model2.primaryKeyAttribute;
|
|
@@ -501,15 +501,26 @@ const _Repository = class _Repository {
|
|
|
501
501
|
}
|
|
502
502
|
}
|
|
503
503
|
if (filterByTk && !options.filter) {
|
|
504
|
-
|
|
504
|
+
const where = [];
|
|
505
|
+
for (const tk of filterByTk) {
|
|
506
|
+
const optionParser = new import_options_parser.OptionsParser(
|
|
507
|
+
{
|
|
508
|
+
filterByTk: tk
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
collection: this.collection
|
|
512
|
+
}
|
|
513
|
+
);
|
|
514
|
+
where.push(optionParser.filterByTkToWhereOption());
|
|
515
|
+
}
|
|
516
|
+
const destroyOptions = {
|
|
505
517
|
...options,
|
|
506
518
|
where: {
|
|
507
|
-
[
|
|
508
|
-
[import_sequelize.Op.in]: filterByTk
|
|
509
|
-
}
|
|
519
|
+
[import_sequelize.Op.or]: where
|
|
510
520
|
},
|
|
511
521
|
transaction: transaction2
|
|
512
|
-
}
|
|
522
|
+
};
|
|
523
|
+
return await this.model.destroy(destroyOptions);
|
|
513
524
|
}
|
|
514
525
|
if (options.filter && (0, import_utils.isValidFilter)(options.filter)) {
|
|
515
526
|
if (this.collection.model.primaryKeyAttributes.length !== 1 && !import_lodash.default.get(this.collection.options, "filterTargetKey")) {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Association, BelongsToMany, Hookable, Transactionable } from 'sequelize';
|
|
10
10
|
import { Model } from './model';
|
|
11
|
+
import { TargetKey } from './repository';
|
|
11
12
|
export declare function modelAssociations(instance: Model): {
|
|
12
13
|
[key: string]: Association<import("sequelize").Model<any, any>, import("sequelize").Model<any, any>>;
|
|
13
14
|
};
|
|
@@ -18,7 +19,7 @@ type UpdateValue = {
|
|
|
18
19
|
};
|
|
19
20
|
interface UpdateOptions extends Transactionable {
|
|
20
21
|
filter?: any;
|
|
21
|
-
filterByTk?:
|
|
22
|
+
filterByTk?: TargetKey;
|
|
22
23
|
whitelist?: string[];
|
|
23
24
|
blacklist?: string[];
|
|
24
25
|
updateAssociationValues?: string[];
|
|
@@ -323,7 +323,7 @@ async function updateMultipleAssociation(model, key, value, options = {}) {
|
|
|
323
323
|
} else if (item.sequelize) {
|
|
324
324
|
setItems.push(item);
|
|
325
325
|
} else if (typeof item === "object") {
|
|
326
|
-
const targetKey2 = association.targetKey || "id";
|
|
326
|
+
const targetKey2 = association.targetKey || association.options.targetKey || "id";
|
|
327
327
|
if (item[targetKey2]) {
|
|
328
328
|
const attributes = {
|
|
329
329
|
[targetKey2]: item[targetKey2]
|
|
@@ -337,9 +337,9 @@ async function updateMultipleAssociation(model, key, value, options = {}) {
|
|
|
337
337
|
await model[setAccessor](setItems, { transaction, context, individualHooks: true });
|
|
338
338
|
const newItems = [];
|
|
339
339
|
const pk = association.target.primaryKeyAttribute;
|
|
340
|
-
const tmpKey = (_a = association["options"]) == null ? void 0 : _a["targetKey"];
|
|
341
340
|
let targetKey = pk;
|
|
342
341
|
const db = model.constructor["database"];
|
|
342
|
+
const tmpKey = (_a = association["options"]) == null ? void 0 : _a["targetKey"];
|
|
343
343
|
if (tmpKey !== pk) {
|
|
344
344
|
const targetKeyFieldOptions = (_b = db.getFieldByPath(`${association.target.name}.${tmpKey}`)) == null ? void 0 : _b.options;
|
|
345
345
|
if (targetKeyFieldOptions == null ? void 0 : targetKeyFieldOptions.unique) {
|
|
@@ -405,7 +405,8 @@ async function updateMultipleAssociation(model, key, value, options = {}) {
|
|
|
405
405
|
}
|
|
406
406
|
}
|
|
407
407
|
for (const newItem of newItems) {
|
|
408
|
-
const
|
|
408
|
+
const findTargetKey = association.targetKey || association.options.targetKey || targetKey;
|
|
409
|
+
const existIndexInSetItems = setItems.findIndex((setItem) => setItem[findTargetKey] === newItem[findTargetKey]);
|
|
409
410
|
if (existIndexInSetItems !== -1) {
|
|
410
411
|
setItems[existIndexInSetItems] = newItem;
|
|
411
412
|
} else {
|
|
@@ -62,7 +62,7 @@ declare const fieldTypeMap: {
|
|
|
62
62
|
boolean: string;
|
|
63
63
|
decimal: string;
|
|
64
64
|
year: string[];
|
|
65
|
-
datetime: string;
|
|
65
|
+
datetime: string[];
|
|
66
66
|
timestamp: string;
|
|
67
67
|
json: string[];
|
|
68
68
|
enum: string;
|
|
@@ -104,7 +104,7 @@ declare const fieldTypeMap: {
|
|
|
104
104
|
boolean: string;
|
|
105
105
|
decimal: string;
|
|
106
106
|
year: string[];
|
|
107
|
-
datetime: string;
|
|
107
|
+
datetime: string[];
|
|
108
108
|
timestamp: string;
|
|
109
109
|
json: string[];
|
|
110
110
|
enum: string;
|
|
@@ -30,24 +30,24 @@ __export(field_type_map_exports, {
|
|
|
30
30
|
});
|
|
31
31
|
module.exports = __toCommonJS(field_type_map_exports);
|
|
32
32
|
const postgres = {
|
|
33
|
-
"character varying": ["string", "uuid", "nanoid", "encryption"],
|
|
34
|
-
varchar: ["string", "uuid", "nanoid", "encryption"],
|
|
35
|
-
char: ["string", "uuid", "nanoid", "encryption"],
|
|
33
|
+
"character varying": ["string", "uuid", "nanoid", "encryption", "datetimeNoTz"],
|
|
34
|
+
varchar: ["string", "uuid", "nanoid", "encryption", "datetimeNoTz"],
|
|
35
|
+
char: ["string", "uuid", "nanoid", "encryption", "datetimeNoTz"],
|
|
36
36
|
character: "string",
|
|
37
37
|
text: "text",
|
|
38
38
|
oid: "string",
|
|
39
39
|
name: "string",
|
|
40
40
|
smallint: ["integer", "sort"],
|
|
41
|
-
integer: ["integer", "sort"],
|
|
42
|
-
bigint: ["bigInt", "sort"],
|
|
41
|
+
integer: ["integer", "unixTimestamp", "sort"],
|
|
42
|
+
bigint: ["bigInt", "unixTimestamp", "sort"],
|
|
43
43
|
decimal: "decimal",
|
|
44
44
|
numeric: "float",
|
|
45
45
|
real: "float",
|
|
46
46
|
"double precision": "float",
|
|
47
|
-
"timestamp without time zone": "
|
|
48
|
-
"timestamp with time zone": "
|
|
47
|
+
"timestamp without time zone": "datetimeNoTz",
|
|
48
|
+
"timestamp with time zone": "datetimeTz",
|
|
49
49
|
"time without time zone": "time",
|
|
50
|
-
date: "
|
|
50
|
+
date: "dateOnly",
|
|
51
51
|
boolean: "boolean",
|
|
52
52
|
json: ["json", "array"],
|
|
53
53
|
jsonb: ["json", "array", "jsonb"],
|
|
@@ -68,24 +68,24 @@ const mysql = {
|
|
|
68
68
|
"mediumint unsigned": ["integer", "boolean", "sort"],
|
|
69
69
|
char: ["string", "uuid", "nanoid", "encryption"],
|
|
70
70
|
varchar: ["string", "uuid", "nanoid", "encryption"],
|
|
71
|
-
date: "
|
|
71
|
+
date: "dateOnly",
|
|
72
72
|
time: "time",
|
|
73
73
|
tinytext: "text",
|
|
74
74
|
text: "text",
|
|
75
75
|
mediumtext: "text",
|
|
76
76
|
longtext: "text",
|
|
77
|
-
int: ["integer", "sort"],
|
|
78
|
-
"int unsigned": ["integer", "sort"],
|
|
79
|
-
integer: ["integer", "sort"],
|
|
80
|
-
bigint: ["bigInt", "sort"],
|
|
81
|
-
"bigint unsigned": ["bigInt", "sort"],
|
|
77
|
+
int: ["integer", "unixTimestamp", "sort"],
|
|
78
|
+
"int unsigned": ["integer", "unixTimestamp", "sort"],
|
|
79
|
+
integer: ["integer", "unixTimestamp", "sort"],
|
|
80
|
+
bigint: ["bigInt", "unixTimestamp", "sort"],
|
|
81
|
+
"bigint unsigned": ["bigInt", "unixTimestamp", "sort"],
|
|
82
82
|
float: "float",
|
|
83
83
|
double: "float",
|
|
84
84
|
boolean: "boolean",
|
|
85
85
|
decimal: "decimal",
|
|
86
86
|
year: ["string", "integer"],
|
|
87
|
-
datetime: "
|
|
88
|
-
timestamp: "
|
|
87
|
+
datetime: ["datetimeNoTz", "datetimeTz"],
|
|
88
|
+
timestamp: "datetimeTz",
|
|
89
89
|
json: ["json", "array"],
|
|
90
90
|
enum: "string"
|
|
91
91
|
};
|
|
@@ -94,7 +94,7 @@ const sqlite = {
|
|
|
94
94
|
varchar: ["string", "uuid", "nanoid", "encryption"],
|
|
95
95
|
integer: "integer",
|
|
96
96
|
real: "real",
|
|
97
|
-
datetime: "
|
|
97
|
+
datetime: "datetimeTz",
|
|
98
98
|
date: "date",
|
|
99
99
|
time: "time",
|
|
100
100
|
boolean: "boolean",
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/database",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0-alpha.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
7
7
|
"license": "AGPL-3.0",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@nocobase/logger": "1.
|
|
10
|
-
"@nocobase/utils": "1.
|
|
9
|
+
"@nocobase/logger": "1.4.0-alpha.0",
|
|
10
|
+
"@nocobase/utils": "1.4.0-alpha.0",
|
|
11
11
|
"async-mutex": "^0.3.2",
|
|
12
12
|
"chalk": "^4.1.1",
|
|
13
13
|
"cron-parser": "4.4.0",
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"url": "git+https://github.com/nocobase/nocobase.git",
|
|
39
39
|
"directory": "packages/database"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "8ffa7b54bbaf720c0c9857da4b19a99110dffc4b"
|
|
42
42
|
}
|