vona-module-a-orm 5.0.37
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/LICENSE +21 -0
- package/cli/databaseDialect/boilerplate/{{sceneName}}.{{beanName}}.ts_ +4 -0
- package/cli/entity/boilerplate/{{beanName}}.ts_ +7 -0
- package/cli/entity/metadata/generate.ts +52 -0
- package/cli/model/boilerplate/{{beanName}}.ts_ +8 -0
- package/cli/model/metadata/generate.ts +285 -0
- package/dist/.metadata/index.d.ts +246 -0
- package/dist/.metadata/this.d.ts +2 -0
- package/dist/bean/aopMethod.transaction.d.ts +9 -0
- package/dist/bean/bean.database.d.ts +12 -0
- package/dist/bean/bean.databaseDialectBase.d.ts +20 -0
- package/dist/bean/bean.model/bean.model_cache.d.ts +56 -0
- package/dist/bean/bean.model/bean.model_crud.d.ts +13 -0
- package/dist/bean/bean.model/bean.model_crud_inner.d.ts +15 -0
- package/dist/bean/bean.model/bean.model_crud_table.d.ts +13 -0
- package/dist/bean/bean.model/bean.model_knex.d.ts +15 -0
- package/dist/bean/bean.model/bean.model_meta.d.ts +40 -0
- package/dist/bean/bean.model/bean.model_utils.d.ts +39 -0
- package/dist/bean/bean.model/bean.model_view.d.ts +14 -0
- package/dist/bean/bean.model.d.ts +3 -0
- package/dist/bean/bean.modelBase.d.ts +3 -0
- package/dist/bean/broadcast.columnsClear.d.ts +10 -0
- package/dist/bean/broadcast.databaseClientReload.d.ts +12 -0
- package/dist/bean/event.clientNameReal.d.ts +6 -0
- package/dist/bean/event.columnsClear.d.ts +9 -0
- package/dist/bean/event.databaseClientReload.d.ts +11 -0
- package/dist/bean/schedule.softDeletionPrune.d.ts +6 -0
- package/dist/common/buildWhere.d.ts +4 -0
- package/dist/common/checkWhere.d.ts +1 -0
- package/dist/common/index.d.ts +3 -0
- package/dist/common/utils.d.ts +10 -0
- package/dist/config/config.d.ts +72 -0
- package/dist/config/errors.d.ts +3 -0
- package/dist/config/locale/en-us.d.ts +9 -0
- package/dist/config/locale/zh-cn.d.ts +9 -0
- package/dist/extend/index.d.ts +4 -0
- package/dist/extend/schemaBuilder.d.ts +13 -0
- package/dist/extend/tableBuilder.d.ts +22 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +4085 -0
- package/dist/lib/columns.d.ts +9 -0
- package/dist/lib/database.d.ts +6 -0
- package/dist/lib/databaseDialect.d.ts +1 -0
- package/dist/lib/dto/dto.d.ts +12 -0
- package/dist/lib/dto/dtoAggregate.d.ts +8 -0
- package/dist/lib/dto/dtoCreate.d.ts +5 -0
- package/dist/lib/dto/dtoGet.d.ts +8 -0
- package/dist/lib/dto/dtoGroup.d.ts +8 -0
- package/dist/lib/dto/dtoMutate.d.ts +8 -0
- package/dist/lib/dto/dtoUpdate.d.ts +5 -0
- package/dist/lib/dto/index.d.ts +1 -0
- package/dist/lib/entity.d.ts +3 -0
- package/dist/lib/index.d.ts +10 -0
- package/dist/lib/model.d.ts +2 -0
- package/dist/lib/modelCacheBase.d.ts +20 -0
- package/dist/lib/relations.d.ts +15 -0
- package/dist/lib/relationsDynamic.d.ts +15 -0
- package/dist/lib/relationsMutate.d.ts +14 -0
- package/dist/lib/relationsStatic.d.ts +9 -0
- package/dist/main.d.ts +9 -0
- package/dist/service/cacheEntity_.d.ts +10 -0
- package/dist/service/cacheQuery_.d.ts +7 -0
- package/dist/service/columnsCache_.d.ts +22 -0
- package/dist/service/columns_.d.ts +13 -0
- package/dist/service/database.d.ts +17 -0
- package/dist/service/databaseAsyncLocalStorage_.d.ts +10 -0
- package/dist/service/databaseClient_.d.ts +30 -0
- package/dist/service/db_.d.ts +26 -0
- package/dist/service/entityResolver_.d.ts +9 -0
- package/dist/service/modelResolver_.d.ts +8 -0
- package/dist/service/relations_.d.ts +19 -0
- package/dist/service/transactionAsyncLocalStorage_.d.ts +10 -0
- package/dist/service/transactionConsistency/342/200/214_.d.ts +10 -0
- package/dist/service/transactionFiber_.d.ts +13 -0
- package/dist/service/transactionState_.d.ts +11 -0
- package/dist/service/transaction_.d.ts +18 -0
- package/dist/types/columns.d.ts +6 -0
- package/dist/types/config.d.ts +14 -0
- package/dist/types/database.d.ts +47 -0
- package/dist/types/dialect.d.ts +6 -0
- package/dist/types/dto/dtoAggregate.d.ts +2 -0
- package/dist/types/dto/dtoGet.d.ts +12 -0
- package/dist/types/dto/dtoGroup.d.ts +2 -0
- package/dist/types/dto/dtoMutate.d.ts +14 -0
- package/dist/types/dto/index.d.ts +4 -0
- package/dist/types/entity.d.ts +15 -0
- package/dist/types/entityBase.d.ts +5 -0
- package/dist/types/entityBaseEmpty.d.ts +2 -0
- package/dist/types/entityBaseInner.d.ts +7 -0
- package/dist/types/entityBaseSimple.d.ts +4 -0
- package/dist/types/extra.d.ts +11 -0
- package/dist/types/index.d.ts +30 -0
- package/dist/types/logger.d.ts +7 -0
- package/dist/types/model.d.ts +79 -0
- package/dist/types/modelAggr.d.ts +26 -0
- package/dist/types/modelCount.d.ts +15 -0
- package/dist/types/modelGeneral.d.ts +23 -0
- package/dist/types/modelGroup.d.ts +23 -0
- package/dist/types/modelWhere.d.ts +86 -0
- package/dist/types/onion/databaseDialect.d.ts +17 -0
- package/dist/types/onion/entity.d.ts +26 -0
- package/dist/types/onion/index.d.ts +4 -0
- package/dist/types/onion/model.d.ts +55 -0
- package/dist/types/onion/table.d.ts +2 -0
- package/dist/types/relations.d.ts +102 -0
- package/dist/types/relationsAggr.d.ts +16 -0
- package/dist/types/relationsColumns.d.ts +45 -0
- package/dist/types/relationsDef.d.ts +59 -0
- package/dist/types/relationsDefDynamic.d.ts +56 -0
- package/dist/types/relationsDefMutate.d.ts +9 -0
- package/dist/types/relationsGroup.d.ts +21 -0
- package/dist/types/relationsMutate.d.ts +25 -0
- package/dist/types/relationsTables.d.ts +15 -0
- package/dist/types/tableIdentity.d.ts +1 -0
- package/dist/types/transaction.d.ts +18 -0
- package/package.json +74 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,4085 @@
|
|
|
1
|
+
import { BigNumber } from 'bignumber.js';
|
|
2
|
+
import { BeanInfo, BeanAopMethodBase, BeanBase, deepExtend, Virtual, appResource, beanFullNameFromOnionName, cast, appMetadata, useApp, BeanSimple, combineConfigDefault, BeanScopeBase, createBeanDecorator, PickClassInner, $Class } from 'vona';
|
|
3
|
+
import { AopMethod, Aspect } from 'vona-module-a-aspect';
|
|
4
|
+
import { Service, Bean, Scope } from 'vona-module-a-bean';
|
|
5
|
+
import { AsyncLocalStorage, AsyncResource } from 'node:async_hooks';
|
|
6
|
+
import knex from 'knex';
|
|
7
|
+
import { isNil, safeBoolean, isClass, ensureArray, hashkey } from '@cabloy/utils';
|
|
8
|
+
import { swapDeps } from '@cabloy/deps';
|
|
9
|
+
import { prepareClassType, getTargetDecoratorRules, Api, v, OrderMaxBase, OrderCoreBase, getSchemaDynamic, SymbolSchemaDynamicRefId, addSchemaDynamic, mergeFieldsOpenapiMetadata } from 'vona-module-a-openapi';
|
|
10
|
+
import { ZodMetadata } from '@cabloy/zod-query';
|
|
11
|
+
import { SymbolDecoratorRuleColumn } from 'vona-module-a-openapiutils';
|
|
12
|
+
export * from 'table-identity';
|
|
13
|
+
import { Broadcast, BeanBroadcastBase } from 'vona-module-a-broadcast';
|
|
14
|
+
import { Event, BeanEventBase } from 'vona-module-a-event';
|
|
15
|
+
import { Schedule } from 'vona-module-a-schedule';
|
|
16
|
+
import { configAllWithIgnoreNull, configAll, configRedisWithIgnoreNull, configRedis } from 'vona-module-a-summer';
|
|
17
|
+
import { ServiceDatabaseAsyncLocalStorage as ServiceDatabaseAsyncLocalStorage$1, ServiceTransactionConsistency as ServiceTransactionConsistency_ } from 'vona-module-a-orm';
|
|
18
|
+
|
|
19
|
+
var _dec$u, _dec2$u, _class$u;
|
|
20
|
+
let AopMethodTransaction = (_dec$u = AopMethod(), _dec2$u = BeanInfo({
|
|
21
|
+
module: "a-orm"
|
|
22
|
+
}), _dec$u(_class$u = _dec2$u(_class$u = class AopMethodTransaction extends BeanAopMethodBase {
|
|
23
|
+
execute(options, _args, next, _receiver, _prop) {
|
|
24
|
+
return this.bean.database.current.transaction.begin(() => {
|
|
25
|
+
return next();
|
|
26
|
+
}, options);
|
|
27
|
+
}
|
|
28
|
+
}) || _class$u) || _class$u);
|
|
29
|
+
|
|
30
|
+
var _dec$t, _dec2$t, _class$t;
|
|
31
|
+
let ServiceDatabaseAsyncLocalStorage = (_dec$t = Service(), _dec2$t = BeanInfo({
|
|
32
|
+
module: "a-orm"
|
|
33
|
+
}), _dec$t(_class$t = _dec2$t(_class$t = class ServiceDatabaseAsyncLocalStorage extends BeanBase {
|
|
34
|
+
constructor(...args) {
|
|
35
|
+
super(...args);
|
|
36
|
+
this.dbStorage = void 0;
|
|
37
|
+
}
|
|
38
|
+
__init__() {
|
|
39
|
+
this.dbStorage = new AsyncLocalStorage();
|
|
40
|
+
}
|
|
41
|
+
get current() {
|
|
42
|
+
return this.dbStorage.getStore();
|
|
43
|
+
}
|
|
44
|
+
async run(store, fn) {
|
|
45
|
+
if (store === this.current) {
|
|
46
|
+
return fn();
|
|
47
|
+
}
|
|
48
|
+
return this.dbStorage.run(store, () => {
|
|
49
|
+
return fn();
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}) || _class$t) || _class$t);
|
|
53
|
+
|
|
54
|
+
var _dec$s, _dec2$s, _class$s;
|
|
55
|
+
const SymbolColumnsCache = Symbol('SymbolColumnsCache');
|
|
56
|
+
const SymbolColumnsDefaultCache = Symbol('SymbolColumnsDefaultCache');
|
|
57
|
+
let ServiceColumnsCache = (_dec$s = Service(), _dec2$s = BeanInfo({
|
|
58
|
+
module: "a-orm"
|
|
59
|
+
}), _dec$s(_class$s = _dec2$s(_class$s = class ServiceColumnsCache extends BeanBase {
|
|
60
|
+
constructor(...args) {
|
|
61
|
+
super(...args);
|
|
62
|
+
this.clientName = void 0;
|
|
63
|
+
this[SymbolColumnsCache] = {};
|
|
64
|
+
this[SymbolColumnsDefaultCache] = {};
|
|
65
|
+
this._onColumnsClearCancel = void 0;
|
|
66
|
+
}
|
|
67
|
+
/** real client name */
|
|
68
|
+
__init__(clientName) {
|
|
69
|
+
this.clientName = clientName;
|
|
70
|
+
this._onColumnsClearCancel = this.scope.event.columnsClear.on(({
|
|
71
|
+
clientName,
|
|
72
|
+
tableName
|
|
73
|
+
}, next) => {
|
|
74
|
+
if (clientName === this.clientName) {
|
|
75
|
+
this.columnsClear(tableName);
|
|
76
|
+
}
|
|
77
|
+
next();
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
async __dispose__() {
|
|
81
|
+
this._onColumnsClearCancel?.();
|
|
82
|
+
}
|
|
83
|
+
getColumnsDefaultCache(table) {
|
|
84
|
+
return this[SymbolColumnsDefaultCache][table];
|
|
85
|
+
}
|
|
86
|
+
setColumnsDefaultCache(table, data) {
|
|
87
|
+
this[SymbolColumnsDefaultCache][table] = data;
|
|
88
|
+
}
|
|
89
|
+
deleteColumnsDefaultCache(table) {
|
|
90
|
+
delete this[SymbolColumnsDefaultCache][table];
|
|
91
|
+
}
|
|
92
|
+
getColumnsCache(table) {
|
|
93
|
+
return this[SymbolColumnsCache][table];
|
|
94
|
+
}
|
|
95
|
+
setColumnsCache(table, columns) {
|
|
96
|
+
this[SymbolColumnsCache][table] = columns;
|
|
97
|
+
}
|
|
98
|
+
deleteColumnsCache(table) {
|
|
99
|
+
delete this[SymbolColumnsCache][table];
|
|
100
|
+
}
|
|
101
|
+
columnsClear(tableName) {
|
|
102
|
+
if (tableName) {
|
|
103
|
+
const exists = this.getColumnsCache(tableName);
|
|
104
|
+
this.deleteColumnsCache(tableName);
|
|
105
|
+
this.deleteColumnsDefaultCache(tableName);
|
|
106
|
+
return exists;
|
|
107
|
+
} else {
|
|
108
|
+
const exists = Object.keys(this[SymbolColumnsCache]).length > 0;
|
|
109
|
+
this[SymbolColumnsCache] = {};
|
|
110
|
+
this[SymbolColumnsDefaultCache] = {};
|
|
111
|
+
return exists;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}) || _class$s) || _class$s);
|
|
115
|
+
|
|
116
|
+
var _dec$r, _dec2$r, _class$r;
|
|
117
|
+
let ServiceColumns = (_dec$r = Service(), _dec2$r = BeanInfo({
|
|
118
|
+
module: "a-orm"
|
|
119
|
+
}), _dec$r(_class$r = _dec2$r(_class$r = class ServiceColumns extends BeanBase {
|
|
120
|
+
constructor(...args) {
|
|
121
|
+
super(...args);
|
|
122
|
+
this._db = void 0;
|
|
123
|
+
this._serviceColumnsCache = void 0;
|
|
124
|
+
}
|
|
125
|
+
__init__(db) {
|
|
126
|
+
this._db = db;
|
|
127
|
+
}
|
|
128
|
+
get db() {
|
|
129
|
+
return this._db;
|
|
130
|
+
}
|
|
131
|
+
get serviceColumnsCache() {
|
|
132
|
+
if (!this._serviceColumnsCache) {
|
|
133
|
+
const clientNameReal = this.scope.service.database.prepareClientNameReal(this.db.clientName);
|
|
134
|
+
this._serviceColumnsCache = this.bean._getBeanSelector(ServiceColumnsCache, clientNameReal);
|
|
135
|
+
}
|
|
136
|
+
return this._serviceColumnsCache;
|
|
137
|
+
}
|
|
138
|
+
async columns(tableName) {
|
|
139
|
+
if (!tableName) return {};
|
|
140
|
+
let columns = this.serviceColumnsCache.getColumnsCache(tableName);
|
|
141
|
+
if (!columns) {
|
|
142
|
+
const dialect = this.db.dialect;
|
|
143
|
+
const connection = this.db.connection;
|
|
144
|
+
const map = await connection(tableName).columnInfo();
|
|
145
|
+
columns = {};
|
|
146
|
+
for (const name in map) {
|
|
147
|
+
columns[name] = dialect.coerceColumn(map[name]);
|
|
148
|
+
}
|
|
149
|
+
this.serviceColumnsCache.setColumnsCache(tableName, columns);
|
|
150
|
+
}
|
|
151
|
+
return columns;
|
|
152
|
+
}
|
|
153
|
+
async defaultData(tableName) {
|
|
154
|
+
if (!tableName) return {};
|
|
155
|
+
let data = this.serviceColumnsCache.getColumnsDefaultCache(tableName);
|
|
156
|
+
if (!data) {
|
|
157
|
+
data = {};
|
|
158
|
+
// columns
|
|
159
|
+
const columns = await this.columns(tableName);
|
|
160
|
+
for (const columnName in columns) {
|
|
161
|
+
data[columnName] = columns[columnName].default;
|
|
162
|
+
}
|
|
163
|
+
this.serviceColumnsCache.setColumnsDefaultCache(tableName, data);
|
|
164
|
+
}
|
|
165
|
+
return data;
|
|
166
|
+
}
|
|
167
|
+
columnsClear(tableName) {
|
|
168
|
+
return this.scope.service.database.columnsClear(this.db.clientName, tableName);
|
|
169
|
+
}
|
|
170
|
+
}) || _class$r) || _class$r);
|
|
171
|
+
|
|
172
|
+
const TransactionIsolationLevelsMap = {
|
|
173
|
+
DEFAULT: undefined,
|
|
174
|
+
READ_UNCOMMITTED: 'read uncommitted',
|
|
175
|
+
READ_COMMITTED: 'read committed',
|
|
176
|
+
REPEATABLE_READ: 'repeatable read',
|
|
177
|
+
SERIALIZABLE: 'serializable',
|
|
178
|
+
SNAPSHOT: 'snapshot'
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// export type TransactionPropagation=''
|
|
182
|
+
|
|
183
|
+
var _dec$q, _dec2$q, _class$q;
|
|
184
|
+
let ServiceDatabase = (_dec$q = Service(), _dec2$q = BeanInfo({
|
|
185
|
+
module: "a-orm"
|
|
186
|
+
}), _dec$q(_class$q = _dec2$q(_class$q = class ServiceDatabase extends BeanBase {
|
|
187
|
+
getDialect(client) {
|
|
188
|
+
if (!client) throw new Error('database dialect not specified');
|
|
189
|
+
const beanFullName = this.scope.config.dialects[client];
|
|
190
|
+
const dialect = this.app.bean._getBean(beanFullName);
|
|
191
|
+
if (!dialect) throw new Error(`database dialect not found: ${client}`);
|
|
192
|
+
return dialect;
|
|
193
|
+
}
|
|
194
|
+
prepareDbInfo(dbInfoOrClientName) {
|
|
195
|
+
let level;
|
|
196
|
+
let clientName;
|
|
197
|
+
if (typeof dbInfoOrClientName === 'string') {
|
|
198
|
+
level = undefined;
|
|
199
|
+
clientName = dbInfoOrClientName;
|
|
200
|
+
} else {
|
|
201
|
+
level = dbInfoOrClientName?.level;
|
|
202
|
+
clientName = dbInfoOrClientName?.clientName;
|
|
203
|
+
}
|
|
204
|
+
// check if selector
|
|
205
|
+
if (clientName && clientName.includes(':')) return clientName;
|
|
206
|
+
// check if default
|
|
207
|
+
clientName = this.prepareClientName(clientName ?? this.bean.database.current?.clientName);
|
|
208
|
+
// level
|
|
209
|
+
level = level ?? this.bean.database.current?.level ?? 0;
|
|
210
|
+
return {
|
|
211
|
+
level,
|
|
212
|
+
clientName
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
prepareClientNameSelector(dbInfo) {
|
|
216
|
+
// combine
|
|
217
|
+
return dbInfo.level === 0 ? dbInfo.clientName : `${dbInfo.clientName}:${dbInfo.level}`;
|
|
218
|
+
}
|
|
219
|
+
parseClientNameSelector(clientNameSelector) {
|
|
220
|
+
if (isNil(clientNameSelector)) throw new Error('invalid clientNameSelector');
|
|
221
|
+
const [clientName, level] = clientNameSelector.split(':');
|
|
222
|
+
if (!clientName) throw new Error('clientName must be specified');
|
|
223
|
+
return {
|
|
224
|
+
level: Number(level ?? 0),
|
|
225
|
+
clientName: clientName
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
prepareClientName(clientName) {
|
|
229
|
+
return !clientName || clientName === 'default' ? this.getDefaultClientName() : clientName;
|
|
230
|
+
}
|
|
231
|
+
getDefaultClientName() {
|
|
232
|
+
let defaultClient = this.app.config.database.defaultClient;
|
|
233
|
+
if (typeof defaultClient === 'function') {
|
|
234
|
+
defaultClient = defaultClient(this.ctx);
|
|
235
|
+
}
|
|
236
|
+
return defaultClient;
|
|
237
|
+
}
|
|
238
|
+
prepareClientNameReal(clientName) {
|
|
239
|
+
return this.scope.event.clientNameReal.emitSync(this.prepareClientName(clientName), clientName => {
|
|
240
|
+
return clientName;
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
columnsClear(clientName, tableName) {
|
|
244
|
+
this.__columnsClearRaw(clientName, tableName);
|
|
245
|
+
this.scope.broadcast.columnsClear.emit({
|
|
246
|
+
clientName,
|
|
247
|
+
tableName
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
__columnsClearRaw(clientName, tableName) {
|
|
251
|
+
this.scope.event.columnsClear.emitSync({
|
|
252
|
+
clientName: this.prepareClientNameReal(clientName),
|
|
253
|
+
tableName
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
async reloadClients(clientName, clientConfig, extraData) {
|
|
257
|
+
await this.__reloadAllClientsRaw(clientName, clientConfig, extraData);
|
|
258
|
+
this.scope.broadcast.databaseClientReload.emit({
|
|
259
|
+
clientName,
|
|
260
|
+
clientConfig,
|
|
261
|
+
extraData
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
async __reloadAllClientsRaw(clientName, clientConfig, extraData) {
|
|
265
|
+
await this.scope.event.databaseClientReload.emit({
|
|
266
|
+
clientName: this.prepareClientName(clientName),
|
|
267
|
+
clientConfig,
|
|
268
|
+
extraData
|
|
269
|
+
});
|
|
270
|
+
this.__columnsClearRaw(clientName);
|
|
271
|
+
}
|
|
272
|
+
}) || _class$q) || _class$q);
|
|
273
|
+
|
|
274
|
+
var _dec$p, _dec2$p, _class$p;
|
|
275
|
+
let ServiceTransactionConsistency = (_dec$p = Service(), _dec2$p = BeanInfo({
|
|
276
|
+
module: "a-orm"
|
|
277
|
+
}), _dec$p(_class$p = _dec2$p(_class$p = class ServiceTransactionConsistency extends BeanBase {
|
|
278
|
+
constructor(...args) {
|
|
279
|
+
super(...args);
|
|
280
|
+
this._commitCallbacks = [];
|
|
281
|
+
this._compensateCallbacks = [];
|
|
282
|
+
}
|
|
283
|
+
commit(cb) {
|
|
284
|
+
this._commitCallbacks.push(AsyncResource.bind(cb));
|
|
285
|
+
}
|
|
286
|
+
compensate(cb) {
|
|
287
|
+
this._compensateCallbacks.unshift(AsyncResource.bind(cb));
|
|
288
|
+
}
|
|
289
|
+
async commitDone() {
|
|
290
|
+
while (true) {
|
|
291
|
+
const cb = this._commitCallbacks.shift();
|
|
292
|
+
if (!cb) break;
|
|
293
|
+
await cb();
|
|
294
|
+
}
|
|
295
|
+
this._compensateCallbacks = [];
|
|
296
|
+
}
|
|
297
|
+
async compensateDone() {
|
|
298
|
+
while (true) {
|
|
299
|
+
const cb = this._compensateCallbacks.shift();
|
|
300
|
+
if (!cb) break;
|
|
301
|
+
await cb();
|
|
302
|
+
}
|
|
303
|
+
this._commitCallbacks = [];
|
|
304
|
+
}
|
|
305
|
+
}) || _class$p) || _class$p);
|
|
306
|
+
|
|
307
|
+
var _dec$o, _dec2$o, _class$o;
|
|
308
|
+
let ServiceTransactionFiber = (_dec$o = Service(), _dec2$o = BeanInfo({
|
|
309
|
+
module: "a-orm"
|
|
310
|
+
}), _dec$o(_class$o = _dec2$o(_class$o = class ServiceTransactionFiber extends BeanBase {
|
|
311
|
+
constructor(...args) {
|
|
312
|
+
super(...args);
|
|
313
|
+
this._connection = void 0;
|
|
314
|
+
this._transactionConsistency = void 0;
|
|
315
|
+
}
|
|
316
|
+
__init__(connection) {
|
|
317
|
+
this._connection = connection;
|
|
318
|
+
this._transactionConsistency = this.app.bean._newBean(ServiceTransactionConsistency);
|
|
319
|
+
}
|
|
320
|
+
get connection() {
|
|
321
|
+
return this._connection;
|
|
322
|
+
}
|
|
323
|
+
commit(cb) {
|
|
324
|
+
this._transactionConsistency.commit(cb);
|
|
325
|
+
}
|
|
326
|
+
compensate(cb) {
|
|
327
|
+
this._transactionConsistency.compensate(cb);
|
|
328
|
+
}
|
|
329
|
+
async doCommit() {
|
|
330
|
+
await this._connection.commit();
|
|
331
|
+
await this._transactionConsistency.commitDone();
|
|
332
|
+
this._connection = undefined;
|
|
333
|
+
}
|
|
334
|
+
async doRollback() {
|
|
335
|
+
await this._connection.rollback();
|
|
336
|
+
await this._transactionConsistency.compensateDone();
|
|
337
|
+
this._connection = undefined;
|
|
338
|
+
}
|
|
339
|
+
}) || _class$o) || _class$o);
|
|
340
|
+
|
|
341
|
+
var _dec$n, _dec2$n, _class$n;
|
|
342
|
+
let ServiceTransactionState = (_dec$n = Service(), _dec2$n = BeanInfo({
|
|
343
|
+
module: "a-orm"
|
|
344
|
+
}), _dec$n(_class$n = _dec2$n(_class$n = class ServiceTransactionState extends BeanBase {
|
|
345
|
+
constructor(...args) {
|
|
346
|
+
super(...args);
|
|
347
|
+
this._fibers = {};
|
|
348
|
+
}
|
|
349
|
+
get serviceDatabase() {
|
|
350
|
+
return this.bean._getBean(ServiceDatabase);
|
|
351
|
+
}
|
|
352
|
+
get(dbInfo) {
|
|
353
|
+
const selector = this.serviceDatabase.prepareClientNameSelector(dbInfo);
|
|
354
|
+
return this._fibers[selector];
|
|
355
|
+
}
|
|
356
|
+
add(dbInfo, connection) {
|
|
357
|
+
const selector = this.serviceDatabase.prepareClientNameSelector(dbInfo);
|
|
358
|
+
const fiber = this.bean._newBean(ServiceTransactionFiber, connection);
|
|
359
|
+
this._fibers[selector] = fiber;
|
|
360
|
+
return fiber;
|
|
361
|
+
}
|
|
362
|
+
remove(dbInfo) {
|
|
363
|
+
const selector = this.serviceDatabase.prepareClientNameSelector(dbInfo);
|
|
364
|
+
delete this._fibers[selector];
|
|
365
|
+
}
|
|
366
|
+
}) || _class$n) || _class$n);
|
|
367
|
+
|
|
368
|
+
var _dec$m, _dec2$m, _class$m;
|
|
369
|
+
let ServiceTransactionAsyncLocalStorage = (_dec$m = Service(), _dec2$m = BeanInfo({
|
|
370
|
+
module: "a-orm"
|
|
371
|
+
}), _dec$m(_class$m = _dec2$m(_class$m = class ServiceTransactionAsyncLocalStorage extends BeanBase {
|
|
372
|
+
constructor(...args) {
|
|
373
|
+
super(...args);
|
|
374
|
+
this.transactionStorage = void 0;
|
|
375
|
+
}
|
|
376
|
+
__init__() {
|
|
377
|
+
this.transactionStorage = new AsyncLocalStorage();
|
|
378
|
+
}
|
|
379
|
+
get transactionState() {
|
|
380
|
+
return this.transactionStorage.getStore();
|
|
381
|
+
}
|
|
382
|
+
async run(fn) {
|
|
383
|
+
// only once
|
|
384
|
+
if (this.transactionState) {
|
|
385
|
+
return fn();
|
|
386
|
+
}
|
|
387
|
+
const transactionState = this.bean._newBean(ServiceTransactionState);
|
|
388
|
+
return this.transactionStorage.run(transactionState, () => {
|
|
389
|
+
return fn();
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
}) || _class$m) || _class$m);
|
|
393
|
+
|
|
394
|
+
var _dec$l, _dec2$l, _class$l;
|
|
395
|
+
let ServiceTransaction = (_dec$l = Service(), _dec2$l = BeanInfo({
|
|
396
|
+
module: "a-orm"
|
|
397
|
+
}), _dec$l(_class$l = _dec2$l(_class$l = class ServiceTransaction extends BeanBase {
|
|
398
|
+
constructor(...args) {
|
|
399
|
+
super(...args);
|
|
400
|
+
this._db = void 0;
|
|
401
|
+
}
|
|
402
|
+
__init__(db) {
|
|
403
|
+
this._db = db;
|
|
404
|
+
}
|
|
405
|
+
get transactionState() {
|
|
406
|
+
return this.bean._getBean(ServiceTransactionAsyncLocalStorage).transactionState;
|
|
407
|
+
}
|
|
408
|
+
get transactionFiber() {
|
|
409
|
+
return this.transactionState.get(this._db.info);
|
|
410
|
+
}
|
|
411
|
+
get inTransaction() {
|
|
412
|
+
return !!this.transactionFiber;
|
|
413
|
+
}
|
|
414
|
+
get connection() {
|
|
415
|
+
return this.transactionFiber?.connection;
|
|
416
|
+
}
|
|
417
|
+
commit(cb, options) {
|
|
418
|
+
if (options?.ctxPrefer) {
|
|
419
|
+
this.ctx?.commit(cb);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
const fiber = this.transactionFiber;
|
|
423
|
+
if (!fiber) {
|
|
424
|
+
this.ctx?.commit(cb);
|
|
425
|
+
} else {
|
|
426
|
+
fiber.commit(cb);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
compensate(cb) {
|
|
430
|
+
const fiber = this.transactionFiber;
|
|
431
|
+
if (fiber) {
|
|
432
|
+
fiber.compensate(cb);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
async begin(fn, options) {
|
|
436
|
+
// transactionOptions
|
|
437
|
+
const transactionOptions = Object.assign({}, options, {
|
|
438
|
+
propagation: undefined
|
|
439
|
+
});
|
|
440
|
+
// propagation
|
|
441
|
+
const propagation = options?.propagation ?? 'REQUIRED';
|
|
442
|
+
if (propagation === 'REQUIRED') {
|
|
443
|
+
// required
|
|
444
|
+
return this._isolationLevelRequired(fn, transactionOptions);
|
|
445
|
+
} else if (propagation === 'SUPPORTS') {
|
|
446
|
+
// supports
|
|
447
|
+
if (this.inTransaction) {
|
|
448
|
+
return this._isolationLevelRequired(fn, transactionOptions);
|
|
449
|
+
} else {
|
|
450
|
+
return fn();
|
|
451
|
+
}
|
|
452
|
+
} else if (propagation === 'MANDATORY') {
|
|
453
|
+
// mandatory
|
|
454
|
+
if (this.inTransaction) {
|
|
455
|
+
return this._isolationLevelRequired(fn, transactionOptions);
|
|
456
|
+
} else {
|
|
457
|
+
throw new Error('transaction error: EnumTransactionPropagation.MANDATORY');
|
|
458
|
+
}
|
|
459
|
+
} else if (propagation === 'REQUIRES_NEW') {
|
|
460
|
+
// requires_new
|
|
461
|
+
if (!this.inTransaction) {
|
|
462
|
+
return this._isolationLevelRequired(fn, transactionOptions);
|
|
463
|
+
} else {
|
|
464
|
+
return this.bean.database.switchDbIsolate(() => {
|
|
465
|
+
return this.bean.database.current.transaction.begin(() => {
|
|
466
|
+
return fn();
|
|
467
|
+
}, transactionOptions);
|
|
468
|
+
}, this._db.info);
|
|
469
|
+
}
|
|
470
|
+
} else if (propagation === 'NOT_SUPPORTED') {
|
|
471
|
+
if (!this.inTransaction) {
|
|
472
|
+
return fn();
|
|
473
|
+
} else {
|
|
474
|
+
return this.bean.database.switchDbIsolate(fn, this._db.info);
|
|
475
|
+
}
|
|
476
|
+
} else if (propagation === 'NEVER') {
|
|
477
|
+
if (!this.inTransaction) {
|
|
478
|
+
return fn();
|
|
479
|
+
} else {
|
|
480
|
+
throw new Error('transaction error: EnumTransactionPropagation.NEVER');
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
throw new Error('transaction error: unknown propagation');
|
|
484
|
+
}
|
|
485
|
+
async _isolationLevelRequired(fn, options) {
|
|
486
|
+
let res;
|
|
487
|
+
// begin
|
|
488
|
+
let fiber;
|
|
489
|
+
if (!this.inTransaction) {
|
|
490
|
+
const connection = this._db.client.connection;
|
|
491
|
+
const transactionConnection = await connection.transaction(_translateTransactionOptions(options));
|
|
492
|
+
fiber = this.transactionState.add(this._db.info, transactionConnection);
|
|
493
|
+
}
|
|
494
|
+
// fn
|
|
495
|
+
try {
|
|
496
|
+
res = await fn();
|
|
497
|
+
} catch (err) {
|
|
498
|
+
if (fiber) {
|
|
499
|
+
await fiber.doRollback();
|
|
500
|
+
this.transactionState.remove(this._db.info);
|
|
501
|
+
}
|
|
502
|
+
throw err;
|
|
503
|
+
}
|
|
504
|
+
try {
|
|
505
|
+
if (fiber) {
|
|
506
|
+
await fiber.doCommit();
|
|
507
|
+
this.transactionState.remove(this._db.info);
|
|
508
|
+
}
|
|
509
|
+
} catch (err) {
|
|
510
|
+
if (fiber) {
|
|
511
|
+
await fiber.doRollback();
|
|
512
|
+
this.transactionState.remove(this._db.info);
|
|
513
|
+
}
|
|
514
|
+
throw err;
|
|
515
|
+
}
|
|
516
|
+
return res;
|
|
517
|
+
}
|
|
518
|
+
}) || _class$l) || _class$l);
|
|
519
|
+
function _translateTransactionOptions(options) {
|
|
520
|
+
if (!options) return undefined;
|
|
521
|
+
return {
|
|
522
|
+
isolationLevel: TransactionIsolationLevelsMap[options.isolationLevel ?? 'DEFAULT'],
|
|
523
|
+
readOnly: options.readOnly
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
var _dec$k, _dec2$k, _class$k;
|
|
528
|
+
let ServiceDb = (_dec$k = Service(), _dec2$k = BeanInfo({
|
|
529
|
+
module: "a-orm"
|
|
530
|
+
}), _dec$k(_class$k = _dec2$k(_class$k = class ServiceDb extends BeanBase {
|
|
531
|
+
constructor(...args) {
|
|
532
|
+
super(...args);
|
|
533
|
+
this._client = void 0;
|
|
534
|
+
this._columns = void 0;
|
|
535
|
+
this._transaction = void 0;
|
|
536
|
+
}
|
|
537
|
+
__init__(client) {
|
|
538
|
+
this._client = client;
|
|
539
|
+
}
|
|
540
|
+
get info() {
|
|
541
|
+
return {
|
|
542
|
+
level: this.level,
|
|
543
|
+
clientName: this.clientName
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
get level() {
|
|
547
|
+
return this._client.level;
|
|
548
|
+
}
|
|
549
|
+
get clientName() {
|
|
550
|
+
return this._client.clientName;
|
|
551
|
+
}
|
|
552
|
+
get client() {
|
|
553
|
+
return this._client;
|
|
554
|
+
}
|
|
555
|
+
get columns() {
|
|
556
|
+
if (!this._columns) {
|
|
557
|
+
this._columns = this.app.bean._newBean(ServiceColumns, this);
|
|
558
|
+
}
|
|
559
|
+
return this._columns;
|
|
560
|
+
}
|
|
561
|
+
get transaction() {
|
|
562
|
+
if (!this._transaction) {
|
|
563
|
+
this._transaction = this.app.bean._newBean(ServiceTransaction, this);
|
|
564
|
+
}
|
|
565
|
+
return this._transaction;
|
|
566
|
+
}
|
|
567
|
+
get inTransaction() {
|
|
568
|
+
return this.transaction.inTransaction;
|
|
569
|
+
}
|
|
570
|
+
get connection() {
|
|
571
|
+
return this.transaction.connection ?? this.client.connection;
|
|
572
|
+
}
|
|
573
|
+
get dialectName() {
|
|
574
|
+
return this.client.clientConfig.client;
|
|
575
|
+
}
|
|
576
|
+
get dialect() {
|
|
577
|
+
return this.scope.service.database.getDialect(this.dialectName);
|
|
578
|
+
}
|
|
579
|
+
commit(cb, options) {
|
|
580
|
+
return this.transaction.commit(cb, options);
|
|
581
|
+
}
|
|
582
|
+
compensate(cb) {
|
|
583
|
+
return this.transaction.compensate(cb);
|
|
584
|
+
}
|
|
585
|
+
}) || _class$k) || _class$k);
|
|
586
|
+
|
|
587
|
+
var _dec$j, _dec2$j, _class$j;
|
|
588
|
+
let ServiceDatabaseClient = (_dec$j = Service(), _dec2$j = BeanInfo({
|
|
589
|
+
module: "a-orm"
|
|
590
|
+
}), _dec$j(_class$j = _dec2$j(_class$j = class ServiceDatabaseClient extends BeanBase {
|
|
591
|
+
constructor(...args) {
|
|
592
|
+
super(...args);
|
|
593
|
+
this.level = void 0;
|
|
594
|
+
this.clientName = void 0;
|
|
595
|
+
this.clientNameSelector = void 0;
|
|
596
|
+
this.clientConfig = void 0;
|
|
597
|
+
this._knex = void 0;
|
|
598
|
+
this._db = void 0;
|
|
599
|
+
this._onDatabaseClientReloadCancel = void 0;
|
|
600
|
+
}
|
|
601
|
+
get configDatabase() {
|
|
602
|
+
return this.app.config.database;
|
|
603
|
+
}
|
|
604
|
+
get connection() {
|
|
605
|
+
return this._knex;
|
|
606
|
+
}
|
|
607
|
+
get db() {
|
|
608
|
+
return this._db;
|
|
609
|
+
}
|
|
610
|
+
__init__(clientNameSelector, clientConfig) {
|
|
611
|
+
// db
|
|
612
|
+
this._db = this.bean._newBean(ServiceDb, this);
|
|
613
|
+
// load
|
|
614
|
+
this.__load(clientNameSelector, clientConfig);
|
|
615
|
+
// event
|
|
616
|
+
this._onDatabaseClientReloadCancel = this.scope.event.databaseClientReload.on(async ({
|
|
617
|
+
clientName,
|
|
618
|
+
clientConfig
|
|
619
|
+
}, next) => {
|
|
620
|
+
if (clientName === this.clientName) {
|
|
621
|
+
await this.reload(clientConfig);
|
|
622
|
+
}
|
|
623
|
+
await next();
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
async __dispose__() {
|
|
627
|
+
this._db = undefined;
|
|
628
|
+
await this.__close();
|
|
629
|
+
this._onDatabaseClientReloadCancel?.();
|
|
630
|
+
}
|
|
631
|
+
__load(clientNameSelector, clientConfig) {
|
|
632
|
+
// name
|
|
633
|
+
this.clientNameSelector = clientNameSelector;
|
|
634
|
+
const dbInfo = this.scope.service.database.parseClientNameSelector(clientNameSelector);
|
|
635
|
+
this.level = dbInfo.level;
|
|
636
|
+
this.clientName = dbInfo.clientName;
|
|
637
|
+
// config
|
|
638
|
+
this.clientConfig = clientConfig ? deepExtend({}, clientConfig) : this.getClientConfig(this.clientName);
|
|
639
|
+
this.$loggerChild('database').debug('clientName: %s, clientConfig: %j', this.clientName, this.clientConfig);
|
|
640
|
+
// knex
|
|
641
|
+
this._knex = knex(this.clientConfig);
|
|
642
|
+
}
|
|
643
|
+
async __close() {
|
|
644
|
+
if (this._knex) {
|
|
645
|
+
await this._knex.destroy();
|
|
646
|
+
this._knex = undefined;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
async reload(clientConfig) {
|
|
650
|
+
await this.__close();
|
|
651
|
+
this.__load(this.clientNameSelector, clientConfig);
|
|
652
|
+
}
|
|
653
|
+
getClientConfig(clientName, original = false) {
|
|
654
|
+
// clientConfig
|
|
655
|
+
let clientConfig = this.configDatabase.clients[clientName];
|
|
656
|
+
if (original) return clientConfig;
|
|
657
|
+
// check
|
|
658
|
+
if (!clientConfig) {
|
|
659
|
+
throw new Error(`database config not found: ${clientName}`);
|
|
660
|
+
}
|
|
661
|
+
// configBaseClient
|
|
662
|
+
const dialect = this.scope.service.database.getDialect(clientConfig.client);
|
|
663
|
+
const configBaseClient = dialect.getConfigBase();
|
|
664
|
+
// combine
|
|
665
|
+
const configBase = this.configDatabase.base;
|
|
666
|
+
clientConfig = deepExtend({}, configBase, configBaseClient, clientConfig);
|
|
667
|
+
// ready
|
|
668
|
+
return clientConfig;
|
|
669
|
+
}
|
|
670
|
+
getDatabaseName() {
|
|
671
|
+
const connection = this.clientConfig.connection;
|
|
672
|
+
return connection.database || connection.filename;
|
|
673
|
+
}
|
|
674
|
+
_prepareDatabaseName(databaseName) {
|
|
675
|
+
const result = {};
|
|
676
|
+
const connection = this.clientConfig.connection;
|
|
677
|
+
if (connection.database) {
|
|
678
|
+
result.database = databaseName;
|
|
679
|
+
} else if (connection.filename) {
|
|
680
|
+
result.filename = databaseName;
|
|
681
|
+
}
|
|
682
|
+
return result;
|
|
683
|
+
}
|
|
684
|
+
async changeConfigAndReload(databaseName) {
|
|
685
|
+
// set databaseName
|
|
686
|
+
const connDatabaseName = this._prepareDatabaseName(databaseName);
|
|
687
|
+
// set config
|
|
688
|
+
// * should not use this.clientConfig.connection, because password is hidden
|
|
689
|
+
const config = this.getClientConfig(this.clientName, true);
|
|
690
|
+
config.connection = Object.assign({}, config.connection, connDatabaseName);
|
|
691
|
+
// only used by startup, so no consider that workders broadcast
|
|
692
|
+
this.configDatabase.clients[this.clientName] = config;
|
|
693
|
+
// reload
|
|
694
|
+
await this.reload(config);
|
|
695
|
+
}
|
|
696
|
+
}) || _class$j) || _class$j);
|
|
697
|
+
|
|
698
|
+
var _dec$i, _dec2$i, _class$i;
|
|
699
|
+
let BeanDatabase = (_dec$i = Bean(), _dec2$i = BeanInfo({
|
|
700
|
+
module: "a-orm"
|
|
701
|
+
}), _dec$i(_class$i = _dec2$i(_class$i = class BeanDatabase extends BeanBase {
|
|
702
|
+
get current() {
|
|
703
|
+
return this.bean._getBean(ServiceDatabaseAsyncLocalStorage).current;
|
|
704
|
+
}
|
|
705
|
+
getClient(dbInfoOrClientName, clientConfig) {
|
|
706
|
+
const dbInfo = this.scope.service.database.prepareDbInfo(dbInfoOrClientName);
|
|
707
|
+
const selector = this.scope.service.database.prepareClientNameSelector(dbInfo);
|
|
708
|
+
return this.app.bean._getBeanSelector(ServiceDatabaseClient, selector, clientConfig);
|
|
709
|
+
}
|
|
710
|
+
getDb(dbInfoOrClientName, clientConfig) {
|
|
711
|
+
return this.getClient(dbInfoOrClientName, clientConfig).db;
|
|
712
|
+
}
|
|
713
|
+
async switchDbIsolate(fn, dbInfoOrClientName) {
|
|
714
|
+
const dbInfo = this.scope.service.database.prepareDbInfo(dbInfoOrClientName);
|
|
715
|
+
return this.switchDb(fn, {
|
|
716
|
+
level: dbInfo.level + 1,
|
|
717
|
+
clientName: dbInfo.clientName
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
async switchDb(fn, dbInfoOrClientName) {
|
|
721
|
+
const current = this.bean.database.current;
|
|
722
|
+
const dbInfo = this.scope.service.database.prepareDbInfo(dbInfoOrClientName);
|
|
723
|
+
if (dbInfo.level === current?.level && dbInfo.clientName === current?.clientName) {
|
|
724
|
+
return fn();
|
|
725
|
+
}
|
|
726
|
+
const db = this.getDb(dbInfo);
|
|
727
|
+
return this.bean._getBean(ServiceDatabaseAsyncLocalStorage).run(db, () => {
|
|
728
|
+
return this.bean._getBean(ServiceTransactionAsyncLocalStorage).run(fn);
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
}) || _class$i) || _class$i);
|
|
732
|
+
|
|
733
|
+
var _dec$h, _dec2$h, _dec3$5, _class$h;
|
|
734
|
+
let BeanDatabaseDialectBase = (_dec$h = Bean(), _dec2$h = Virtual(), _dec3$5 = BeanInfo({
|
|
735
|
+
module: "a-orm"
|
|
736
|
+
}), _dec$h(_class$h = _dec2$h(_class$h = _dec3$5(_class$h = class BeanDatabaseDialectBase extends BeanBase {
|
|
737
|
+
getConfigBase() {
|
|
738
|
+
return undefined;
|
|
739
|
+
}
|
|
740
|
+
async fetchDatabases(_schemaBuilder, _databasePrefix) {
|
|
741
|
+
throw new Error('Not Implemented');
|
|
742
|
+
}
|
|
743
|
+
async createDatabase(_schemaBuilder, _databaseName) {
|
|
744
|
+
throw new Error('Not Implemented');
|
|
745
|
+
}
|
|
746
|
+
async dropDatabase(_schemaBuilder, _databaseName) {
|
|
747
|
+
throw new Error('Not Implemented');
|
|
748
|
+
}
|
|
749
|
+
async fetchIndexes(_schemaBuilder, _tableName) {
|
|
750
|
+
throw new Error('Not Implemented');
|
|
751
|
+
}
|
|
752
|
+
async insert(_builder) {
|
|
753
|
+
throw new Error('Not Implemented');
|
|
754
|
+
}
|
|
755
|
+
query(_result) {
|
|
756
|
+
throw new Error('Not Implemented');
|
|
757
|
+
}
|
|
758
|
+
async viewDependents(_builder, _viewName) {
|
|
759
|
+
throw new Error('Not Implemented');
|
|
760
|
+
}
|
|
761
|
+
coerceColumn(column) {
|
|
762
|
+
// result
|
|
763
|
+
const result = {
|
|
764
|
+
type: column.type
|
|
765
|
+
};
|
|
766
|
+
// coerce
|
|
767
|
+
result.default = this._coerceColumnValue(column.type, column.defaultValue);
|
|
768
|
+
// ok
|
|
769
|
+
return result;
|
|
770
|
+
}
|
|
771
|
+
_coerceColumnValue(type, value) {
|
|
772
|
+
// null
|
|
773
|
+
if (isNil(value)) return undefined;
|
|
774
|
+
// type
|
|
775
|
+
if (['bit', 'bool', 'boolean'].includes(type)) return safeBoolean(value);
|
|
776
|
+
if (['int'].includes(type)) return this._safeNumber(value);
|
|
777
|
+
if (this._columnTypePrefixes(type, ['timestamp']) && value === 'CURRENT_TIMESTAMP') return undefined; // new Date();
|
|
778
|
+
if (this._columnTypePrefixes(type, ['float', 'double'])) return this._safeNumber(value);
|
|
779
|
+
if (this._columnTypePrefixes(type, ['tinyint', 'smallint', 'mediumint', 'bigint', 'numeric', 'integer'])) {
|
|
780
|
+
return this._safeNumber(value);
|
|
781
|
+
}
|
|
782
|
+
// pg: NULL::character varying
|
|
783
|
+
if (value.indexOf('NULL::') === 0) return undefined;
|
|
784
|
+
// others
|
|
785
|
+
return value;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
// pg: nextval
|
|
789
|
+
_safeNumber(value) {
|
|
790
|
+
const num = Number(value);
|
|
791
|
+
return Number.isNaN(num) ? undefined : num;
|
|
792
|
+
}
|
|
793
|
+
_columnTypePrefixes(type, prefixes) {
|
|
794
|
+
return prefixes.some(prefix => type.includes(prefix));
|
|
795
|
+
}
|
|
796
|
+
}) || _class$h) || _class$h) || _class$h);
|
|
797
|
+
|
|
798
|
+
const OpAggrs = ['count', 'sum', 'avg', 'max', 'min'];
|
|
799
|
+
const OpJoint = {
|
|
800
|
+
and: '_and_',
|
|
801
|
+
or: '_or_',
|
|
802
|
+
not: '_not_',
|
|
803
|
+
exists: '_exists_',
|
|
804
|
+
notExists: '_notExists_'
|
|
805
|
+
};
|
|
806
|
+
const OpNormal = {
|
|
807
|
+
eq: '_eq_',
|
|
808
|
+
notEq: '_notEq_',
|
|
809
|
+
gt: '_gt_',
|
|
810
|
+
gte: '_gte_',
|
|
811
|
+
lt: '_lt_',
|
|
812
|
+
lte: '_lte_',
|
|
813
|
+
in: '_in_',
|
|
814
|
+
notIn: '_notIn_',
|
|
815
|
+
is: '_is_',
|
|
816
|
+
isNot: '_isNot_',
|
|
817
|
+
between: '_between_',
|
|
818
|
+
notBetween: '_notBetween_',
|
|
819
|
+
startsWith: '_startsWith_',
|
|
820
|
+
endsWith: '_endsWith_',
|
|
821
|
+
includes: '_includes_',
|
|
822
|
+
startsWithI: '_startsWithI_',
|
|
823
|
+
endsWithI: '_endsWithI_',
|
|
824
|
+
includesI: '_includesI_',
|
|
825
|
+
ref: '_ref_'
|
|
826
|
+
};
|
|
827
|
+
const Op = {
|
|
828
|
+
skip: '_skip_',
|
|
829
|
+
...OpJoint,
|
|
830
|
+
...OpNormal
|
|
831
|
+
};
|
|
832
|
+
const OpJointValues = Object.values(OpJoint);
|
|
833
|
+
const OpNormalValues = Object.values(OpNormal);
|
|
834
|
+
const OpValues = Object.values(Op);
|
|
835
|
+
|
|
836
|
+
// not use TypeOpsJointPostfix, which cause type not take affect for table.field
|
|
837
|
+
// export type TypeOpsJoint = TypeRecordValues<TypeOpsJointPostfix<Pick<typeof Op, 'and' | 'or' | 'not' | 'exists' | 'notExists'>>>;
|
|
838
|
+
|
|
839
|
+
// not use Knex.Raw
|
|
840
|
+
|
|
841
|
+
// not use Knex.Raw
|
|
842
|
+
// Columns extends {} ? TypeModelWhereInner<Columns> | Knex.Raw : TypeModelWhereInner<TRecord> | Knex.Raw;
|
|
843
|
+
|
|
844
|
+
function isRaw(raw) {
|
|
845
|
+
return typeof raw?.constructor === 'function' && raw?.constructor?.name === 'Raw';
|
|
846
|
+
}
|
|
847
|
+
function getTableOrTableAlias(table) {
|
|
848
|
+
const _table = table.toString();
|
|
849
|
+
return _table.includes(' as ') ? _table.split(' as ')[1].trim() : _table;
|
|
850
|
+
}
|
|
851
|
+
function getTargetColumnName(column) {
|
|
852
|
+
if (column.includes(' as ')) return column.split(' as ')[1].trim();
|
|
853
|
+
if (column.includes('.')) return column.split('.')[1].trim();
|
|
854
|
+
return column;
|
|
855
|
+
}
|
|
856
|
+
function prepareColumns(columns) {
|
|
857
|
+
if (!columns) return undefined;
|
|
858
|
+
columns = Array.isArray(columns) ? columns : [columns];
|
|
859
|
+
if (columns.includes('*')) return undefined;
|
|
860
|
+
return columns;
|
|
861
|
+
}
|
|
862
|
+
function prepareClassModel(classType) {
|
|
863
|
+
if (typeof classType === 'string') {
|
|
864
|
+
const beanOptions = appResource.getBean(beanFullNameFromOnionName(classType, 'model'));
|
|
865
|
+
return beanOptions.beanClass;
|
|
866
|
+
}
|
|
867
|
+
return prepareClassType(classType);
|
|
868
|
+
}
|
|
869
|
+
function getClassEntityFromClassModel(modelClass) {
|
|
870
|
+
const beanOptions = appResource.getBean(modelClass);
|
|
871
|
+
const options = beanOptions.options;
|
|
872
|
+
return options.entity;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// export function formatValue(value) {
|
|
876
|
+
// if (typeof value !== 'object' || value instanceof Date) return value;
|
|
877
|
+
// // date
|
|
878
|
+
// if (value.type === 'Date') return moment(value.val).toDate();
|
|
879
|
+
// // like
|
|
880
|
+
// if (value.op === 'like') return `%${value.val}%`;
|
|
881
|
+
// if (value.op === 'likeLeft') return `%${value.val}`;
|
|
882
|
+
// if (value.op === 'likeRight') return `${value.val}%`;
|
|
883
|
+
// if (value.op === 'likeStrict') return `${value.val}`;
|
|
884
|
+
// // in
|
|
885
|
+
// if (['in', 'notIn'].includes(value.op)) {
|
|
886
|
+
// return formatValueArray(value);
|
|
887
|
+
// }
|
|
888
|
+
// // others
|
|
889
|
+
// return value.val;
|
|
890
|
+
// }
|
|
891
|
+
|
|
892
|
+
// export function formatValueArray(value) {
|
|
893
|
+
// if (!value.val) return null;
|
|
894
|
+
// const arr = typeof value.val === 'string' ? value.val.split(',') : value.val;
|
|
895
|
+
// if (arr.length === 0) return null;
|
|
896
|
+
// return arr;
|
|
897
|
+
// }
|
|
898
|
+
|
|
899
|
+
function buildWhere(knex, builder, wheres, having = false) {
|
|
900
|
+
_buildWhereInner(having, knex, builder, wheres);
|
|
901
|
+
}
|
|
902
|
+
function _buildWhereInner(having, knex, builder, wheres, column) {
|
|
903
|
+
// skip
|
|
904
|
+
if (wheres === Op.skip) {
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
// raw
|
|
908
|
+
if (isRaw(wheres)) {
|
|
909
|
+
builder[having ? 'havingRaw' : 'whereRaw'](wheres);
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
// loop
|
|
913
|
+
for (const key in wheres) {
|
|
914
|
+
const value = wheres[key];
|
|
915
|
+
if (key[0] !== '_') {
|
|
916
|
+
// columns
|
|
917
|
+
_buildWhereColumn(having, knex, builder, key, value);
|
|
918
|
+
} else if (OpNormalValues.includes(key)) {
|
|
919
|
+
// op: normal
|
|
920
|
+
if (column) {
|
|
921
|
+
_buildWhereColumn(having, knex, builder, column, value, key);
|
|
922
|
+
}
|
|
923
|
+
} else {
|
|
924
|
+
const op = _checkOpJoint(key);
|
|
925
|
+
if (op) {
|
|
926
|
+
// op: joint
|
|
927
|
+
_buildWhereOpJoint(having, knex, builder, column, value, op);
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
function _buildWhereOpJoint(having, knex, builder, column, wheres, op) {
|
|
933
|
+
// skip
|
|
934
|
+
if (wheres === Op.skip) {
|
|
935
|
+
return;
|
|
936
|
+
}
|
|
937
|
+
// and/or
|
|
938
|
+
if (op === Op.and) {
|
|
939
|
+
builder[having ? 'having' : 'where'](builder => {
|
|
940
|
+
for (const key in wheres) {
|
|
941
|
+
builder.andWhere(builder => {
|
|
942
|
+
_buildWhereInner(false, knex, builder, {
|
|
943
|
+
[key]: wheres[key]
|
|
944
|
+
}, column);
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
});
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
// or
|
|
951
|
+
if (op === Op.or) {
|
|
952
|
+
builder[having ? 'having' : 'where'](builder => {
|
|
953
|
+
for (const key in wheres) {
|
|
954
|
+
builder.orWhere(builder => {
|
|
955
|
+
_buildWhereInner(false, knex, builder, {
|
|
956
|
+
[key]: wheres[key]
|
|
957
|
+
}, column);
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
// not
|
|
964
|
+
if (op === Op.not) {
|
|
965
|
+
builder[having ? 'havingNot' : 'whereNot'](builder => {
|
|
966
|
+
_buildWhereInner(false, knex, builder, wheres, column);
|
|
967
|
+
});
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
// exists
|
|
971
|
+
if (op === Op.exists) {
|
|
972
|
+
builder[having ? 'havingExists' : 'whereExists'](wheres);
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
// notexists
|
|
976
|
+
if (op === Op.notExists) {
|
|
977
|
+
builder[having ? 'havingNotExists' : 'whereNotExists'](wheres);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
function _buildWhereColumn(having, knex, builder, column, value, op) {
|
|
981
|
+
// skip
|
|
982
|
+
if (value === Op.skip) {
|
|
983
|
+
return;
|
|
984
|
+
}
|
|
985
|
+
// raw
|
|
986
|
+
if (isRaw(value)) {
|
|
987
|
+
_buildWhereColumnOpNormal(having, knex, builder, column, value, op ?? Op.eq);
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
// null/undefined
|
|
991
|
+
if (isNil(value)) {
|
|
992
|
+
_buildWhereColumnOpNormal(having, knex, builder, column, value, op ?? Op.is);
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
// array
|
|
996
|
+
if (Array.isArray(value)) {
|
|
997
|
+
_buildWhereColumnOpNormal(having, knex, builder, column, value, op ?? Op.in);
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
1000
|
+
// date
|
|
1001
|
+
if (value instanceof Date) {
|
|
1002
|
+
_buildWhereColumnOpNormal(having, knex, builder, column, value, op ?? Op.eq);
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
// object
|
|
1006
|
+
if (typeof value === 'object') {
|
|
1007
|
+
builder[having ? 'having' : 'where'](builder => {
|
|
1008
|
+
_buildWhereInner(false, knex, builder, value, column);
|
|
1009
|
+
});
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
// column
|
|
1013
|
+
_buildWhereColumnOpNormal(having, knex, builder, column, value, op ?? Op.eq);
|
|
1014
|
+
}
|
|
1015
|
+
function _buildWhereColumnOpNormal(having, knex, builder, column, value, op) {
|
|
1016
|
+
column = _checkHavingColumn(knex, column);
|
|
1017
|
+
if (op === Op.eq) {
|
|
1018
|
+
builder[having ? 'having' : 'where'](column, '=', value);
|
|
1019
|
+
} else if (op === Op.notEq) {
|
|
1020
|
+
builder[having ? 'having' : 'where'](column, '<>', value);
|
|
1021
|
+
} else if (op === Op.gt) {
|
|
1022
|
+
builder[having ? 'having' : 'where'](column, '>', value);
|
|
1023
|
+
} else if (op === Op.gte) {
|
|
1024
|
+
builder[having ? 'having' : 'where'](column, '>=', value);
|
|
1025
|
+
} else if (op === Op.lt) {
|
|
1026
|
+
builder[having ? 'having' : 'where'](column, '<', value);
|
|
1027
|
+
} else if (op === Op.lte) {
|
|
1028
|
+
builder[having ? 'having' : 'where'](column, '<=', value);
|
|
1029
|
+
} else if (op === Op.in) {
|
|
1030
|
+
builder[having ? 'havingIn' : 'whereIn'](column, value);
|
|
1031
|
+
} else if (op === Op.notIn) {
|
|
1032
|
+
builder[having ? 'havingNotIn' : 'whereNotIn'](column, value);
|
|
1033
|
+
} else if (op === Op.is) {
|
|
1034
|
+
builder[having ? 'havingNull' : 'whereNull'](column);
|
|
1035
|
+
} else if (op === Op.isNot) {
|
|
1036
|
+
builder[having ? 'havingNotNull' : 'whereNotNull'](column);
|
|
1037
|
+
} else if (op === Op.between) {
|
|
1038
|
+
builder[having ? 'havingBetween' : 'whereBetween'](column, value);
|
|
1039
|
+
} else if (op === Op.notBetween) {
|
|
1040
|
+
builder[having ? 'havingNotBetween' : 'whereNotBetween'](column, value);
|
|
1041
|
+
} else if (op === Op.startsWith) {
|
|
1042
|
+
builder[having ? 'havingLike' : 'whereLike'](column, `${value}%`);
|
|
1043
|
+
} else if (op === Op.endsWith) {
|
|
1044
|
+
builder[having ? 'havingLike' : 'whereLike'](column, `%${value}`);
|
|
1045
|
+
} else if (op === Op.includes) {
|
|
1046
|
+
builder[having ? 'havingLike' : 'whereLike'](column, `%${value}%`);
|
|
1047
|
+
} else if (op === Op.startsWithI) {
|
|
1048
|
+
builder[having ? 'havingILike' : 'whereILike'](column, `${value}%`);
|
|
1049
|
+
} else if (op === Op.endsWithI) {
|
|
1050
|
+
builder[having ? 'havingILike' : 'whereILike'](column, `%${value}`);
|
|
1051
|
+
} else if (op === Op.includesI) {
|
|
1052
|
+
builder[having ? 'havingILike' : 'whereILike'](column, `%${value}%`);
|
|
1053
|
+
} else if (op === Op.ref) {
|
|
1054
|
+
builder[having ? 'having' : 'where'](column, '=', knex.ref(value));
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
function _checkHavingColumn(knex, column) {
|
|
1058
|
+
let [aggr, name] = cast(column).split('_');
|
|
1059
|
+
if (!OpAggrs.includes(aggr) || !name) return column;
|
|
1060
|
+
if (aggr === 'count' && name === 'all') name = '*';
|
|
1061
|
+
return knex.raw(`${_safeOp(aggr)}(${_safeColumn(name)})`);
|
|
1062
|
+
}
|
|
1063
|
+
function isAggrColumn(column) {
|
|
1064
|
+
const [aggr, name] = cast(column).split('_');
|
|
1065
|
+
if (!OpAggrs.includes(aggr) || !name) return false;
|
|
1066
|
+
return true;
|
|
1067
|
+
}
|
|
1068
|
+
function _checkOpJoint(op) {
|
|
1069
|
+
for (const item of OpJointValues) {
|
|
1070
|
+
if (op.startsWith(item)) {
|
|
1071
|
+
return item;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
return undefined;
|
|
1075
|
+
}
|
|
1076
|
+
function _safeOp(op) {
|
|
1077
|
+
return op.replace(/[\\.*#%'"`;,() ]/g, '');
|
|
1078
|
+
}
|
|
1079
|
+
function _safeColumn(column) {
|
|
1080
|
+
return column.replace(/[\\.#%'"`;,() ]/g, '');
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
function $column(key) {
|
|
1084
|
+
return key;
|
|
1085
|
+
}
|
|
1086
|
+
function $columns(key) {
|
|
1087
|
+
return key;
|
|
1088
|
+
}
|
|
1089
|
+
function $columnsAll(classEntity, withTableName, withMeta) {
|
|
1090
|
+
const classEntity2 = _prepareClassEntity(classEntity);
|
|
1091
|
+
let columns = appMetadata.getMetadata(SymbolDecoratorRuleColumn, classEntity2.prototype);
|
|
1092
|
+
if (withTableName) {
|
|
1093
|
+
const tableName = $tableName(classEntity2);
|
|
1094
|
+
columns = {
|
|
1095
|
+
...columns,
|
|
1096
|
+
$table: tableName
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
if (withMeta) {
|
|
1100
|
+
const comments = $tableComments(classEntity2);
|
|
1101
|
+
const defaults = $tableDefaults(classEntity2);
|
|
1102
|
+
columns = {
|
|
1103
|
+
...columns,
|
|
1104
|
+
$comment: comments,
|
|
1105
|
+
$default: defaults
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
return columns;
|
|
1109
|
+
}
|
|
1110
|
+
function $tableColumns(classEntity, key) {
|
|
1111
|
+
// tableName
|
|
1112
|
+
const tableName = $tableName(classEntity);
|
|
1113
|
+
return {
|
|
1114
|
+
[tableName]: key
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
function $tableName(classEntity) {
|
|
1118
|
+
const beanOptionsEntity = appResource.getBean(_prepareClassEntity(classEntity));
|
|
1119
|
+
const entityOptions = beanOptionsEntity?.options;
|
|
1120
|
+
return entityOptions.table;
|
|
1121
|
+
}
|
|
1122
|
+
function $tableComments(classEntity) {
|
|
1123
|
+
const app = useApp();
|
|
1124
|
+
const classEntity2 = _prepareClassEntity(classEntity);
|
|
1125
|
+
// rules
|
|
1126
|
+
const rules = getTargetDecoratorRules(classEntity2.prototype);
|
|
1127
|
+
const comments = {};
|
|
1128
|
+
for (const key in rules) {
|
|
1129
|
+
const rule = rules[key];
|
|
1130
|
+
const comment = rule._def.openapi?.metadata?.description || rule._def.openapi?.metadata?.title;
|
|
1131
|
+
comments[key] = comment ? app.meta.text(comment) : '';
|
|
1132
|
+
}
|
|
1133
|
+
// table comment
|
|
1134
|
+
const beanOptions = appResource.getBean(classEntity2);
|
|
1135
|
+
if (beanOptions) {
|
|
1136
|
+
const openapi = cast(beanOptions.options)?.openapi;
|
|
1137
|
+
const comment = openapi?.description || openapi?.title;
|
|
1138
|
+
cast(comments).$table = comment ? app.meta.text(comment) : '';
|
|
1139
|
+
}
|
|
1140
|
+
// ok
|
|
1141
|
+
return comments;
|
|
1142
|
+
}
|
|
1143
|
+
function $tableDefaults(classEntity) {
|
|
1144
|
+
const classEntity2 = _prepareClassEntity(classEntity);
|
|
1145
|
+
// rules
|
|
1146
|
+
const rules = getTargetDecoratorRules(classEntity2.prototype);
|
|
1147
|
+
const defaults = {};
|
|
1148
|
+
for (const key in rules) {
|
|
1149
|
+
const rule = rules[key];
|
|
1150
|
+
defaults[key] = ZodMetadata.getDefaultValue(rule);
|
|
1151
|
+
}
|
|
1152
|
+
// ok
|
|
1153
|
+
return defaults;
|
|
1154
|
+
}
|
|
1155
|
+
function _prepareClassEntity(classEntity) {
|
|
1156
|
+
return isClass(classEntity) ? classEntity : cast(classEntity)();
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
const SymbolKeyFieldsMore = Symbol('$fieldsMore');
|
|
1160
|
+
|
|
1161
|
+
function _applyDecoratedDescriptor(i, e, r, n, l) {
|
|
1162
|
+
var a = {};
|
|
1163
|
+
return Object.keys(n).forEach(function (i) {
|
|
1164
|
+
a[i] = n[i];
|
|
1165
|
+
}), a.enumerable = !!a.enumerable, a.configurable = !!a.configurable, ("value" in a || a.initializer) && (a.writable = true), a = r.slice().reverse().reduce(function (r, n) {
|
|
1166
|
+
return n(i, e, r) || r;
|
|
1167
|
+
}, a), void 0 === a.initializer ? (Object.defineProperty(i, e, a), null) : a;
|
|
1168
|
+
}
|
|
1169
|
+
function _initializerDefineProperty(e, i, r, l) {
|
|
1170
|
+
r && Object.defineProperty(e, i, {
|
|
1171
|
+
enumerable: r.enumerable,
|
|
1172
|
+
configurable: r.configurable,
|
|
1173
|
+
writable: r.writable,
|
|
1174
|
+
value: r.initializer ? r.initializer.call(l) : void 0
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
class EntityBaseEmpty {}
|
|
1179
|
+
|
|
1180
|
+
var _dec$g, _dec2$g, _dec3$4, _dec4$2, _dec5, _dec6, _dec7, _dec8, _class$g, _descriptor$2, _descriptor2, _descriptor3, _descriptor4;
|
|
1181
|
+
let EntityBaseInner = (_dec$g = Api.field(v.openapi({
|
|
1182
|
+
title: $locale('CreatedAt'),
|
|
1183
|
+
rest: {
|
|
1184
|
+
order: OrderMaxBase - 2
|
|
1185
|
+
}
|
|
1186
|
+
})), _dec2$g = Reflect.metadata("design:type", typeof Date === "undefined" ? Object : Date), _dec3$4 = Api.field(v.openapi({
|
|
1187
|
+
title: $locale('UpdatedAt'),
|
|
1188
|
+
rest: {
|
|
1189
|
+
order: OrderMaxBase - 1
|
|
1190
|
+
}
|
|
1191
|
+
})), _dec4$2 = Reflect.metadata("design:type", typeof Date === "undefined" ? Object : Date), _dec5 = Api.field(v.openapi({
|
|
1192
|
+
title: $locale('Deleted'),
|
|
1193
|
+
rest: {
|
|
1194
|
+
visible: false
|
|
1195
|
+
}
|
|
1196
|
+
}), v.default(false)), _dec6 = Reflect.metadata("design:type", Boolean), _dec7 = Api.field(v.openapi({
|
|
1197
|
+
title: $locale('InstanceId'),
|
|
1198
|
+
rest: {
|
|
1199
|
+
visible: false
|
|
1200
|
+
}
|
|
1201
|
+
}), v.default(0)), _dec8 = Reflect.metadata("design:type", Number), _class$g = class EntityBaseInner extends EntityBaseEmpty {
|
|
1202
|
+
constructor(...args) {
|
|
1203
|
+
super(...args);
|
|
1204
|
+
_initializerDefineProperty(this, "createdAt", _descriptor$2, this);
|
|
1205
|
+
_initializerDefineProperty(this, "updatedAt", _descriptor2, this);
|
|
1206
|
+
_initializerDefineProperty(this, "deleted", _descriptor3, this);
|
|
1207
|
+
_initializerDefineProperty(this, "iid", _descriptor4, this);
|
|
1208
|
+
}
|
|
1209
|
+
}, _descriptor$2 = _applyDecoratedDescriptor(_class$g.prototype, "createdAt", [_dec$g, _dec2$g], {
|
|
1210
|
+
configurable: true,
|
|
1211
|
+
enumerable: true,
|
|
1212
|
+
writable: true,
|
|
1213
|
+
initializer: null
|
|
1214
|
+
}), _descriptor2 = _applyDecoratedDescriptor(_class$g.prototype, "updatedAt", [_dec3$4, _dec4$2], {
|
|
1215
|
+
configurable: true,
|
|
1216
|
+
enumerable: true,
|
|
1217
|
+
writable: true,
|
|
1218
|
+
initializer: null
|
|
1219
|
+
}), _descriptor3 = _applyDecoratedDescriptor(_class$g.prototype, "deleted", [_dec5, _dec6], {
|
|
1220
|
+
configurable: true,
|
|
1221
|
+
enumerable: true,
|
|
1222
|
+
writable: true,
|
|
1223
|
+
initializer: null
|
|
1224
|
+
}), _descriptor4 = _applyDecoratedDescriptor(_class$g.prototype, "iid", [_dec7, _dec8], {
|
|
1225
|
+
configurable: true,
|
|
1226
|
+
enumerable: true,
|
|
1227
|
+
writable: true,
|
|
1228
|
+
initializer: null
|
|
1229
|
+
}), _class$g);
|
|
1230
|
+
|
|
1231
|
+
var _dec$f, _dec2$f, _class$f, _descriptor$1;
|
|
1232
|
+
let EntityBase = (_dec$f = Api.field(v.openapi({
|
|
1233
|
+
title: $locale('TableIdentity'),
|
|
1234
|
+
rest: {
|
|
1235
|
+
order: OrderCoreBase + 1
|
|
1236
|
+
}
|
|
1237
|
+
}), v.tableIdentity()), _dec2$f = Reflect.metadata("design:type", typeof TableIdentity === "undefined" ? Object : TableIdentity), _class$f = class EntityBase extends EntityBaseInner {
|
|
1238
|
+
constructor(...args) {
|
|
1239
|
+
super(...args);
|
|
1240
|
+
_initializerDefineProperty(this, "id", _descriptor$1, this);
|
|
1241
|
+
}
|
|
1242
|
+
}, _descriptor$1 = _applyDecoratedDescriptor(_class$f.prototype, "id", [_dec$f, _dec2$f], {
|
|
1243
|
+
configurable: true,
|
|
1244
|
+
enumerable: true,
|
|
1245
|
+
writable: true,
|
|
1246
|
+
initializer: null
|
|
1247
|
+
}), _class$f);
|
|
1248
|
+
|
|
1249
|
+
var _dec$e, _dec2$e, _class$e, _descriptor;
|
|
1250
|
+
let EntityBaseSimple = (_dec$e = Api.field(v.openapi({
|
|
1251
|
+
title: $locale('TableIdentity'),
|
|
1252
|
+
rest: {
|
|
1253
|
+
order: OrderCoreBase + 1
|
|
1254
|
+
}
|
|
1255
|
+
})), _dec2$e = Reflect.metadata("design:type", Number), _class$e = class EntityBaseSimple extends EntityBaseInner {
|
|
1256
|
+
constructor(...args) {
|
|
1257
|
+
super(...args);
|
|
1258
|
+
_initializerDefineProperty(this, "id", _descriptor, this);
|
|
1259
|
+
}
|
|
1260
|
+
}, _descriptor = _applyDecoratedDescriptor(_class$e.prototype, "id", [_dec$e, _dec2$e], {
|
|
1261
|
+
configurable: true,
|
|
1262
|
+
enumerable: true,
|
|
1263
|
+
writable: true,
|
|
1264
|
+
initializer: null
|
|
1265
|
+
}), _class$e);
|
|
1266
|
+
|
|
1267
|
+
const SymbolKeyEntity = Symbol('$entity');
|
|
1268
|
+
const SymbolKeyEntityMeta = Symbol('$entityMeta');
|
|
1269
|
+
const SymbolKeyModelOptions = Symbol('$modelOptions');
|
|
1270
|
+
|
|
1271
|
+
const SymbolModelDb = Symbol('SymbolModelDb');
|
|
1272
|
+
const SymbolModelTable = Symbol('SymbolModelTable');
|
|
1273
|
+
class BeanModelMeta extends BeanBase {
|
|
1274
|
+
constructor(...args) {
|
|
1275
|
+
super(...args);
|
|
1276
|
+
this[SymbolKeyEntity] = void 0;
|
|
1277
|
+
this[SymbolKeyEntityMeta] = void 0;
|
|
1278
|
+
this[SymbolKeyModelOptions] = void 0;
|
|
1279
|
+
this[SymbolModelDb] = void 0;
|
|
1280
|
+
this[SymbolModelTable] = void 0;
|
|
1281
|
+
}
|
|
1282
|
+
__init__(clientName, table) {
|
|
1283
|
+
// clientName
|
|
1284
|
+
if (!isNil(clientName)) {
|
|
1285
|
+
if (typeof clientName === 'string') {
|
|
1286
|
+
this[SymbolModelDb] = this.bean.database.getDb(clientName);
|
|
1287
|
+
} else {
|
|
1288
|
+
this[SymbolModelDb] = clientName;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
// table
|
|
1292
|
+
this[SymbolModelTable] = table;
|
|
1293
|
+
}
|
|
1294
|
+
get self() {
|
|
1295
|
+
return cast(this);
|
|
1296
|
+
}
|
|
1297
|
+
get connection() {
|
|
1298
|
+
return this.db.connection;
|
|
1299
|
+
}
|
|
1300
|
+
get dialect() {
|
|
1301
|
+
return this.db.dialect;
|
|
1302
|
+
}
|
|
1303
|
+
get scopeOrm() {
|
|
1304
|
+
return this.$scope.orm;
|
|
1305
|
+
}
|
|
1306
|
+
get modelViewRecord() {
|
|
1307
|
+
return this.$scope.version.model.viewRecord;
|
|
1308
|
+
}
|
|
1309
|
+
get db() {
|
|
1310
|
+
return this[SymbolModelDb] ?? this._getDb();
|
|
1311
|
+
}
|
|
1312
|
+
_getDb() {
|
|
1313
|
+
let clientName = this.options.client;
|
|
1314
|
+
// use current
|
|
1315
|
+
if (!clientName) return this.bean.database.current;
|
|
1316
|
+
// custom clientName
|
|
1317
|
+
if (typeof clientName === 'function') {
|
|
1318
|
+
clientName = clientName(this.ctx, this);
|
|
1319
|
+
}
|
|
1320
|
+
// db
|
|
1321
|
+
return this.bean.database.getDb(clientName);
|
|
1322
|
+
}
|
|
1323
|
+
getTable() {
|
|
1324
|
+
return this[SymbolModelTable] ?? this._getTable();
|
|
1325
|
+
}
|
|
1326
|
+
_getTable() {
|
|
1327
|
+
const table = this.options.table;
|
|
1328
|
+
if (table && typeof table === 'string') return table;
|
|
1329
|
+
const defaultTable = this.options.entity && $tableName(this.options.entity);
|
|
1330
|
+
if (table && typeof table === 'function') {
|
|
1331
|
+
return table(this.ctx, defaultTable, this);
|
|
1332
|
+
}
|
|
1333
|
+
if (defaultTable) return defaultTable;
|
|
1334
|
+
throw new Error(`not found table of ${this.$beanFullName}`);
|
|
1335
|
+
}
|
|
1336
|
+
get options() {
|
|
1337
|
+
return this.$beanOptions.options || {};
|
|
1338
|
+
}
|
|
1339
|
+
get disableInstance() {
|
|
1340
|
+
return this.options.disableInstance ?? this.scopeOrm.config.model.disableInstance;
|
|
1341
|
+
}
|
|
1342
|
+
get disableDeleted() {
|
|
1343
|
+
return this.options.disableDeleted ?? this.scopeOrm.config.model.disableDeleted;
|
|
1344
|
+
}
|
|
1345
|
+
get disableCreateTime() {
|
|
1346
|
+
return this.options.disableCreateTime ?? this.scopeOrm.config.model.disableCreateTime;
|
|
1347
|
+
}
|
|
1348
|
+
get disableUpdateTime() {
|
|
1349
|
+
return this.options.disableUpdateTime ?? this.scopeOrm.config.model.disableUpdateTime;
|
|
1350
|
+
}
|
|
1351
|
+
_prepareDisableInstanceByOptions(table, data, options, useRaw) {
|
|
1352
|
+
const columnNameInstance = useRaw ? 'iid' : `${getTableOrTableAlias(table)}.iid`;
|
|
1353
|
+
if (this._checkDisableInstanceByOptions(options)) {
|
|
1354
|
+
delete data.iid;
|
|
1355
|
+
delete data[columnNameInstance];
|
|
1356
|
+
} else {
|
|
1357
|
+
delete data.iid;
|
|
1358
|
+
if (!isNil(options?.iid)) {
|
|
1359
|
+
data[columnNameInstance] = options?.iid;
|
|
1360
|
+
} else {
|
|
1361
|
+
if (!this.ctx.instance) {
|
|
1362
|
+
throw new Error('ctx.instance not exists');
|
|
1363
|
+
}
|
|
1364
|
+
data[columnNameInstance] = this.ctx.instance.id;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
return data;
|
|
1368
|
+
}
|
|
1369
|
+
_prepareDisableDeletedByOptions(table, data, options, useRaw) {
|
|
1370
|
+
const columnNameDeleted = useRaw ? 'deleted' : `${getTableOrTableAlias(table)}.deleted`;
|
|
1371
|
+
const deleted = this._prepareDisableDeletedByOptionsSimple(options);
|
|
1372
|
+
if (!isNil(deleted)) {
|
|
1373
|
+
delete data.deleted; // force
|
|
1374
|
+
data[columnNameDeleted] = deleted;
|
|
1375
|
+
}
|
|
1376
|
+
return data;
|
|
1377
|
+
}
|
|
1378
|
+
_prepareDisableDeletedByOptionsSimple(options) {
|
|
1379
|
+
if (!isNil(options?.deleted)) {
|
|
1380
|
+
if (!this.disableDeleted) {
|
|
1381
|
+
return options?.deleted;
|
|
1382
|
+
}
|
|
1383
|
+
} else {
|
|
1384
|
+
if (this._checkDisableDeletedByOptions(options)) ; else {
|
|
1385
|
+
return false;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
return undefined;
|
|
1389
|
+
}
|
|
1390
|
+
_checkIfEntityValidByDeleted(entity, options) {
|
|
1391
|
+
const deleted = this._prepareDisableDeletedByOptionsSimple(options);
|
|
1392
|
+
return isNil(deleted) || Boolean(entity.deleted) === Boolean(deleted);
|
|
1393
|
+
}
|
|
1394
|
+
_checkDisableInstanceByOptions(options) {
|
|
1395
|
+
return options?.disableInstance ?? this.disableInstance;
|
|
1396
|
+
}
|
|
1397
|
+
_checkDisableDeletedByOptions(options) {
|
|
1398
|
+
if (this.disableDeleted) return true;
|
|
1399
|
+
return options?.disableDeleted ?? this.disableDeleted;
|
|
1400
|
+
}
|
|
1401
|
+
_checkDisableCreateTimeByOptions(options) {
|
|
1402
|
+
return options?.disableCreateTime ?? this.disableCreateTime;
|
|
1403
|
+
}
|
|
1404
|
+
_checkDisableUpdateTimeByOptions(options) {
|
|
1405
|
+
return options?.disableUpdateTime ?? this.disableUpdateTime;
|
|
1406
|
+
}
|
|
1407
|
+
newInstance(client, table) {
|
|
1408
|
+
return this.app.bean._newBean(this.$beanFullName, client ?? this.db, table);
|
|
1409
|
+
}
|
|
1410
|
+
newInstanceTarget(modelClassTarget, client, table) {
|
|
1411
|
+
const modelClass2 = prepareClassModel(modelClassTarget);
|
|
1412
|
+
const beanOptions = appResource.getBean(modelClass2);
|
|
1413
|
+
const beanFullName = beanOptions.beanFullName;
|
|
1414
|
+
const options = beanOptions?.options;
|
|
1415
|
+
if (isNil(client) || client === 'auto') {
|
|
1416
|
+
client = options?.client ? 'initial' : 'inherit';
|
|
1417
|
+
}
|
|
1418
|
+
if (client === 'initial') {
|
|
1419
|
+
return this.app.bean._newBean(beanFullName, undefined, table);
|
|
1420
|
+
} else if (client === 'inherit') {
|
|
1421
|
+
client = this.db;
|
|
1422
|
+
}
|
|
1423
|
+
return this.app.bean._newBean(beanFullName, client ?? this.db, table);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
class BeanModelUtils extends BeanModelMeta {
|
|
1428
|
+
async prepareData(table, item) {
|
|
1429
|
+
if (typeof table !== 'string') {
|
|
1430
|
+
item = table;
|
|
1431
|
+
table = undefined;
|
|
1432
|
+
}
|
|
1433
|
+
// table
|
|
1434
|
+
table = table || this.getTable();
|
|
1435
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
1436
|
+
// item
|
|
1437
|
+
if (!item) return [{}, {}];
|
|
1438
|
+
// columns
|
|
1439
|
+
const columns = await this.columns(table);
|
|
1440
|
+
// data
|
|
1441
|
+
const data = {};
|
|
1442
|
+
const dataOriginal = {};
|
|
1443
|
+
for (const columnName in columns) {
|
|
1444
|
+
const column = columns[columnName];
|
|
1445
|
+
if (Object.prototype.hasOwnProperty.call(item, columnName)) {
|
|
1446
|
+
let value = item[columnName];
|
|
1447
|
+
dataOriginal[columnName] = value;
|
|
1448
|
+
if (column.type === 'json' && value !== undefined) {
|
|
1449
|
+
value = JSON.stringify(value);
|
|
1450
|
+
}
|
|
1451
|
+
data[columnName] = value;
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
return [data, dataOriginal];
|
|
1455
|
+
}
|
|
1456
|
+
async defaultData(table) {
|
|
1457
|
+
if (this.options.entity) {
|
|
1458
|
+
return $tableDefaults(this.options.entity);
|
|
1459
|
+
}
|
|
1460
|
+
table = table || this.getTable();
|
|
1461
|
+
return await this.db.columns.defaultData(table);
|
|
1462
|
+
}
|
|
1463
|
+
async columns(table) {
|
|
1464
|
+
table = table || this.getTable();
|
|
1465
|
+
return await this.db.columns.columns(table);
|
|
1466
|
+
}
|
|
1467
|
+
isRaw(raw) {
|
|
1468
|
+
return isRaw(raw);
|
|
1469
|
+
}
|
|
1470
|
+
raw(sql, bindings) {
|
|
1471
|
+
return this.connection.raw(sql, bindings);
|
|
1472
|
+
}
|
|
1473
|
+
ref(src) {
|
|
1474
|
+
return this.connection.ref(src);
|
|
1475
|
+
}
|
|
1476
|
+
toIdentifier(name) {
|
|
1477
|
+
const parts = Array.isArray(name) ? name : name.split(',');
|
|
1478
|
+
return this.raw(parts.map(_ => '??').join(','), parts);
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
// checkWhere(where: TypeModelWhere<TRecord>) {
|
|
1482
|
+
// return checkWhere(where);
|
|
1483
|
+
// }
|
|
1484
|
+
|
|
1485
|
+
buildWhere(builder, wheres) {
|
|
1486
|
+
if (!wheres) return;
|
|
1487
|
+
return buildWhere(this.connection, builder, wheres);
|
|
1488
|
+
}
|
|
1489
|
+
buildJoin(builder, join) {
|
|
1490
|
+
if (!join) return;
|
|
1491
|
+
const [joinType, joinTable, joinOn] = join;
|
|
1492
|
+
builder[joinType](joinTable, cast(joinOn));
|
|
1493
|
+
}
|
|
1494
|
+
buildJoins(builder, joins) {
|
|
1495
|
+
if (!joins) return;
|
|
1496
|
+
for (const [joinType, joinTable, joinOn] of joins) {
|
|
1497
|
+
if (Array.isArray(joinOn)) {
|
|
1498
|
+
cast(builder)[joinType](joinTable, ...joinOn);
|
|
1499
|
+
} else {
|
|
1500
|
+
builder[joinType](joinTable, joinOn);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
buildDistinct(builder, distinct) {
|
|
1505
|
+
if (distinct === undefined || distinct === false) return;
|
|
1506
|
+
if (distinct === true) {
|
|
1507
|
+
builder.distinct();
|
|
1508
|
+
} else if (Array.isArray(distinct)) {
|
|
1509
|
+
builder.distinct(...distinct);
|
|
1510
|
+
} else {
|
|
1511
|
+
builder.distinct(distinct);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
buildCount(builder, column, distinct) {
|
|
1515
|
+
if (column !== undefined) {
|
|
1516
|
+
builder.count(column);
|
|
1517
|
+
} else if (distinct !== undefined && distinct !== false) {
|
|
1518
|
+
builder.count(this.raw(`distinct ${this.toIdentifier(distinct)}`));
|
|
1519
|
+
} else {
|
|
1520
|
+
builder.count();
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
buildOrders(builder, orders) {
|
|
1524
|
+
if (!orders) return;
|
|
1525
|
+
for (const [orderColumn, orderDirection, orderNulls] of orders) {
|
|
1526
|
+
builder.orderBy(orderColumn, orderDirection, orderNulls);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
buildLimit(builder, limit) {
|
|
1530
|
+
if (limit !== 0 && limit !== undefined) {
|
|
1531
|
+
builder.limit(limit);
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
buildOffset(builder, offset) {
|
|
1535
|
+
if (offset !== undefined) {
|
|
1536
|
+
builder.offset(offset);
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
buildColumns(builder, columns, groups) {
|
|
1540
|
+
if (columns) {
|
|
1541
|
+
builder.select(columns);
|
|
1542
|
+
} else if (groups) {
|
|
1543
|
+
builder.select(groups);
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
buildGroups(builder, groups) {
|
|
1547
|
+
if (!groups) return;
|
|
1548
|
+
groups = ensureArray(groups);
|
|
1549
|
+
builder.groupBy(groups);
|
|
1550
|
+
return groups;
|
|
1551
|
+
}
|
|
1552
|
+
buildAggrs(builder, aggrs) {
|
|
1553
|
+
if (!aggrs) return;
|
|
1554
|
+
for (const key in aggrs) {
|
|
1555
|
+
const columns = ensureArray(aggrs[key]);
|
|
1556
|
+
if (!columns) continue;
|
|
1557
|
+
for (const column of columns) {
|
|
1558
|
+
const column2 = `${key}_${column === '*' ? 'all' : column}`;
|
|
1559
|
+
builder[key](column, {
|
|
1560
|
+
as: column2
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
buildPage(builder, page) {
|
|
1566
|
+
if (!page) return;
|
|
1567
|
+
this.buildLimit(builder, page.size);
|
|
1568
|
+
this.buildOffset(builder, page.index);
|
|
1569
|
+
}
|
|
1570
|
+
prepareHaving(builder, having) {
|
|
1571
|
+
if (!having) return;
|
|
1572
|
+
this.buildHaving(builder, having);
|
|
1573
|
+
}
|
|
1574
|
+
buildHaving(builder, having) {
|
|
1575
|
+
return buildWhere(this.connection, builder, having, true);
|
|
1576
|
+
}
|
|
1577
|
+
prepareWhere(builder, table, where, options) {
|
|
1578
|
+
// table
|
|
1579
|
+
table = table || this.getTable();
|
|
1580
|
+
if (!table) throw new Error('should specify the table name');
|
|
1581
|
+
// disableInstance/disableDeleted
|
|
1582
|
+
where = Object.assign({}, where);
|
|
1583
|
+
where = this._prepareWhereByOptions(table, where, options);
|
|
1584
|
+
// build
|
|
1585
|
+
this.buildWhere(builder, where);
|
|
1586
|
+
}
|
|
1587
|
+
convertItemsToBigNumber(items) {
|
|
1588
|
+
for (const item of items) {
|
|
1589
|
+
for (const key in item) {
|
|
1590
|
+
if (isAggrColumn(key)) {
|
|
1591
|
+
if (!isNil(item[key])) {
|
|
1592
|
+
item[key] = BigNumber(item[key]);
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
return items;
|
|
1598
|
+
}
|
|
1599
|
+
extractCount(result, columnName) {
|
|
1600
|
+
return this.extractFirstNumber(result, 0, columnName);
|
|
1601
|
+
}
|
|
1602
|
+
extractFirstNumber(result, defaultValue, columnName) {
|
|
1603
|
+
const value = this.extractFirstValue(result, defaultValue, columnName);
|
|
1604
|
+
if (value === undefined || value === null) return undefined;
|
|
1605
|
+
return BigNumber(value);
|
|
1606
|
+
}
|
|
1607
|
+
extractFirstValue(result, defaultValue, columnName) {
|
|
1608
|
+
const value = this._extractFirstValue(result, columnName);
|
|
1609
|
+
if (value === undefined || value === null) return defaultValue;
|
|
1610
|
+
return value;
|
|
1611
|
+
}
|
|
1612
|
+
_extractFirstValue(result, columnName) {
|
|
1613
|
+
const res = Array.isArray(result) ? result[0] : result;
|
|
1614
|
+
if (!res) return undefined;
|
|
1615
|
+
if (columnName) return res[columnName];
|
|
1616
|
+
const keys = Object.keys(res);
|
|
1617
|
+
if (keys.length === 0) return undefined;
|
|
1618
|
+
return res[keys[0]];
|
|
1619
|
+
}
|
|
1620
|
+
_prepareWhereByOptions(table, where, options) {
|
|
1621
|
+
// disableInstance: should not check if specified
|
|
1622
|
+
where = this._prepareDisableInstanceByOptions(table, where, options);
|
|
1623
|
+
// disableDeleted: should not check if specified
|
|
1624
|
+
where = this._prepareDisableDeletedByOptions(table, where, options);
|
|
1625
|
+
// ok
|
|
1626
|
+
return where;
|
|
1627
|
+
}
|
|
1628
|
+
_prepareInsertDataByOptions(table, data, options) {
|
|
1629
|
+
let result = Object.assign({}, data);
|
|
1630
|
+
// disableInstance: should not check if specified
|
|
1631
|
+
result = this._prepareDisableInstanceByOptions(table, result, options, true);
|
|
1632
|
+
// disableDeleted: should not check if specified
|
|
1633
|
+
result = this._prepareDisableDeletedByOptions(table, result, options, true);
|
|
1634
|
+
// createdAt/updatedAt
|
|
1635
|
+
if (isNil(result.createdAt)) {
|
|
1636
|
+
if (!this._checkDisableCreateTimeByOptions(options)) {
|
|
1637
|
+
result.createdAt = new Date();
|
|
1638
|
+
} else {
|
|
1639
|
+
delete result.createdAt;
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
if (isNil(result.updatedAt)) {
|
|
1643
|
+
if (!this._checkDisableUpdateTimeByOptions(options)) {
|
|
1644
|
+
result.updatedAt = new Date();
|
|
1645
|
+
} else {
|
|
1646
|
+
delete result.updatedAt;
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
return result;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
class BeanModelKnex extends BeanModelUtils {
|
|
1654
|
+
get schema() {
|
|
1655
|
+
return this.connection.schema;
|
|
1656
|
+
}
|
|
1657
|
+
builder(table) {
|
|
1658
|
+
// table
|
|
1659
|
+
table = table || this.getTable();
|
|
1660
|
+
if (table) {
|
|
1661
|
+
return this.connection(table);
|
|
1662
|
+
}
|
|
1663
|
+
return this.connection.queryBuilder();
|
|
1664
|
+
}
|
|
1665
|
+
builderSelect(table, options) {
|
|
1666
|
+
if (typeof table !== 'string') {
|
|
1667
|
+
options = table;
|
|
1668
|
+
table = undefined;
|
|
1669
|
+
}
|
|
1670
|
+
// table
|
|
1671
|
+
table = table || this.getTable();
|
|
1672
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
1673
|
+
// builder
|
|
1674
|
+
const builder = this.builder(table);
|
|
1675
|
+
// where
|
|
1676
|
+
this.prepareWhere(builder, table, {}, options);
|
|
1677
|
+
// ready
|
|
1678
|
+
return builder;
|
|
1679
|
+
}
|
|
1680
|
+
async query(sql, bindings) {
|
|
1681
|
+
const raw = this.connection.raw(sql, bindings);
|
|
1682
|
+
const result = await raw;
|
|
1683
|
+
// dialect
|
|
1684
|
+
return this.dialect.query(result);
|
|
1685
|
+
}
|
|
1686
|
+
async queryOne(sql, bindings) {
|
|
1687
|
+
const res = await this.query(sql, bindings);
|
|
1688
|
+
return res[0];
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1692
|
+
class BeanModelView extends BeanModelKnex {
|
|
1693
|
+
async createView(viewName, callback) {
|
|
1694
|
+
if (callback) {
|
|
1695
|
+
// create view
|
|
1696
|
+
let _view = null;
|
|
1697
|
+
await this.schema.createView(viewName, view => {
|
|
1698
|
+
_view = view;
|
|
1699
|
+
return callback(view);
|
|
1700
|
+
});
|
|
1701
|
+
// view sql
|
|
1702
|
+
const sql = cast(_view).toSQL();
|
|
1703
|
+
const viewSql = sql[0].sql;
|
|
1704
|
+
// record view
|
|
1705
|
+
const viewRecord = await this.modelViewRecord.get({
|
|
1706
|
+
viewName
|
|
1707
|
+
});
|
|
1708
|
+
if (viewRecord) {
|
|
1709
|
+
await this.modelViewRecord.update({
|
|
1710
|
+
id: viewRecord.id,
|
|
1711
|
+
viewSql
|
|
1712
|
+
});
|
|
1713
|
+
} else {
|
|
1714
|
+
await this.modelViewRecord.insert({
|
|
1715
|
+
viewName,
|
|
1716
|
+
viewSql
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1719
|
+
} else {
|
|
1720
|
+
// get record
|
|
1721
|
+
const viewRecord = await this.modelViewRecord.get({
|
|
1722
|
+
viewName
|
|
1723
|
+
});
|
|
1724
|
+
if (!viewRecord) throw new Error(`not found view record: ${viewName}`);
|
|
1725
|
+
await this.raw(viewRecord.viewSql);
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
async dropView(viewName, disableRemoveRecord) {
|
|
1729
|
+
// drop view: use dropViewIfExists
|
|
1730
|
+
await this.schema.dropViewIfExists(viewName);
|
|
1731
|
+
// remove record
|
|
1732
|
+
if (!disableRemoveRecord) {
|
|
1733
|
+
await this.modelViewRecord.delete({
|
|
1734
|
+
viewName
|
|
1735
|
+
});
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
async alterView(viewName, callback) {
|
|
1739
|
+
await this._viewDependentsAll_handle(viewName, async () => {
|
|
1740
|
+
// drop view
|
|
1741
|
+
await this.dropView(viewName, true);
|
|
1742
|
+
// create view
|
|
1743
|
+
await this.createView(viewName, callback);
|
|
1744
|
+
});
|
|
1745
|
+
}
|
|
1746
|
+
async createTable(tableName, callback) {
|
|
1747
|
+
await this.schema.createTable(tableName, callback);
|
|
1748
|
+
}
|
|
1749
|
+
async dropTable(tableName) {
|
|
1750
|
+
await this.schema.dropTable(tableName);
|
|
1751
|
+
}
|
|
1752
|
+
async alterTable(tableName, callback, alterViewAuto) {
|
|
1753
|
+
if (!alterViewAuto) {
|
|
1754
|
+
// alter table
|
|
1755
|
+
return await this.schema.alterTable(tableName, table => {
|
|
1756
|
+
return callback(table);
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
await this._viewDependentsAll_handle(tableName, async () => {
|
|
1760
|
+
await this.schema.alterTable(tableName, table => {
|
|
1761
|
+
return callback(table);
|
|
1762
|
+
});
|
|
1763
|
+
});
|
|
1764
|
+
}
|
|
1765
|
+
async viewDependents(viewName) {
|
|
1766
|
+
// builder
|
|
1767
|
+
const builder = this.builder();
|
|
1768
|
+
// dialect
|
|
1769
|
+
return await this.dialect.viewDependents(builder, viewName);
|
|
1770
|
+
}
|
|
1771
|
+
async viewDependentsAll(viewName) {
|
|
1772
|
+
// views
|
|
1773
|
+
const views = [{
|
|
1774
|
+
name: viewName,
|
|
1775
|
+
dependencies: []
|
|
1776
|
+
}];
|
|
1777
|
+
// dependencies all
|
|
1778
|
+
await this._viewDependentsAll_inner(viewName, views);
|
|
1779
|
+
// swap
|
|
1780
|
+
swapDeps(views);
|
|
1781
|
+
// shift
|
|
1782
|
+
views.shift();
|
|
1783
|
+
// ready
|
|
1784
|
+
return views.map(view => view.name);
|
|
1785
|
+
}
|
|
1786
|
+
async _viewDependentsAll_inner(viewName, views) {
|
|
1787
|
+
const dependents = await this.viewDependents(viewName);
|
|
1788
|
+
for (const dependent of dependents) {
|
|
1789
|
+
// dependencies
|
|
1790
|
+
const view = views.find(view => view.name === dependent);
|
|
1791
|
+
if (view) {
|
|
1792
|
+
const dep = cast(view.dependencies).find(dep => dep.toLowerCase() === viewName.toLowerCase());
|
|
1793
|
+
if (!dep) {
|
|
1794
|
+
cast(view.dependencies).push(viewName);
|
|
1795
|
+
}
|
|
1796
|
+
} else {
|
|
1797
|
+
views.push({
|
|
1798
|
+
name: dependent,
|
|
1799
|
+
dependencies: [viewName]
|
|
1800
|
+
});
|
|
1801
|
+
}
|
|
1802
|
+
// next
|
|
1803
|
+
await this._viewDependentsAll_inner(dependent, views);
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
async _viewDependentsAll_handle(viewName, callback) {
|
|
1807
|
+
// viewDependentsAll
|
|
1808
|
+
const viewDependents = await this.viewDependentsAll(viewName);
|
|
1809
|
+
// drop dependents
|
|
1810
|
+
for (let i = viewDependents.length - 1; i >= 0; i--) {
|
|
1811
|
+
const viewDependent = viewDependents[i];
|
|
1812
|
+
await this.dropView(viewDependent, true);
|
|
1813
|
+
}
|
|
1814
|
+
// callback
|
|
1815
|
+
await callback();
|
|
1816
|
+
// create dependents
|
|
1817
|
+
for (const viewDependent of viewDependents) {
|
|
1818
|
+
await this.createView(viewDependent);
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1823
|
+
class BeanModelCrudInner extends BeanModelView {
|
|
1824
|
+
async _mget(table, ids, options) {
|
|
1825
|
+
const items = await this._mget_original(table, ids, options);
|
|
1826
|
+
return items.filter(item => !isNil(item));
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
// with undefined
|
|
1830
|
+
async _mget_original(table, ids, options) {
|
|
1831
|
+
// table
|
|
1832
|
+
table = table || this.getTable();
|
|
1833
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
1834
|
+
// ids maybe empty
|
|
1835
|
+
if (!ids || ids.length === 0) return [];
|
|
1836
|
+
// params
|
|
1837
|
+
const params = {
|
|
1838
|
+
where: {
|
|
1839
|
+
id: ids
|
|
1840
|
+
}
|
|
1841
|
+
};
|
|
1842
|
+
if (options?.columns) {
|
|
1843
|
+
params.columns = options?.columns;
|
|
1844
|
+
}
|
|
1845
|
+
// select
|
|
1846
|
+
const options2 = options?.columns ? Object.assign({}, options, {
|
|
1847
|
+
columns: undefined
|
|
1848
|
+
}) : options;
|
|
1849
|
+
const items = await this._select(table, params, options2);
|
|
1850
|
+
// sort
|
|
1851
|
+
const result = [];
|
|
1852
|
+
for (const id of ids) {
|
|
1853
|
+
// item maybe undefined
|
|
1854
|
+
const item = items.find(item => cast(item).id === id);
|
|
1855
|
+
result.push(item);
|
|
1856
|
+
}
|
|
1857
|
+
return result;
|
|
1858
|
+
}
|
|
1859
|
+
async _select(table, params, options, builder) {
|
|
1860
|
+
// table
|
|
1861
|
+
table = table || this.getTable();
|
|
1862
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
1863
|
+
// builder
|
|
1864
|
+
builder = builder ?? this._select_buildParams(table, params, options);
|
|
1865
|
+
// ready
|
|
1866
|
+
this.$loggerChild('model').debug('model.select: %s', builder.toQuery());
|
|
1867
|
+
return await builder;
|
|
1868
|
+
}
|
|
1869
|
+
_select_buildParams(table, params, options) {
|
|
1870
|
+
// builder
|
|
1871
|
+
const builder = this.builder(table);
|
|
1872
|
+
// groups
|
|
1873
|
+
const groups = this.buildGroups(builder, params?.groups);
|
|
1874
|
+
// columns
|
|
1875
|
+
this.buildColumns(builder, params?.columns, groups);
|
|
1876
|
+
// distinct
|
|
1877
|
+
this.buildDistinct(builder, params?.distinct);
|
|
1878
|
+
// aggregate
|
|
1879
|
+
this.buildAggrs(builder, params?.aggrs);
|
|
1880
|
+
// joins
|
|
1881
|
+
this.buildJoins(builder, params?.joins);
|
|
1882
|
+
// where
|
|
1883
|
+
this.prepareWhere(builder, table, params?.where, options);
|
|
1884
|
+
// having
|
|
1885
|
+
this.prepareHaving(builder, params?.having);
|
|
1886
|
+
// orders
|
|
1887
|
+
this.buildOrders(builder, params?.orders);
|
|
1888
|
+
// limit
|
|
1889
|
+
this.buildLimit(builder, params?.limit);
|
|
1890
|
+
// offset
|
|
1891
|
+
this.buildOffset(builder, params?.offset);
|
|
1892
|
+
// ok
|
|
1893
|
+
return builder;
|
|
1894
|
+
}
|
|
1895
|
+
async _get(table, where, options) {
|
|
1896
|
+
// table
|
|
1897
|
+
table = table || this.getTable();
|
|
1898
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
1899
|
+
// params
|
|
1900
|
+
const params = {
|
|
1901
|
+
where,
|
|
1902
|
+
limit: 1
|
|
1903
|
+
};
|
|
1904
|
+
if (options?.columns) {
|
|
1905
|
+
params.columns = options?.columns;
|
|
1906
|
+
}
|
|
1907
|
+
// select
|
|
1908
|
+
const items = await this._select(table, params, options);
|
|
1909
|
+
const item = items[0];
|
|
1910
|
+
if (!item) return undefined;
|
|
1911
|
+
return item;
|
|
1912
|
+
}
|
|
1913
|
+
async _count(table, params, options) {
|
|
1914
|
+
// table
|
|
1915
|
+
table = table || this.getTable();
|
|
1916
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
1917
|
+
// params
|
|
1918
|
+
params = params || {};
|
|
1919
|
+
// builder
|
|
1920
|
+
const builder = this.builder(table);
|
|
1921
|
+
// count
|
|
1922
|
+
this.buildCount(builder, params.column, params.distinct);
|
|
1923
|
+
// joins
|
|
1924
|
+
this.buildJoins(builder, params.joins);
|
|
1925
|
+
// where
|
|
1926
|
+
this.prepareWhere(builder, table, params.where, options);
|
|
1927
|
+
// ready
|
|
1928
|
+
this.$loggerChild('model').debug('model.count: %s', builder.toQuery());
|
|
1929
|
+
const res = await builder;
|
|
1930
|
+
return this.extractFirstNumber(res);
|
|
1931
|
+
}
|
|
1932
|
+
async _insertBulk(table, data, options) {
|
|
1933
|
+
// table
|
|
1934
|
+
table = table || this.getTable();
|
|
1935
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
1936
|
+
// data
|
|
1937
|
+
data = data || {};
|
|
1938
|
+
const datasTemp = Array.isArray(data) ? data : [data];
|
|
1939
|
+
// options
|
|
1940
|
+
const datas = [];
|
|
1941
|
+
const datasOriginal = [];
|
|
1942
|
+
for (const dataTemp of datasTemp) {
|
|
1943
|
+
// first
|
|
1944
|
+
const dataTemp2 = this._prepareInsertDataByOptions(table, dataTemp, options);
|
|
1945
|
+
// then
|
|
1946
|
+
const [dataNew, dataNewOriginal] = await this.prepareData(table, dataTemp2);
|
|
1947
|
+
datas.push(dataNew);
|
|
1948
|
+
datasOriginal.push(dataNewOriginal);
|
|
1949
|
+
}
|
|
1950
|
+
// builder
|
|
1951
|
+
const builder = this.builder(table);
|
|
1952
|
+
// insert
|
|
1953
|
+
builder.insert(datas);
|
|
1954
|
+
// debug
|
|
1955
|
+
this.$loggerChild('model').debug('model.insert: %s', builder.toQuery());
|
|
1956
|
+
// dialect insert
|
|
1957
|
+
const ids = await this.dialect.insert(builder);
|
|
1958
|
+
// combine
|
|
1959
|
+
const result = [];
|
|
1960
|
+
const dataDefault = await this.defaultData(table);
|
|
1961
|
+
for (let index = 0; index < ids.length; index++) {
|
|
1962
|
+
const dataWithId = {};
|
|
1963
|
+
if (ids[index] !== undefined) dataWithId.id = ids[index];
|
|
1964
|
+
// datasOriginal[index] maybe has id
|
|
1965
|
+
result.push(Object.assign({}, dataDefault, dataWithId, datasOriginal[index]));
|
|
1966
|
+
}
|
|
1967
|
+
// ok
|
|
1968
|
+
return Array.isArray(data) ? result : result[0];
|
|
1969
|
+
}
|
|
1970
|
+
async _update(table, data, options) {
|
|
1971
|
+
// table
|
|
1972
|
+
table = table || this.getTable();
|
|
1973
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
1974
|
+
// data
|
|
1975
|
+
[data] = await this.prepareData(table, data);
|
|
1976
|
+
// where
|
|
1977
|
+
const where = Object.assign({}, options?.where);
|
|
1978
|
+
// id
|
|
1979
|
+
const columnId = `${table}.id`;
|
|
1980
|
+
for (const key of ['id', columnId]) {
|
|
1981
|
+
if (!isNil(data[key])) {
|
|
1982
|
+
cast(where).id = data[key];
|
|
1983
|
+
delete data[key];
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
// disableUpdateTime
|
|
1987
|
+
if (!this._checkDisableUpdateTimeByOptions(options)) {
|
|
1988
|
+
cast(data).updatedAt = new Date();
|
|
1989
|
+
}
|
|
1990
|
+
// builder
|
|
1991
|
+
const builder = this.builder(table);
|
|
1992
|
+
// update
|
|
1993
|
+
builder.update(data);
|
|
1994
|
+
// where
|
|
1995
|
+
this.prepareWhere(builder, table, where, options);
|
|
1996
|
+
// debug
|
|
1997
|
+
this.$loggerChild('model').debug('model.update: %s', builder.toQuery());
|
|
1998
|
+
// ready
|
|
1999
|
+
await builder;
|
|
2000
|
+
// ok
|
|
2001
|
+
return data;
|
|
2002
|
+
}
|
|
2003
|
+
async _delete(table, where, options) {
|
|
2004
|
+
// table
|
|
2005
|
+
table = table || this.getTable();
|
|
2006
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
2007
|
+
// disableDeleted
|
|
2008
|
+
if (!this._checkDisableDeletedByOptions(options)) {
|
|
2009
|
+
// need not set options2: disableDeleted: true, deleted: undefined
|
|
2010
|
+
const options2 = Object.assign({}, options, {
|
|
2011
|
+
where
|
|
2012
|
+
});
|
|
2013
|
+
await this._update(table, {
|
|
2014
|
+
deleted: true
|
|
2015
|
+
}, options2);
|
|
2016
|
+
return;
|
|
2017
|
+
}
|
|
2018
|
+
// builder
|
|
2019
|
+
const builder = this.builder(table);
|
|
2020
|
+
// delete
|
|
2021
|
+
builder.delete();
|
|
2022
|
+
// where
|
|
2023
|
+
this.prepareWhere(builder, table, where, options);
|
|
2024
|
+
// debug
|
|
2025
|
+
this.$loggerChild('model').debug('model.delete: %s', builder.toQuery());
|
|
2026
|
+
// ready
|
|
2027
|
+
await builder;
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
class BeanModelCrudTable extends BeanModelCrudInner {
|
|
2032
|
+
async mget(table, ids, options) {
|
|
2033
|
+
return await this._mget(table, ids, options);
|
|
2034
|
+
}
|
|
2035
|
+
async select(table, params, options) {
|
|
2036
|
+
return await this._select(table, params, options);
|
|
2037
|
+
}
|
|
2038
|
+
async get(table, where, options) {
|
|
2039
|
+
return await this._get(table, where, options);
|
|
2040
|
+
}
|
|
2041
|
+
async count(table, params, options) {
|
|
2042
|
+
return await this._count(table, params, options);
|
|
2043
|
+
}
|
|
2044
|
+
async insert(table, data, options) {
|
|
2045
|
+
return await this._insertBulk(table, data, options);
|
|
2046
|
+
}
|
|
2047
|
+
async insertBulk(table, data, options) {
|
|
2048
|
+
return await this._insertBulk(table, data, options);
|
|
2049
|
+
}
|
|
2050
|
+
async update(table, data, options) {
|
|
2051
|
+
return await this._update(table, data, options);
|
|
2052
|
+
}
|
|
2053
|
+
async delete(table, where, options) {
|
|
2054
|
+
return await this._delete(table, where, options);
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
var _dec$d, _dec2$d, _dec3$3, _class$d;
|
|
2059
|
+
let BeanModel = (_dec$d = Bean(), _dec2$d = Virtual(), _dec3$3 = BeanInfo({
|
|
2060
|
+
module: "a-orm"
|
|
2061
|
+
}), _dec$d(_class$d = _dec2$d(_class$d = _dec3$3(_class$d = class BeanModel extends BeanModelCrudTable {}) || _class$d) || _class$d) || _class$d);
|
|
2062
|
+
|
|
2063
|
+
const SymbolCacheOptions = Symbol('SymbolCacheOptions');
|
|
2064
|
+
const SymbolCacheEnabled = Symbol('SymbolCacheEnabled');
|
|
2065
|
+
class ModelCacheBase extends BeanBase {
|
|
2066
|
+
constructor(...args) {
|
|
2067
|
+
super(...args);
|
|
2068
|
+
this[SymbolCacheOptions] = void 0;
|
|
2069
|
+
this._model = void 0;
|
|
2070
|
+
this._cacheType = void 0;
|
|
2071
|
+
}
|
|
2072
|
+
__init__(model, cacheType) {
|
|
2073
|
+
this._model = model;
|
|
2074
|
+
this._cacheType = cacheType;
|
|
2075
|
+
}
|
|
2076
|
+
get scopeOrm() {
|
|
2077
|
+
return this.$scope.orm;
|
|
2078
|
+
}
|
|
2079
|
+
getInstance(table) {
|
|
2080
|
+
if (this.options === false) throw new Error('cache disabled');
|
|
2081
|
+
return this.app.bean.summer.cache(this.getName(table), this.options);
|
|
2082
|
+
}
|
|
2083
|
+
getName(table) {
|
|
2084
|
+
const clientNameReal = this.$scope.orm.service.database.prepareClientNameReal(this._model.db.clientName);
|
|
2085
|
+
return `${this.$beanFullName}:${clientNameReal}:${table}:${this._cacheType}`;
|
|
2086
|
+
}
|
|
2087
|
+
get options() {
|
|
2088
|
+
if (this[SymbolCacheOptions] === undefined) {
|
|
2089
|
+
this[SymbolCacheOptions] = this._getCacheOptionsInner();
|
|
2090
|
+
}
|
|
2091
|
+
return this[SymbolCacheOptions];
|
|
2092
|
+
}
|
|
2093
|
+
get enabled() {
|
|
2094
|
+
if (this[SymbolCacheEnabled] === undefined) {
|
|
2095
|
+
this[SymbolCacheEnabled] = this._getCacheEnabledInner();
|
|
2096
|
+
}
|
|
2097
|
+
return this[SymbolCacheEnabled];
|
|
2098
|
+
}
|
|
2099
|
+
_getCacheEnabledInner() {
|
|
2100
|
+
if (this.options === false) return false;
|
|
2101
|
+
// enable
|
|
2102
|
+
if (!this.bean.onion.checkOnionOptionsEnabled(this.options)) return false;
|
|
2103
|
+
// default
|
|
2104
|
+
return true;
|
|
2105
|
+
}
|
|
2106
|
+
_getCacheOptionsInner() {
|
|
2107
|
+
if (this._model.options.cache?.[this._cacheType] === false) return false;
|
|
2108
|
+
// options
|
|
2109
|
+
let _cacheOptions = this._model.options.cache?.[this._cacheType] ?? {};
|
|
2110
|
+
// preset
|
|
2111
|
+
let configPreset;
|
|
2112
|
+
let preset = _cacheOptions.preset;
|
|
2113
|
+
if (!preset && !_cacheOptions.mode) preset = this.scopeOrm.config.summer.presetDefault;
|
|
2114
|
+
if (preset) {
|
|
2115
|
+
configPreset = this.scopeOrm.config.summer.preset[preset];
|
|
2116
|
+
}
|
|
2117
|
+
// extend
|
|
2118
|
+
_cacheOptions = deepExtend({
|
|
2119
|
+
enable: this.scopeOrm.config.summer.enable,
|
|
2120
|
+
meta: this.scopeOrm.config.summer.meta,
|
|
2121
|
+
redis: {
|
|
2122
|
+
client: this.scopeOrm.config.summer.redis.client
|
|
2123
|
+
}
|
|
2124
|
+
}, configPreset, _cacheOptions, {
|
|
2125
|
+
preset: undefined
|
|
2126
|
+
});
|
|
2127
|
+
// ok
|
|
2128
|
+
return _cacheOptions;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
var _dec$c, _dec2$c, _class$c;
|
|
2133
|
+
let ServiceCacheEntity = (_dec$c = Service(), _dec2$c = BeanInfo({
|
|
2134
|
+
module: "a-orm"
|
|
2135
|
+
}), _dec$c(_class$c = _dec2$c(_class$c = class ServiceCacheEntity extends ModelCacheBase {
|
|
2136
|
+
__init__(model) {
|
|
2137
|
+
super.__init__(model, 'entity');
|
|
2138
|
+
}
|
|
2139
|
+
async clear(table) {
|
|
2140
|
+
if (!this.enabled) return;
|
|
2141
|
+
table = table || this._model.getTable();
|
|
2142
|
+
const cache = this.getInstance(table);
|
|
2143
|
+
await cache.clear();
|
|
2144
|
+
}
|
|
2145
|
+
async del(id, table) {
|
|
2146
|
+
if (!this.enabled) return;
|
|
2147
|
+
table = table || this._model.getTable();
|
|
2148
|
+
const cache = this.getInstance(table);
|
|
2149
|
+
if (Array.isArray(id)) {
|
|
2150
|
+
await cache.mdel(id);
|
|
2151
|
+
} else {
|
|
2152
|
+
await cache.del(id);
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
get keysAux() {
|
|
2156
|
+
return this._model.options.cache?.keysAux;
|
|
2157
|
+
}
|
|
2158
|
+
}) || _class$c) || _class$c);
|
|
2159
|
+
|
|
2160
|
+
var _dec$b, _dec2$b, _class$b;
|
|
2161
|
+
let ServiceCacheQuery = (_dec$b = Service(), _dec2$b = BeanInfo({
|
|
2162
|
+
module: "a-orm"
|
|
2163
|
+
}), _dec$b(_class$b = _dec2$b(_class$b = class ServiceCacheQuery extends ModelCacheBase {
|
|
2164
|
+
__init__(model) {
|
|
2165
|
+
super.__init__(model, 'query');
|
|
2166
|
+
}
|
|
2167
|
+
async clear(table) {
|
|
2168
|
+
if (!this.enabled) return;
|
|
2169
|
+
table = table || this._model.getTable();
|
|
2170
|
+
const cache = this.getInstance(table);
|
|
2171
|
+
await cache.clear();
|
|
2172
|
+
}
|
|
2173
|
+
}) || _class$b) || _class$b);
|
|
2174
|
+
|
|
2175
|
+
var _dec$a, _dec2$a, _class$a;
|
|
2176
|
+
let ServiceRelations = (_dec$a = Service(), _dec2$a = BeanInfo({
|
|
2177
|
+
module: "a-orm"
|
|
2178
|
+
}), _dec$a(_class$a = _dec2$a(_class$a = class ServiceRelations extends BeanBase {
|
|
2179
|
+
constructor(...args) {
|
|
2180
|
+
super(...args);
|
|
2181
|
+
this._model = void 0;
|
|
2182
|
+
}
|
|
2183
|
+
__init__(model) {
|
|
2184
|
+
this._model = model;
|
|
2185
|
+
}
|
|
2186
|
+
async handleRelationsOne(entity, includeWrapper, methodOptions) {
|
|
2187
|
+
if (!entity) return entity;
|
|
2188
|
+
// relations
|
|
2189
|
+
const relations = this.__handleRelationsCollection(includeWrapper);
|
|
2190
|
+
if (!relations) return entity;
|
|
2191
|
+
for (const relation of relations) {
|
|
2192
|
+
await this.__handleRelationOne(entity, relation, methodOptions);
|
|
2193
|
+
}
|
|
2194
|
+
return entity;
|
|
2195
|
+
}
|
|
2196
|
+
async handleRelationsMany(entities, includeWrapper, methodOptions) {
|
|
2197
|
+
if (entities.length === 0) return entities;
|
|
2198
|
+
// relations
|
|
2199
|
+
const relations = this.__handleRelationsCollection(includeWrapper);
|
|
2200
|
+
if (!relations) return entities;
|
|
2201
|
+
for (const relation of relations) {
|
|
2202
|
+
await this.__handleRelationMany(entities, relation, methodOptions);
|
|
2203
|
+
}
|
|
2204
|
+
return entities;
|
|
2205
|
+
}
|
|
2206
|
+
async handleRelationsMutate(entitiesResult, entities, includeWrapper, methodOptions) {
|
|
2207
|
+
if (entitiesResult.length === 0) return entitiesResult;
|
|
2208
|
+
// relations
|
|
2209
|
+
const relations = this.__handleRelationsCollection(includeWrapper);
|
|
2210
|
+
if (!relations) return entitiesResult;
|
|
2211
|
+
for (const relation of relations) {
|
|
2212
|
+
entitiesResult = await this.__handleRelationMutate(entitiesResult, entities, relation, methodOptions);
|
|
2213
|
+
}
|
|
2214
|
+
return entitiesResult;
|
|
2215
|
+
}
|
|
2216
|
+
async handleRelationsDelete(ids, includeWrapper, methodOptions) {
|
|
2217
|
+
if (ids.length === 0) return;
|
|
2218
|
+
// relations
|
|
2219
|
+
const relations = this.__handleRelationsCollection(includeWrapper);
|
|
2220
|
+
if (!relations) return;
|
|
2221
|
+
for (const relation of relations) {
|
|
2222
|
+
await this.__handleRelationDelete(ids, relation, methodOptions);
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
async __handleRelationOne(entity, relation, methodOptions) {
|
|
2226
|
+
const [relationName, relationReal, includeReal, withReal] = relation;
|
|
2227
|
+
const {
|
|
2228
|
+
type,
|
|
2229
|
+
modelMiddle,
|
|
2230
|
+
model,
|
|
2231
|
+
keyFrom,
|
|
2232
|
+
keyTo,
|
|
2233
|
+
key,
|
|
2234
|
+
options
|
|
2235
|
+
} = relationReal;
|
|
2236
|
+
const modelTarget = this.__getModelTarget(model, options?.meta);
|
|
2237
|
+
const tableNameTarget = modelTarget.getTable();
|
|
2238
|
+
const optionsReal = Object.assign({}, options, {
|
|
2239
|
+
include: includeReal,
|
|
2240
|
+
with: withReal
|
|
2241
|
+
});
|
|
2242
|
+
const methodOptionsReal = Object.assign({}, methodOptions, {
|
|
2243
|
+
columns: undefined
|
|
2244
|
+
});
|
|
2245
|
+
if (type === 'hasOne') {
|
|
2246
|
+
const idFrom = cast(entity).id;
|
|
2247
|
+
if (isNil(idFrom)) {
|
|
2248
|
+
entity[relationName] = undefined;
|
|
2249
|
+
} else {
|
|
2250
|
+
const where = {
|
|
2251
|
+
[key]: idFrom
|
|
2252
|
+
};
|
|
2253
|
+
const options2 = deepExtend({}, methodOptionsReal, optionsReal);
|
|
2254
|
+
entity[relationName] = await modelTarget.get(where, options2);
|
|
2255
|
+
}
|
|
2256
|
+
} else if (type === 'belongsTo') {
|
|
2257
|
+
const idTo = cast(entity)[key];
|
|
2258
|
+
if (isNil(idTo)) {
|
|
2259
|
+
entity[relationName] = undefined;
|
|
2260
|
+
} else {
|
|
2261
|
+
const where = {
|
|
2262
|
+
id: idTo
|
|
2263
|
+
};
|
|
2264
|
+
const options2 = deepExtend({}, methodOptionsReal, optionsReal);
|
|
2265
|
+
entity[relationName] = await modelTarget.get(where, options2);
|
|
2266
|
+
}
|
|
2267
|
+
} else if (type === 'hasMany') {
|
|
2268
|
+
const idFrom = cast(entity).id;
|
|
2269
|
+
if (isNil(idFrom)) {
|
|
2270
|
+
entity[relationName] = optionsReal.groups ? [] : optionsReal.aggrs ? undefined : [];
|
|
2271
|
+
} else {
|
|
2272
|
+
if (optionsReal.groups) {
|
|
2273
|
+
const options2 = deepExtend({}, optionsReal, {
|
|
2274
|
+
where: {
|
|
2275
|
+
[`${tableNameTarget}.${key}`]: idFrom
|
|
2276
|
+
}
|
|
2277
|
+
});
|
|
2278
|
+
entity[relationName] = await modelTarget.group(options2, methodOptionsReal);
|
|
2279
|
+
} else if (optionsReal.aggrs) {
|
|
2280
|
+
const options2 = deepExtend({}, optionsReal, {
|
|
2281
|
+
where: {
|
|
2282
|
+
[`${tableNameTarget}.${key}`]: idFrom
|
|
2283
|
+
}
|
|
2284
|
+
});
|
|
2285
|
+
entity[relationName] = await modelTarget.aggregate(options2, methodOptionsReal);
|
|
2286
|
+
} else {
|
|
2287
|
+
const options2 = deepExtend({}, optionsReal, {
|
|
2288
|
+
where: {
|
|
2289
|
+
[`${tableNameTarget}.${key}`]: idFrom
|
|
2290
|
+
}
|
|
2291
|
+
});
|
|
2292
|
+
entity[relationName] = await modelTarget.select(options2, methodOptionsReal);
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
} else if (type === 'belongsToMany') {
|
|
2296
|
+
const modelTargetMiddle = this.__getModelTarget(modelMiddle, options?.meta?.middle);
|
|
2297
|
+
const idFrom = cast(entity).id;
|
|
2298
|
+
if (isNil(idFrom)) {
|
|
2299
|
+
entity[relationName] = optionsReal.groups ? [] : optionsReal.aggrs ? undefined : [];
|
|
2300
|
+
} else {
|
|
2301
|
+
const itemsMiddle = await modelTargetMiddle.select({
|
|
2302
|
+
where: {
|
|
2303
|
+
[keyFrom]: idFrom
|
|
2304
|
+
}
|
|
2305
|
+
}, methodOptionsReal);
|
|
2306
|
+
const idsTo = itemsMiddle.map(item => item[keyTo]);
|
|
2307
|
+
if (optionsReal.groups) {
|
|
2308
|
+
const options2 = deepExtend({}, optionsReal, {
|
|
2309
|
+
where: {
|
|
2310
|
+
[`${tableNameTarget}.id`]: idsTo
|
|
2311
|
+
}
|
|
2312
|
+
});
|
|
2313
|
+
entity[relationName] = await modelTarget.group(options2, methodOptionsReal);
|
|
2314
|
+
} else if (optionsReal.aggrs) {
|
|
2315
|
+
const options2 = deepExtend({}, optionsReal, {
|
|
2316
|
+
where: {
|
|
2317
|
+
[`${tableNameTarget}.id`]: idsTo
|
|
2318
|
+
}
|
|
2319
|
+
});
|
|
2320
|
+
entity[relationName] = await modelTarget.aggregate(options2, methodOptionsReal);
|
|
2321
|
+
} else {
|
|
2322
|
+
const options2 = deepExtend({}, methodOptionsReal, optionsReal);
|
|
2323
|
+
entity[relationName] = await modelTarget.mget(idsTo, options2);
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
async __handleRelationMany(entities, relation, methodOptions) {
|
|
2329
|
+
const [relationName, relationReal, includeReal, withReal] = relation;
|
|
2330
|
+
const {
|
|
2331
|
+
type,
|
|
2332
|
+
modelMiddle,
|
|
2333
|
+
model,
|
|
2334
|
+
keyFrom,
|
|
2335
|
+
keyTo,
|
|
2336
|
+
key,
|
|
2337
|
+
options
|
|
2338
|
+
} = relationReal;
|
|
2339
|
+
const modelTarget = this.__getModelTarget(model, options?.meta);
|
|
2340
|
+
const tableNameTarget = modelTarget.getTable();
|
|
2341
|
+
const optionsReal = Object.assign({}, options, {
|
|
2342
|
+
include: includeReal,
|
|
2343
|
+
with: withReal
|
|
2344
|
+
});
|
|
2345
|
+
const methodOptionsReal = Object.assign({}, methodOptions, {
|
|
2346
|
+
columns: undefined
|
|
2347
|
+
});
|
|
2348
|
+
if (type === 'hasOne') {
|
|
2349
|
+
const idsFrom = entities.map(item => cast(item).id).filter(id => !isNil(id));
|
|
2350
|
+
const [columns, withKey] = this.__prepareColumnsAndKey(optionsReal.columns, key);
|
|
2351
|
+
const options2 = deepExtend({}, optionsReal, {
|
|
2352
|
+
columns,
|
|
2353
|
+
where: {
|
|
2354
|
+
[key]: idsFrom
|
|
2355
|
+
}
|
|
2356
|
+
});
|
|
2357
|
+
const items = await modelTarget.select(options2, methodOptionsReal);
|
|
2358
|
+
for (const entity of entities) {
|
|
2359
|
+
entity[relationName] = items.find(item => {
|
|
2360
|
+
if (item[key] === cast(entity).id) {
|
|
2361
|
+
if (!withKey) delete item[key];
|
|
2362
|
+
return true;
|
|
2363
|
+
}
|
|
2364
|
+
return false;
|
|
2365
|
+
});
|
|
2366
|
+
}
|
|
2367
|
+
} else if (type === 'belongsTo') {
|
|
2368
|
+
const idsTo = entities.map(item => cast(item)[key]).filter(id => !isNil(id));
|
|
2369
|
+
const options2 = deepExtend({}, methodOptionsReal, optionsReal);
|
|
2370
|
+
const items = await modelTarget.mget(idsTo, options2);
|
|
2371
|
+
for (const entity of entities) {
|
|
2372
|
+
entity[relationName] = items.find(item => cast(item).id === cast(entity)[key]);
|
|
2373
|
+
}
|
|
2374
|
+
} else if (type === 'hasMany') {
|
|
2375
|
+
const idsFrom = entities.map(item => cast(item).id).filter(id => !isNil(id));
|
|
2376
|
+
if (optionsReal.groups) {
|
|
2377
|
+
const groups = [`${tableNameTarget}.${key}`].concat(optionsReal.groups);
|
|
2378
|
+
const options2 = deepExtend({}, optionsReal, {
|
|
2379
|
+
groups,
|
|
2380
|
+
where: {
|
|
2381
|
+
[`${tableNameTarget}.${key}`]: idsFrom
|
|
2382
|
+
}
|
|
2383
|
+
});
|
|
2384
|
+
const items = await modelTarget.group(options2, methodOptionsReal);
|
|
2385
|
+
for (const entity of entities) {
|
|
2386
|
+
entity[relationName] = [];
|
|
2387
|
+
for (const item of items) {
|
|
2388
|
+
if (item[key] === cast(entity).id) {
|
|
2389
|
+
delete item[key];
|
|
2390
|
+
entity[relationName].push(item);
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
} else if (optionsReal.aggrs) {
|
|
2395
|
+
const options2 = deepExtend({}, optionsReal, {
|
|
2396
|
+
groups: `${tableNameTarget}.${key}`,
|
|
2397
|
+
where: {
|
|
2398
|
+
[`${tableNameTarget}.${key}`]: idsFrom
|
|
2399
|
+
}
|
|
2400
|
+
});
|
|
2401
|
+
const items = await modelTarget.group(options2, methodOptionsReal);
|
|
2402
|
+
for (const entity of entities) {
|
|
2403
|
+
entity[relationName] = items.find(item => item[key] === cast(entity).id);
|
|
2404
|
+
}
|
|
2405
|
+
} else {
|
|
2406
|
+
const [columns, withKey] = this.__prepareColumnsAndKey(optionsReal.columns, key);
|
|
2407
|
+
const options2 = deepExtend({}, optionsReal, {
|
|
2408
|
+
columns,
|
|
2409
|
+
where: {
|
|
2410
|
+
[`${tableNameTarget}.${key}`]: idsFrom
|
|
2411
|
+
}
|
|
2412
|
+
});
|
|
2413
|
+
const items = await modelTarget.select(options2, methodOptionsReal);
|
|
2414
|
+
for (const entity of entities) {
|
|
2415
|
+
entity[relationName] = [];
|
|
2416
|
+
for (const item of items) {
|
|
2417
|
+
if (item[key] === cast(entity).id) {
|
|
2418
|
+
if (!withKey) delete item[key];
|
|
2419
|
+
entity[relationName].push(item);
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
} else if (type === 'belongsToMany') {
|
|
2425
|
+
const modelTargetMiddle = this.__getModelTarget(modelMiddle, options?.meta?.middle);
|
|
2426
|
+
const idsFrom = entities.map(item => cast(item).id).filter(id => !isNil(id));
|
|
2427
|
+
const itemsMiddle = await modelTargetMiddle.select({
|
|
2428
|
+
where: {
|
|
2429
|
+
[keyFrom]: idsFrom
|
|
2430
|
+
}
|
|
2431
|
+
}, methodOptionsReal);
|
|
2432
|
+
if (optionsReal.groups) {
|
|
2433
|
+
for (const entity of entities) {
|
|
2434
|
+
const idsTo = itemsMiddle.filter(item => item[keyFrom] === cast(entity).id).map(item => item[keyTo]);
|
|
2435
|
+
const options2 = deepExtend({}, optionsReal, {
|
|
2436
|
+
groups: optionsReal.groups,
|
|
2437
|
+
where: {
|
|
2438
|
+
[`${tableNameTarget}.id`]: idsTo
|
|
2439
|
+
}
|
|
2440
|
+
});
|
|
2441
|
+
entity[relationName] = await modelTarget.group(options2, methodOptionsReal);
|
|
2442
|
+
}
|
|
2443
|
+
} else if (optionsReal.aggrs) {
|
|
2444
|
+
for (const entity of entities) {
|
|
2445
|
+
const idsTo = itemsMiddle.filter(item => item[keyFrom] === cast(entity).id).map(item => item[keyTo]);
|
|
2446
|
+
const options2 = deepExtend({}, optionsReal, {
|
|
2447
|
+
where: {
|
|
2448
|
+
[`${tableNameTarget}.id`]: idsTo
|
|
2449
|
+
}
|
|
2450
|
+
});
|
|
2451
|
+
entity[relationName] = await modelTarget.aggregate(options2, methodOptionsReal);
|
|
2452
|
+
}
|
|
2453
|
+
} else {
|
|
2454
|
+
const idsTo = itemsMiddle.map(item => item[keyTo]);
|
|
2455
|
+
const options2 = deepExtend({}, methodOptionsReal, optionsReal);
|
|
2456
|
+
const items = await modelTarget.mget(idsTo, options2);
|
|
2457
|
+
for (const entity of entities) {
|
|
2458
|
+
entity[relationName] = [];
|
|
2459
|
+
for (const itemMiddle of itemsMiddle) {
|
|
2460
|
+
if (itemMiddle[keyFrom] === cast(entity).id) {
|
|
2461
|
+
entity[relationName].push(items.find(item => cast(item).id === cast(itemMiddle)[keyTo]));
|
|
2462
|
+
}
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
async __handleRelationMutate(entitiesResult, entities, relation, methodOptions) {
|
|
2469
|
+
const [relationName, relationReal, includeReal, withReal] = relation;
|
|
2470
|
+
const {
|
|
2471
|
+
type,
|
|
2472
|
+
modelMiddle,
|
|
2473
|
+
model,
|
|
2474
|
+
keyFrom,
|
|
2475
|
+
keyTo,
|
|
2476
|
+
key,
|
|
2477
|
+
options
|
|
2478
|
+
} = relationReal;
|
|
2479
|
+
const modelTarget = this.__getModelTarget(model, options?.meta);
|
|
2480
|
+
const methodOptionsReal = Object.assign({}, methodOptions, {
|
|
2481
|
+
include: includeReal,
|
|
2482
|
+
with: withReal
|
|
2483
|
+
});
|
|
2484
|
+
if (type === 'hasOne') {
|
|
2485
|
+
let children = [];
|
|
2486
|
+
for (let index = 0; index < entities.length; index++) {
|
|
2487
|
+
const entity = entities[index];
|
|
2488
|
+
if (entity[relationName]) {
|
|
2489
|
+
// donot checkif has id of entity[relationName], for safety
|
|
2490
|
+
const item = await modelTarget.get({
|
|
2491
|
+
[key]: cast(entity).id
|
|
2492
|
+
});
|
|
2493
|
+
if (!isNil(item?.id) && !isNil(entity[relationName].id) && item?.id !== entity[relationName].id) {
|
|
2494
|
+
throw new Error(`invalid id: ${entity[relationName].id}`);
|
|
2495
|
+
}
|
|
2496
|
+
children.push(Object.assign({}, entity[relationName], {
|
|
2497
|
+
[key]: cast(entity).id,
|
|
2498
|
+
id: item?.id
|
|
2499
|
+
}));
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
children = await modelTarget.mutateBulk(children, methodOptionsReal);
|
|
2503
|
+
const result = entitiesResult.concat();
|
|
2504
|
+
for (let index = 0; index < entities.length; index++) {
|
|
2505
|
+
const entityResult = result[index];
|
|
2506
|
+
const entity = entities[index];
|
|
2507
|
+
if (entity[relationName]) {
|
|
2508
|
+
entityResult[relationName] = children.find(item => item[key] === cast(entity).id);
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
return result;
|
|
2512
|
+
} else if (type === 'belongsTo') {
|
|
2513
|
+
// do nothing
|
|
2514
|
+
return entitiesResult;
|
|
2515
|
+
} else if (type === 'hasMany') {
|
|
2516
|
+
let children = [];
|
|
2517
|
+
for (let index = 0; index < entities.length; index++) {
|
|
2518
|
+
const entity = entities[index];
|
|
2519
|
+
if (entity[relationName] && entity[relationName].length > 0) {
|
|
2520
|
+
const entityId = cast(entity).id;
|
|
2521
|
+
const idsTo = entity[relationName].map(item => item.id).filter(id => !isNil(id));
|
|
2522
|
+
const itemsTarget = await cast(modelTarget).__select_raw(undefined, {
|
|
2523
|
+
where: {
|
|
2524
|
+
[key]: entityId,
|
|
2525
|
+
id: idsTo
|
|
2526
|
+
}
|
|
2527
|
+
}, methodOptionsReal);
|
|
2528
|
+
const idsTarget = itemsTarget.map(item => item.id);
|
|
2529
|
+
for (const child of entity[relationName]) {
|
|
2530
|
+
if (!isNil(child.id) && !idsTarget.includes(child.id)) {
|
|
2531
|
+
throw new Error(`invalid id: ${child.id}`);
|
|
2532
|
+
}
|
|
2533
|
+
children.push(Object.assign({}, child, {
|
|
2534
|
+
[key]: entityId
|
|
2535
|
+
}));
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
children = await modelTarget.mutateBulk(children, methodOptionsReal);
|
|
2540
|
+
const result = entitiesResult.concat();
|
|
2541
|
+
for (let index = 0; index < entities.length; index++) {
|
|
2542
|
+
const entityResult = result[index];
|
|
2543
|
+
const entity = entities[index];
|
|
2544
|
+
if (entity[relationName]) {
|
|
2545
|
+
entityResult[relationName] = [];
|
|
2546
|
+
for (const child of children) {
|
|
2547
|
+
if (child[key] === cast(entity).id) {
|
|
2548
|
+
entityResult[relationName].push(child);
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
return result;
|
|
2554
|
+
} else if (type === 'belongsToMany') {
|
|
2555
|
+
const modelTargetMiddle = this.__getModelTarget(modelMiddle, options?.meta?.middle);
|
|
2556
|
+
let children = [];
|
|
2557
|
+
for (let index = 0; index < entities.length; index++) {
|
|
2558
|
+
const entity = entities[index];
|
|
2559
|
+
if (entity[relationName] && entity[relationName].length > 0) {
|
|
2560
|
+
const idsTo = entity[relationName].map(item => item.id);
|
|
2561
|
+
const itemsMiddle = await cast(modelTargetMiddle).__select_raw(undefined, {
|
|
2562
|
+
where: {
|
|
2563
|
+
[keyFrom]: cast(entity).id,
|
|
2564
|
+
[keyTo]: idsTo
|
|
2565
|
+
}
|
|
2566
|
+
}, methodOptionsReal);
|
|
2567
|
+
for (const child of entity[relationName]) {
|
|
2568
|
+
const itemMiddle = itemsMiddle.find(item => item[keyTo] === child.id);
|
|
2569
|
+
if (!itemMiddle) {
|
|
2570
|
+
if (!child.deleted) {
|
|
2571
|
+
// add
|
|
2572
|
+
children.push({
|
|
2573
|
+
[keyFrom]: cast(entity).id,
|
|
2574
|
+
[keyTo]: child.id
|
|
2575
|
+
});
|
|
2576
|
+
}
|
|
2577
|
+
} else {
|
|
2578
|
+
if (child.deleted) {
|
|
2579
|
+
// delete
|
|
2580
|
+
children.push({
|
|
2581
|
+
id: itemMiddle.id,
|
|
2582
|
+
deleted: child.deleted
|
|
2583
|
+
});
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
children = await modelTargetMiddle.mutateBulk(children, methodOptionsReal);
|
|
2590
|
+
const result = entitiesResult.concat();
|
|
2591
|
+
for (let index = 0; index < entities.length; index++) {
|
|
2592
|
+
const entityResult = result[index];
|
|
2593
|
+
const entity = entities[index];
|
|
2594
|
+
if (entity[relationName]) {
|
|
2595
|
+
entityResult[relationName] = [];
|
|
2596
|
+
for (const child of children) {
|
|
2597
|
+
if (child[keyFrom] === cast(entity).id) {
|
|
2598
|
+
entityResult[relationName].push({
|
|
2599
|
+
id: child[keyTo]
|
|
2600
|
+
});
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
return result;
|
|
2606
|
+
}
|
|
2607
|
+
// do nothing
|
|
2608
|
+
return entitiesResult;
|
|
2609
|
+
}
|
|
2610
|
+
async __handleRelationDelete(ids, relation, methodOptions) {
|
|
2611
|
+
const [_relationName, relationReal, includeReal, withReal] = relation;
|
|
2612
|
+
const {
|
|
2613
|
+
type,
|
|
2614
|
+
modelMiddle,
|
|
2615
|
+
model,
|
|
2616
|
+
keyFrom,
|
|
2617
|
+
key,
|
|
2618
|
+
options
|
|
2619
|
+
} = relationReal;
|
|
2620
|
+
const modelTarget = this.__getModelTarget(model, options?.meta);
|
|
2621
|
+
const methodOptionsReal = Object.assign({}, methodOptions, {
|
|
2622
|
+
include: includeReal,
|
|
2623
|
+
with: withReal
|
|
2624
|
+
});
|
|
2625
|
+
if (type === 'hasOne' || type === 'hasMany') {
|
|
2626
|
+
const children = await cast(modelTarget).__select_raw(undefined, {
|
|
2627
|
+
columns: 'id',
|
|
2628
|
+
where: {
|
|
2629
|
+
[key]: ids
|
|
2630
|
+
}
|
|
2631
|
+
}, methodOptionsReal);
|
|
2632
|
+
const idsTo = children.map(item => item.id);
|
|
2633
|
+
await modelTarget.deleteBulk(idsTo, methodOptionsReal);
|
|
2634
|
+
} else if (type === 'belongsTo') ; else if (type === 'belongsToMany') {
|
|
2635
|
+
const modelTargetMiddle = this.__getModelTarget(modelMiddle, options?.meta?.middle);
|
|
2636
|
+
const itemsMiddle = await cast(modelTargetMiddle).__select_raw(undefined, {
|
|
2637
|
+
columns: 'id',
|
|
2638
|
+
where: {
|
|
2639
|
+
[keyFrom]: ids
|
|
2640
|
+
}
|
|
2641
|
+
}, methodOptionsReal);
|
|
2642
|
+
const idsMiddle = itemsMiddle.map(item => item.id);
|
|
2643
|
+
await modelTargetMiddle.deleteBulk(idsMiddle, methodOptionsReal);
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
__prepareColumnsAndKey(columns, key) {
|
|
2647
|
+
if (!columns) return [columns, true];
|
|
2648
|
+
columns = Array.isArray(columns) ? columns : [columns];
|
|
2649
|
+
if (columns.includes('*') || columns.includes(key)) return [columns, true];
|
|
2650
|
+
columns.push(key);
|
|
2651
|
+
return [columns, false];
|
|
2652
|
+
}
|
|
2653
|
+
__getModelTarget(modelClassTarget, meta) {
|
|
2654
|
+
return this._model.newInstanceTarget(modelClassTarget, meta?.client, meta?.table);
|
|
2655
|
+
}
|
|
2656
|
+
__handleRelationsCollection(includeWrapper) {
|
|
2657
|
+
// collect
|
|
2658
|
+
const relations = [];
|
|
2659
|
+
// include
|
|
2660
|
+
if (this._model.options.relations) {
|
|
2661
|
+
for (const key in this._model.options.relations) {
|
|
2662
|
+
const relationDef = this._model.options.relations[key];
|
|
2663
|
+
const relationCur = includeWrapper?.include?.[key];
|
|
2664
|
+
let relationReal;
|
|
2665
|
+
let includeReal;
|
|
2666
|
+
let withReal;
|
|
2667
|
+
if (relationCur === false) {
|
|
2668
|
+
continue;
|
|
2669
|
+
} else if (relationCur === true) {
|
|
2670
|
+
relationReal = relationDef;
|
|
2671
|
+
} else if (typeof relationCur === 'object') {
|
|
2672
|
+
relationReal = deepExtend({}, relationDef, {
|
|
2673
|
+
options: relationCur
|
|
2674
|
+
});
|
|
2675
|
+
includeReal = relationCur.include;
|
|
2676
|
+
withReal = relationCur.with;
|
|
2677
|
+
} else if (relationDef.options?.autoload) {
|
|
2678
|
+
relationReal = relationDef;
|
|
2679
|
+
} else {
|
|
2680
|
+
continue;
|
|
2681
|
+
}
|
|
2682
|
+
relations.push([key, relationReal, includeReal, withReal]);
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
// with
|
|
2686
|
+
if (includeWrapper?.with) {
|
|
2687
|
+
for (const key in includeWrapper.with) {
|
|
2688
|
+
const relationReal = includeWrapper.with[key];
|
|
2689
|
+
if (!relationReal) continue;
|
|
2690
|
+
relations.push([key, relationReal, relationReal.options?.include, relationReal.options?.with]);
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
return relations;
|
|
2694
|
+
}
|
|
2695
|
+
}) || _class$a) || _class$a);
|
|
2696
|
+
|
|
2697
|
+
class BeanModelCrud extends BeanModelCrudInner {
|
|
2698
|
+
async mget(ids, options) {
|
|
2699
|
+
return await this._mget(undefined, ids, options);
|
|
2700
|
+
}
|
|
2701
|
+
async select(params, options) {
|
|
2702
|
+
return await this._select(undefined, params, options);
|
|
2703
|
+
}
|
|
2704
|
+
async get(where, options) {
|
|
2705
|
+
return await this._get(undefined, where, options);
|
|
2706
|
+
}
|
|
2707
|
+
async count(params, options) {
|
|
2708
|
+
return await this._count(undefined, params, options);
|
|
2709
|
+
}
|
|
2710
|
+
async insert(data, options) {
|
|
2711
|
+
return await this._insertBulk(undefined, data, options);
|
|
2712
|
+
}
|
|
2713
|
+
async insertBulk(data, options) {
|
|
2714
|
+
return await this._insertBulk(undefined, data, options);
|
|
2715
|
+
}
|
|
2716
|
+
async update(data, options) {
|
|
2717
|
+
return await this._update(undefined, data, options);
|
|
2718
|
+
}
|
|
2719
|
+
async delete(where, options) {
|
|
2720
|
+
return await this._delete(undefined, where, options);
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
const SymbolModelsClearAll = Symbol('SymbolModelsClearAll');
|
|
2725
|
+
class BeanModelCache extends BeanModelCrud {
|
|
2726
|
+
constructor(...args) {
|
|
2727
|
+
super(...args);
|
|
2728
|
+
this.cacheQuery = void 0;
|
|
2729
|
+
this.cacheEntity = void 0;
|
|
2730
|
+
this.relations = void 0;
|
|
2731
|
+
this[SymbolModelsClearAll] = void 0;
|
|
2732
|
+
}
|
|
2733
|
+
__init__(clientName, table) {
|
|
2734
|
+
super.__init__(clientName, table);
|
|
2735
|
+
this.cacheQuery = this.bean._newBean(ServiceCacheQuery, this);
|
|
2736
|
+
this.cacheEntity = this.bean._newBean(ServiceCacheEntity, this);
|
|
2737
|
+
this.relations = this.bean._newBean(ServiceRelations, this);
|
|
2738
|
+
}
|
|
2739
|
+
async insert(data, options) {
|
|
2740
|
+
if (!data) data = {};
|
|
2741
|
+
const items = await this.insertBulk([data], options);
|
|
2742
|
+
return items[0];
|
|
2743
|
+
}
|
|
2744
|
+
async insertBulk(items, options) {
|
|
2745
|
+
const itemsResult = await this.__insertBulk_raw(undefined, items, options);
|
|
2746
|
+
const itemsNew = items.map((item, index) => {
|
|
2747
|
+
return Object.assign({}, item, {
|
|
2748
|
+
id: cast(itemsResult[index]).id
|
|
2749
|
+
});
|
|
2750
|
+
});
|
|
2751
|
+
return await this.relations.handleRelationsMutate(itemsResult, itemsNew, options, options);
|
|
2752
|
+
}
|
|
2753
|
+
async __insertBulk_raw(table, items, options) {
|
|
2754
|
+
if (items.length === 0) return [];
|
|
2755
|
+
// table
|
|
2756
|
+
table = table || this.getTable();
|
|
2757
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
2758
|
+
// insert
|
|
2759
|
+
const res = await this._insertBulk(table, items, options);
|
|
2760
|
+
// clear cache
|
|
2761
|
+
await this.cacheQueryClear(table);
|
|
2762
|
+
return res;
|
|
2763
|
+
}
|
|
2764
|
+
async mutate(data, options) {
|
|
2765
|
+
if (!data) data = {};
|
|
2766
|
+
const items = await this.mutateBulk([data], options);
|
|
2767
|
+
return items[0];
|
|
2768
|
+
}
|
|
2769
|
+
async mutateBulk(items, options) {
|
|
2770
|
+
return await this.__mutateBulk_raw(undefined, items, options);
|
|
2771
|
+
}
|
|
2772
|
+
async __mutateBulk_raw(table, items, options) {
|
|
2773
|
+
// table
|
|
2774
|
+
table = table || this.getTable();
|
|
2775
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
2776
|
+
// check
|
|
2777
|
+
const indexesInsert = [];
|
|
2778
|
+
const indexesUpdate = [];
|
|
2779
|
+
const itemsInsert = [];
|
|
2780
|
+
const itemsUpdate = [];
|
|
2781
|
+
const itemsDelete = [];
|
|
2782
|
+
for (let index = 0; index < items.length; index++) {
|
|
2783
|
+
const item = items[index];
|
|
2784
|
+
if (cast(item).deleted) {
|
|
2785
|
+
if (!isNil(cast(item).id)) {
|
|
2786
|
+
itemsDelete.push(item);
|
|
2787
|
+
}
|
|
2788
|
+
} else if (!isNil(cast(item).id)) {
|
|
2789
|
+
itemsUpdate.push(item);
|
|
2790
|
+
indexesUpdate.push(index);
|
|
2791
|
+
} else {
|
|
2792
|
+
itemsInsert.push(item);
|
|
2793
|
+
indexesInsert.push(index);
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
// insert/update
|
|
2797
|
+
const itemsInsertNew = await this.__insertBulk_raw(table, itemsInsert, options);
|
|
2798
|
+
await this.__updateBulk_raw(table, itemsUpdate, options);
|
|
2799
|
+
const itemsMutate = itemsInsert.map((item, index) => {
|
|
2800
|
+
return Object.assign({}, item, {
|
|
2801
|
+
id: cast(itemsInsertNew[index]).id
|
|
2802
|
+
});
|
|
2803
|
+
}).concat(itemsUpdate);
|
|
2804
|
+
let itemsMutateResult = itemsInsertNew.concat(itemsUpdate);
|
|
2805
|
+
const indexesMutate = indexesInsert.concat(indexesUpdate);
|
|
2806
|
+
itemsMutateResult = await this.relations.handleRelationsMutate(itemsMutateResult, itemsMutate, options, options);
|
|
2807
|
+
let result = [];
|
|
2808
|
+
for (let index = 0; index < indexesMutate.length; index++) {
|
|
2809
|
+
result[indexesMutate[index]] = itemsMutateResult[index];
|
|
2810
|
+
}
|
|
2811
|
+
result = result.filter(item => !!item); // fitler deleted items
|
|
2812
|
+
// delete
|
|
2813
|
+
const idsDelete = itemsDelete.map(item => cast(item).id);
|
|
2814
|
+
await this.__deleteBulk_raw_with_relations(table, idsDelete, options);
|
|
2815
|
+
// ok
|
|
2816
|
+
return result;
|
|
2817
|
+
}
|
|
2818
|
+
async mget(ids, options) {
|
|
2819
|
+
const items = await this.__mget_raw(undefined, ids, options);
|
|
2820
|
+
return await this.relations.handleRelationsMany(items, options, options);
|
|
2821
|
+
}
|
|
2822
|
+
async __mget_raw(table, ids, options) {
|
|
2823
|
+
// table
|
|
2824
|
+
table = table || this.getTable();
|
|
2825
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
2826
|
+
// check if cache
|
|
2827
|
+
if (this._checkDisableCacheEntityByOptions(options)) {
|
|
2828
|
+
return await super._mget(table, ids, options);
|
|
2829
|
+
}
|
|
2830
|
+
// cache
|
|
2831
|
+
const cache = this.cacheEntity.getInstance(table);
|
|
2832
|
+
let items = await cache.mget(ids, {
|
|
2833
|
+
mget: async ids => {
|
|
2834
|
+
return await super._mget_original(table, ids, {
|
|
2835
|
+
disableDeleted: true
|
|
2836
|
+
});
|
|
2837
|
+
},
|
|
2838
|
+
db: this.db
|
|
2839
|
+
});
|
|
2840
|
+
// filter disableDeleted
|
|
2841
|
+
items = items.filter(item => {
|
|
2842
|
+
if (!item) return false;
|
|
2843
|
+
if (!this._checkIfEntityValidByDeleted(item, options)) return false;
|
|
2844
|
+
return true;
|
|
2845
|
+
});
|
|
2846
|
+
return this.__filterMGetColumns(items, options?.columns);
|
|
2847
|
+
}
|
|
2848
|
+
async count(params, options, _modelJoins) {
|
|
2849
|
+
const column = params?.column ?? '*';
|
|
2850
|
+
const params2 = Object.assign({}, params, {
|
|
2851
|
+
aggrs: {
|
|
2852
|
+
count: column
|
|
2853
|
+
},
|
|
2854
|
+
column: undefined
|
|
2855
|
+
});
|
|
2856
|
+
const item = await this.aggregate(params2, options);
|
|
2857
|
+
return this.extractFirstValue(item);
|
|
2858
|
+
}
|
|
2859
|
+
async aggregate(params, options, _modelJoins) {
|
|
2860
|
+
const items = await this.__aggregate_raw(undefined, params, options);
|
|
2861
|
+
return items[0];
|
|
2862
|
+
}
|
|
2863
|
+
async __aggregate_raw(table, params, options) {
|
|
2864
|
+
// table
|
|
2865
|
+
table = table || this.getTable();
|
|
2866
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
2867
|
+
const items = await this.__select_cache(table, params, options);
|
|
2868
|
+
return this.convertItemsToBigNumber(items);
|
|
2869
|
+
}
|
|
2870
|
+
async group(params, options, _modelJoins) {
|
|
2871
|
+
return await this.__group_raw(undefined, params, options);
|
|
2872
|
+
}
|
|
2873
|
+
async __group_raw(table, params, options) {
|
|
2874
|
+
// table
|
|
2875
|
+
table = table || this.getTable();
|
|
2876
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
2877
|
+
const items = await this.__select_cache(table, params, options);
|
|
2878
|
+
return this.convertItemsToBigNumber(items);
|
|
2879
|
+
}
|
|
2880
|
+
async select(params, options, _modelJoins) {
|
|
2881
|
+
const items = await this.__select_raw(undefined, params, options);
|
|
2882
|
+
return await this.relations.handleRelationsMany(items, params, options);
|
|
2883
|
+
}
|
|
2884
|
+
async __select_raw(table, params, options) {
|
|
2885
|
+
// table
|
|
2886
|
+
table = table || this.getTable();
|
|
2887
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
2888
|
+
// check if cache
|
|
2889
|
+
if (this._checkDisableCacheEntityByOptions(options)) {
|
|
2890
|
+
return await this.__select_cache(table, params, options);
|
|
2891
|
+
}
|
|
2892
|
+
// 1: select id
|
|
2893
|
+
const columnId = `${table}.id`;
|
|
2894
|
+
const params2 = Object.assign({}, params, {
|
|
2895
|
+
columns: [columnId]
|
|
2896
|
+
});
|
|
2897
|
+
const items = await this.__select_cache(table, params2, options);
|
|
2898
|
+
if (items.length === 0) {
|
|
2899
|
+
// donothing
|
|
2900
|
+
return [];
|
|
2901
|
+
}
|
|
2902
|
+
// 1: special check
|
|
2903
|
+
if (params?.columns) {
|
|
2904
|
+
const columnsTarget = Array.isArray(params?.columns) ? params?.columns : [params?.columns];
|
|
2905
|
+
if (this.__checkIfOnlyKey(columnsTarget, table)) {
|
|
2906
|
+
// just return
|
|
2907
|
+
return items;
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
// 2: mget
|
|
2911
|
+
const ids = items.map(item => cast(item).id);
|
|
2912
|
+
const options2 = params?.columns ? Object.assign({}, options, {
|
|
2913
|
+
columns: params?.columns
|
|
2914
|
+
}) : options;
|
|
2915
|
+
return await this.__mget_raw(table, ids, options2);
|
|
2916
|
+
}
|
|
2917
|
+
async __select_cache(table, params, options) {
|
|
2918
|
+
// check if cache
|
|
2919
|
+
if (this._checkDisableCacheQueryByOptions(options)) {
|
|
2920
|
+
return await super._select(table, params, options);
|
|
2921
|
+
}
|
|
2922
|
+
// builder
|
|
2923
|
+
const builder = this._select_buildParams(table, params, options);
|
|
2924
|
+
const sql = builder.toQuery();
|
|
2925
|
+
const key = {
|
|
2926
|
+
sql
|
|
2927
|
+
};
|
|
2928
|
+
// cache
|
|
2929
|
+
const cache = this.cacheQuery.getInstance(table);
|
|
2930
|
+
const items = await cache.get(key, {
|
|
2931
|
+
get: async () => {
|
|
2932
|
+
return await super._select(table, params, options, builder);
|
|
2933
|
+
},
|
|
2934
|
+
db: this.db
|
|
2935
|
+
});
|
|
2936
|
+
return items;
|
|
2937
|
+
}
|
|
2938
|
+
async get(where, options) {
|
|
2939
|
+
const item = await this.__get_raw(undefined, where, options);
|
|
2940
|
+
return await this.relations.handleRelationsOne(item, options, options);
|
|
2941
|
+
}
|
|
2942
|
+
async __get_raw(table, where, options) {
|
|
2943
|
+
// table
|
|
2944
|
+
table = table || this.getTable();
|
|
2945
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
2946
|
+
// check if cache
|
|
2947
|
+
if (this._checkDisableCacheEntityByOptions(options)) {
|
|
2948
|
+
return await super._get(table, where, options);
|
|
2949
|
+
}
|
|
2950
|
+
const id = this.__checkCacheKeyValid(where, table);
|
|
2951
|
+
if (isNil(id)) {
|
|
2952
|
+
// not key
|
|
2953
|
+
if (this._checkDisableCacheQueryByOptions(options)) {
|
|
2954
|
+
return await super._get(table, where, options);
|
|
2955
|
+
}
|
|
2956
|
+
// by cache query
|
|
2957
|
+
// params
|
|
2958
|
+
const params = {
|
|
2959
|
+
where
|
|
2960
|
+
};
|
|
2961
|
+
if (options?.columns) {
|
|
2962
|
+
params.columns = options?.columns;
|
|
2963
|
+
}
|
|
2964
|
+
// select
|
|
2965
|
+
const options2 = options?.columns ? Object.assign({}, options, {
|
|
2966
|
+
columns: undefined
|
|
2967
|
+
}) : options;
|
|
2968
|
+
const items = await this.__select_raw(table, params, options2);
|
|
2969
|
+
return items[0];
|
|
2970
|
+
}
|
|
2971
|
+
// key
|
|
2972
|
+
return this.__filterGetColumns(await this.__get_key(id, table, where, options), options?.columns);
|
|
2973
|
+
}
|
|
2974
|
+
async update(data, options) {
|
|
2975
|
+
const ids = await this.__update_raw(undefined, data, options);
|
|
2976
|
+
if (!ids || ids.length !== 1) return data;
|
|
2977
|
+
// only support =1
|
|
2978
|
+
const dataNew = [Object.assign({}, data, {
|
|
2979
|
+
id: ids[0]
|
|
2980
|
+
})];
|
|
2981
|
+
const items = await this.relations.handleRelationsMutate(dataNew, dataNew, options, options);
|
|
2982
|
+
return items[0];
|
|
2983
|
+
}
|
|
2984
|
+
async updateBulk(items, options) {
|
|
2985
|
+
await this.__updateBulk_raw(undefined, items, options);
|
|
2986
|
+
return await this.relations.handleRelationsMutate(items, items, options, options);
|
|
2987
|
+
}
|
|
2988
|
+
async __updateBulk_raw(table, items, options) {
|
|
2989
|
+
if (items.length === 0) return;
|
|
2990
|
+
for (const item of items) {
|
|
2991
|
+
await this.__update_raw(table, item, options);
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
async __update_raw(table, data, options) {
|
|
2995
|
+
// table
|
|
2996
|
+
table = table || this.getTable();
|
|
2997
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
2998
|
+
// check if cache
|
|
2999
|
+
if (this._checkDisableCacheEntityByOptions(options)) {
|
|
3000
|
+
await super._update(table, data, options);
|
|
3001
|
+
return;
|
|
3002
|
+
}
|
|
3003
|
+
// check where and get id
|
|
3004
|
+
let id = this.__checkCacheKeyValid(data, table, true);
|
|
3005
|
+
if (!options?.where) {
|
|
3006
|
+
if (isNil(id)) {
|
|
3007
|
+
throw new Error('id should be specified for update method');
|
|
3008
|
+
}
|
|
3009
|
+
if (Array.isArray(id) && id.length === 0) return;
|
|
3010
|
+
const id2 = this.__checkCacheKeyValid(data, table, false);
|
|
3011
|
+
if (!isNil(id2)) {
|
|
3012
|
+
// donothing
|
|
3013
|
+
return;
|
|
3014
|
+
}
|
|
3015
|
+
} else {
|
|
3016
|
+
const id2 = this.__checkCacheKeyValid(options?.where, table, false);
|
|
3017
|
+
if (id2) {
|
|
3018
|
+
id = id2;
|
|
3019
|
+
} else {
|
|
3020
|
+
const where = !isNil(id) ? Object.assign({}, options?.where, {
|
|
3021
|
+
id
|
|
3022
|
+
}) : options?.where;
|
|
3023
|
+
options = Object.assign({}, options, {
|
|
3024
|
+
where: undefined
|
|
3025
|
+
});
|
|
3026
|
+
const items = await this.__select_raw(table, {
|
|
3027
|
+
where,
|
|
3028
|
+
columns: ['id']
|
|
3029
|
+
}, options);
|
|
3030
|
+
if (items.length === 0) {
|
|
3031
|
+
// donothing
|
|
3032
|
+
return;
|
|
3033
|
+
}
|
|
3034
|
+
if (items.length === 1) {
|
|
3035
|
+
id = cast(items[0]).id;
|
|
3036
|
+
} else {
|
|
3037
|
+
id = items.map(item => cast(item).id);
|
|
3038
|
+
}
|
|
3039
|
+
// update by id/ids
|
|
3040
|
+
options = Object.assign({}, options, {
|
|
3041
|
+
where: {
|
|
3042
|
+
id
|
|
3043
|
+
}
|
|
3044
|
+
});
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
await super._update(table, data, options);
|
|
3048
|
+
// delete cache
|
|
3049
|
+
await this.cacheEntityDel(id, table);
|
|
3050
|
+
// id
|
|
3051
|
+
return Array.isArray(id) ? id : [id];
|
|
3052
|
+
}
|
|
3053
|
+
async delete(where, options) {
|
|
3054
|
+
const ids = await this.__delete_raw(undefined, where, options);
|
|
3055
|
+
if (!isNil(ids)) {
|
|
3056
|
+
await this.relations.handleRelationsDelete(ids, options, options);
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
async deleteBulk(ids, options) {
|
|
3060
|
+
return await this.__deleteBulk_raw_with_relations(undefined, ids, options);
|
|
3061
|
+
}
|
|
3062
|
+
async __deleteBulk_raw_with_relations(table, ids, options) {
|
|
3063
|
+
if (ids.length === 0) return;
|
|
3064
|
+
await this.__delete_raw(table, {
|
|
3065
|
+
id: ids
|
|
3066
|
+
}, options);
|
|
3067
|
+
await this.relations.handleRelationsDelete(ids, options, options);
|
|
3068
|
+
}
|
|
3069
|
+
async __delete_raw(table, where, options) {
|
|
3070
|
+
// table
|
|
3071
|
+
table = table || this.getTable();
|
|
3072
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
3073
|
+
// check if cache
|
|
3074
|
+
if (this._checkDisableCacheEntityByOptions(options)) {
|
|
3075
|
+
return await super._delete(table, where, options);
|
|
3076
|
+
}
|
|
3077
|
+
// id
|
|
3078
|
+
let id = this.__checkCacheKeyValid(where, table);
|
|
3079
|
+
if (isNil(id)) {
|
|
3080
|
+
// check where and get id
|
|
3081
|
+
const items = await this.__select_raw(table, {
|
|
3082
|
+
where,
|
|
3083
|
+
columns: ['id']
|
|
3084
|
+
}, options);
|
|
3085
|
+
if (items.length === 0) {
|
|
3086
|
+
// donothing
|
|
3087
|
+
return;
|
|
3088
|
+
}
|
|
3089
|
+
if (items.length === 1) {
|
|
3090
|
+
id = cast(items[0]).id;
|
|
3091
|
+
} else {
|
|
3092
|
+
id = items.map(item => cast(item).id);
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
if (Array.isArray(id) && id.length === 0) return;
|
|
3096
|
+
// delete by id/ids
|
|
3097
|
+
await super._delete(table, {
|
|
3098
|
+
id
|
|
3099
|
+
}, options);
|
|
3100
|
+
// delete cache
|
|
3101
|
+
await this.cacheEntityDel(id, table);
|
|
3102
|
+
// id
|
|
3103
|
+
return Array.isArray(id) ? id : [id];
|
|
3104
|
+
}
|
|
3105
|
+
async __get_key(id, table, where, options) {
|
|
3106
|
+
// cache
|
|
3107
|
+
const cache = this.cacheEntity.getInstance(table);
|
|
3108
|
+
const item = await cache.get(id, {
|
|
3109
|
+
get: async () => {
|
|
3110
|
+
// where: maybe contain aux key
|
|
3111
|
+
// disableInstance: use the model options, not use options by outer
|
|
3112
|
+
return await super._get(table, where, {
|
|
3113
|
+
disableDeleted: true
|
|
3114
|
+
});
|
|
3115
|
+
},
|
|
3116
|
+
db: this.db
|
|
3117
|
+
});
|
|
3118
|
+
if (!item) return item;
|
|
3119
|
+
if (!this._checkIfEntityValidByDeleted(item, options)) return undefined;
|
|
3120
|
+
return item;
|
|
3121
|
+
}
|
|
3122
|
+
__filterMGetColumns(items, columns) {
|
|
3123
|
+
if (items.length === 0 || !columns) return items;
|
|
3124
|
+
return items.map(item => {
|
|
3125
|
+
return this.__filterGetColumns(item, columns);
|
|
3126
|
+
});
|
|
3127
|
+
}
|
|
3128
|
+
__filterGetColumns(data, columns) {
|
|
3129
|
+
if (!data || !columns) return data;
|
|
3130
|
+
if (!Array.isArray(columns)) columns = cast(columns).split(',');
|
|
3131
|
+
const data2 = {};
|
|
3132
|
+
for (let column of cast(columns)) {
|
|
3133
|
+
column = getTargetColumnName(column);
|
|
3134
|
+
if (column === '*') return data;
|
|
3135
|
+
if (data[column] !== undefined) {
|
|
3136
|
+
data2[column] = data[column];
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
return data2;
|
|
3140
|
+
}
|
|
3141
|
+
async cacheEntityDel(id, table) {
|
|
3142
|
+
await this.cacheEntity.del(id, table);
|
|
3143
|
+
await this.cacheQueryClear(table);
|
|
3144
|
+
}
|
|
3145
|
+
async cacheEntityClear(table) {
|
|
3146
|
+
await this.cacheEntity.clear(table);
|
|
3147
|
+
await this.cacheQueryClear(table);
|
|
3148
|
+
}
|
|
3149
|
+
async cacheQueryClear(table) {
|
|
3150
|
+
await this.cacheQuery.clear(table);
|
|
3151
|
+
await this._cacheQueryClearModelsClear();
|
|
3152
|
+
}
|
|
3153
|
+
async _cacheQueryClearModelsClear() {
|
|
3154
|
+
const modelsClear = this._getModelsClear();
|
|
3155
|
+
if (!modelsClear || modelsClear.length === 0) return;
|
|
3156
|
+
for (const modelClear of modelsClear) {
|
|
3157
|
+
const modelTarget = this.newInstanceTarget(modelClear);
|
|
3158
|
+
const modelsClearedByFn = modelTarget.options.cache?.modelsClearedByFn;
|
|
3159
|
+
if (modelsClearedByFn) {
|
|
3160
|
+
await modelsClearedByFn(this.ctx, modelTarget);
|
|
3161
|
+
} else {
|
|
3162
|
+
await modelTarget.cacheQueryClear();
|
|
3163
|
+
}
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
_getModelsClear(modelName) {
|
|
3167
|
+
const modelsClearAll = this._getModelsClearAll();
|
|
3168
|
+
return modelsClearAll[modelName ?? this.$onionName];
|
|
3169
|
+
}
|
|
3170
|
+
_getModelsClearAll() {
|
|
3171
|
+
if (!this[SymbolModelsClearAll]) {
|
|
3172
|
+
this[SymbolModelsClearAll] = this._collectModelsClearAll();
|
|
3173
|
+
}
|
|
3174
|
+
return this[SymbolModelsClearAll];
|
|
3175
|
+
}
|
|
3176
|
+
_collectModelsClearAll() {
|
|
3177
|
+
const modelsClearAll = {};
|
|
3178
|
+
const onionSlices = this.bean.onion.model.getOnionsEnabled();
|
|
3179
|
+
for (const onionSlice of onionSlices) {
|
|
3180
|
+
const modelName = onionSlice.name;
|
|
3181
|
+
if (!modelsClearAll[modelName]) modelsClearAll[modelName] = [];
|
|
3182
|
+
//
|
|
3183
|
+
const modelsClear = onionSlice.beanOptions.options?.cache?.modelsClear;
|
|
3184
|
+
if (modelsClear) {
|
|
3185
|
+
const modelsClear2 = Array.isArray(modelsClear) ? modelsClear : [modelsClear];
|
|
3186
|
+
modelsClearAll[modelName].push(...modelsClear2);
|
|
3187
|
+
}
|
|
3188
|
+
//
|
|
3189
|
+
const modelsClearedBy = onionSlice.beanOptions.options?.cache?.modelsClearedBy;
|
|
3190
|
+
if (modelsClearedBy) {
|
|
3191
|
+
const modelsClearedBy2 = Array.isArray(modelsClearedBy) ? modelsClearedBy : [modelsClearedBy];
|
|
3192
|
+
for (const modelName2 of modelsClearedBy2) {
|
|
3193
|
+
if (!modelsClearAll[modelName2]) modelsClearAll[modelName2] = [];
|
|
3194
|
+
modelsClearAll[modelName2].push(modelName);
|
|
3195
|
+
}
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
return modelsClearAll;
|
|
3199
|
+
}
|
|
3200
|
+
_checkDisableCacheQueryByOptions(options) {
|
|
3201
|
+
if (options?.disableCacheQuery === true || options?.disableCacheQuery === false) {
|
|
3202
|
+
return options?.disableCacheQuery;
|
|
3203
|
+
}
|
|
3204
|
+
return !this.cacheQuery.enabled;
|
|
3205
|
+
}
|
|
3206
|
+
_checkDisableCacheEntityByOptions(options) {
|
|
3207
|
+
if (options?.disableCacheEntity === true || options?.disableCacheEntity === false) {
|
|
3208
|
+
return options?.disableCacheEntity;
|
|
3209
|
+
}
|
|
3210
|
+
return !this.cacheEntity.enabled;
|
|
3211
|
+
}
|
|
3212
|
+
__checkIfOnlyKey(keys, table, noCheckLength) {
|
|
3213
|
+
const columnId = `${table}.id`;
|
|
3214
|
+
if (!noCheckLength) {
|
|
3215
|
+
const keysAux = this.cacheEntity.keysAux;
|
|
3216
|
+
if (keysAux) {
|
|
3217
|
+
const keysAux2 = Array.isArray(keysAux) ? keysAux : [keysAux];
|
|
3218
|
+
keys = keys.filter(item => !keysAux2.includes(String(item)));
|
|
3219
|
+
}
|
|
3220
|
+
if (keys.length !== 1) return false;
|
|
3221
|
+
if (keys[0] === 'id') return 'id';
|
|
3222
|
+
if (keys[0] === columnId) return columnId;
|
|
3223
|
+
return false;
|
|
3224
|
+
} else {
|
|
3225
|
+
if (keys.includes('id')) return 'id';
|
|
3226
|
+
if (keys.includes(columnId)) return columnId;
|
|
3227
|
+
return false;
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
__checkCacheKeyValid(where, table, noCheckLength) {
|
|
3231
|
+
if (!where) return undefined;
|
|
3232
|
+
const columnId = this.__checkIfOnlyKey(Object.keys(where), table, noCheckLength);
|
|
3233
|
+
if (!columnId) return undefined;
|
|
3234
|
+
return ['number', 'string', 'bigint', 'array'].includes(typeof where[columnId]) ? where[columnId] : undefined;
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
|
|
3238
|
+
var _dec$9, _dec2$9, _dec3$2, _class$9;
|
|
3239
|
+
let BeanModelBase = (_dec$9 = Bean(), _dec2$9 = Virtual(), _dec3$2 = BeanInfo({
|
|
3240
|
+
module: "a-orm"
|
|
3241
|
+
}), _dec$9(_class$9 = _dec2$9(_class$9 = _dec3$2(_class$9 = class BeanModelBase extends BeanModelCache {}) || _class$9) || _class$9) || _class$9);
|
|
3242
|
+
|
|
3243
|
+
var _dec$8, _dec2$8, _dec3$1, _dec4$1, _class$8;
|
|
3244
|
+
const SymbolModuleScope$1 = Symbol('SymbolModuleScope');
|
|
3245
|
+
let ServiceEntityResolver = (_dec$8 = Service(), _dec2$8 = BeanInfo({
|
|
3246
|
+
module: "a-orm"
|
|
3247
|
+
}), _dec3$1 = Reflect.metadata("design:type", Function), _dec4$1 = Reflect.metadata("design:paramtypes", [String]), _dec$8(_class$8 = _dec2$8(_class$8 = _dec3$1(_class$8 = _dec4$1(_class$8 = class ServiceEntityResolver extends BeanBase {
|
|
3248
|
+
constructor(moduleScope) {
|
|
3249
|
+
super();
|
|
3250
|
+
this[SymbolModuleScope$1] = void 0;
|
|
3251
|
+
this.__instances = {};
|
|
3252
|
+
this[SymbolModuleScope$1] = moduleScope;
|
|
3253
|
+
}
|
|
3254
|
+
__get__(prop) {
|
|
3255
|
+
if (!this.__instances[prop]) {
|
|
3256
|
+
const beanFullName = `${this[SymbolModuleScope$1]}.entity.${prop}`;
|
|
3257
|
+
const beanOptions = appResource.getBean(beanFullName);
|
|
3258
|
+
this.__instances[prop] = $columnsAll(beanOptions.beanClass, true, true);
|
|
3259
|
+
}
|
|
3260
|
+
return this.__instances[prop];
|
|
3261
|
+
}
|
|
3262
|
+
}) || _class$8) || _class$8) || _class$8) || _class$8);
|
|
3263
|
+
|
|
3264
|
+
var _dec$7, _dec2$7, _dec3, _dec4, _class$7;
|
|
3265
|
+
const SymbolModuleScope = Symbol('SymbolModuleScope');
|
|
3266
|
+
let ServiceModelResolver = (_dec$7 = Service(), _dec2$7 = BeanInfo({
|
|
3267
|
+
module: "a-orm"
|
|
3268
|
+
}), _dec3 = Reflect.metadata("design:type", Function), _dec4 = Reflect.metadata("design:paramtypes", [String]), _dec$7(_class$7 = _dec2$7(_class$7 = _dec3(_class$7 = _dec4(_class$7 = class ServiceModelResolver extends BeanBase {
|
|
3269
|
+
constructor(moduleScope) {
|
|
3270
|
+
super();
|
|
3271
|
+
this[SymbolModuleScope] = void 0;
|
|
3272
|
+
this[SymbolModuleScope] = moduleScope;
|
|
3273
|
+
}
|
|
3274
|
+
__get__(prop) {
|
|
3275
|
+
const beanFullName = `${this[SymbolModuleScope]}.model.${prop}`;
|
|
3276
|
+
return this.bean._getBean(beanFullName);
|
|
3277
|
+
}
|
|
3278
|
+
}) || _class$7) || _class$7) || _class$7) || _class$7);
|
|
3279
|
+
|
|
3280
|
+
var _dec$6, _dec2$6, _class$6;
|
|
3281
|
+
let BroadcastColumnsClear = (_dec$6 = Broadcast(), _dec2$6 = BeanInfo({
|
|
3282
|
+
module: "a-orm"
|
|
3283
|
+
}), _dec$6(_class$6 = _dec2$6(_class$6 = class BroadcastColumnsClear extends BeanBroadcastBase {
|
|
3284
|
+
async execute(data, isEmitter) {
|
|
3285
|
+
const {
|
|
3286
|
+
clientName,
|
|
3287
|
+
tableName
|
|
3288
|
+
} = data;
|
|
3289
|
+
if (!isEmitter) {
|
|
3290
|
+
await cast(this.scope.service.database).__columnsClearRaw(clientName, tableName);
|
|
3291
|
+
}
|
|
3292
|
+
}
|
|
3293
|
+
}) || _class$6) || _class$6);
|
|
3294
|
+
|
|
3295
|
+
var _dec$5, _dec2$5, _class$5;
|
|
3296
|
+
let BroadcastDatabaseClientReload = (_dec$5 = Broadcast(), _dec2$5 = BeanInfo({
|
|
3297
|
+
module: "a-orm"
|
|
3298
|
+
}), _dec$5(_class$5 = _dec2$5(_class$5 = class BroadcastDatabaseClientReload extends BeanBroadcastBase {
|
|
3299
|
+
async execute(data, isEmitter) {
|
|
3300
|
+
const {
|
|
3301
|
+
clientName,
|
|
3302
|
+
clientConfig,
|
|
3303
|
+
extraData
|
|
3304
|
+
} = data;
|
|
3305
|
+
if (!isEmitter) {
|
|
3306
|
+
await cast(this.scope.service.database).__reloadAllClientsRaw(clientName, clientConfig, extraData);
|
|
3307
|
+
}
|
|
3308
|
+
}
|
|
3309
|
+
}) || _class$5) || _class$5);
|
|
3310
|
+
|
|
3311
|
+
var _dec$4, _dec2$4, _class$4;
|
|
3312
|
+
let EventClientNameReal = (_dec$4 = Event(), _dec2$4 = BeanInfo({
|
|
3313
|
+
module: "a-orm"
|
|
3314
|
+
}), _dec$4(_class$4 = _dec2$4(_class$4 = class EventClientNameReal extends BeanEventBase {}) || _class$4) || _class$4);
|
|
3315
|
+
|
|
3316
|
+
var _dec$3, _dec2$3, _class$3;
|
|
3317
|
+
let EventColumnsClear = (_dec$3 = Event(), _dec2$3 = BeanInfo({
|
|
3318
|
+
module: "a-orm"
|
|
3319
|
+
}), _dec$3(_class$3 = _dec2$3(_class$3 = class EventColumnsClear extends BeanEventBase {}) || _class$3) || _class$3);
|
|
3320
|
+
|
|
3321
|
+
var _dec$2, _dec2$2, _class$2;
|
|
3322
|
+
let EventDatabaseClientReload = (_dec$2 = Event(), _dec2$2 = BeanInfo({
|
|
3323
|
+
module: "a-orm"
|
|
3324
|
+
}), _dec$2(_class$2 = _dec2$2(_class$2 = class EventDatabaseClientReload extends BeanEventBase {}) || _class$2) || _class$2);
|
|
3325
|
+
|
|
3326
|
+
var _dec$1, _dec2$1, _class$1;
|
|
3327
|
+
let ScheduleSoftDeletionPrune = (_dec$1 = Schedule({
|
|
3328
|
+
repeat: {
|
|
3329
|
+
every: 24 * 3600 * 1000
|
|
3330
|
+
}
|
|
3331
|
+
}), _dec2$1 = BeanInfo({
|
|
3332
|
+
module: "a-orm"
|
|
3333
|
+
}), _dec$1(_class$1 = _dec2$1(_class$1 = class ScheduleSoftDeletionPrune extends BeanBase {
|
|
3334
|
+
async execute() {
|
|
3335
|
+
const onionSlices = this.bean.onion.model.getOnionsEnabled();
|
|
3336
|
+
for (const onionSlice of onionSlices) {
|
|
3337
|
+
if (onionSlice.beanOptions.options?.disableDeleted) continue;
|
|
3338
|
+
let softDeletionPrune = onionSlice.beanOptions.options?.softDeletionPrune ?? this.scope.config.softDeletionPrune.enable;
|
|
3339
|
+
if (!softDeletionPrune) continue;
|
|
3340
|
+
if (softDeletionPrune === true) softDeletionPrune = {};
|
|
3341
|
+
await this._modulePrune(onionSlice, softDeletionPrune);
|
|
3342
|
+
}
|
|
3343
|
+
}
|
|
3344
|
+
async _modulePrune(onionSlice, softDeletionPrune) {
|
|
3345
|
+
const handler = softDeletionPrune.handler;
|
|
3346
|
+
const expired = softDeletionPrune.expired ?? this.scope.config.softDeletionPrune.expired;
|
|
3347
|
+
const modelTarget = this.bean._getBean(onionSlice.beanOptions.beanFullName);
|
|
3348
|
+
if (handler) {
|
|
3349
|
+
await handler(this.ctx, modelTarget, {
|
|
3350
|
+
expired
|
|
3351
|
+
});
|
|
3352
|
+
} else {
|
|
3353
|
+
const expiredTime = new Date(Date.now() - expired);
|
|
3354
|
+
await modelTarget.delete({
|
|
3355
|
+
deleted: true,
|
|
3356
|
+
updatedAt: {
|
|
3357
|
+
_lt_: expiredTime
|
|
3358
|
+
}
|
|
3359
|
+
}, {
|
|
3360
|
+
disableDeleted: true
|
|
3361
|
+
});
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
}) || _class$1) || _class$1);
|
|
3365
|
+
|
|
3366
|
+
function config(_app) {
|
|
3367
|
+
return {
|
|
3368
|
+
table: {
|
|
3369
|
+
identityType: 'string'
|
|
3370
|
+
},
|
|
3371
|
+
model: {
|
|
3372
|
+
disableDeleted: false,
|
|
3373
|
+
disableInstance: false,
|
|
3374
|
+
disableCreateTime: false,
|
|
3375
|
+
disableUpdateTime: false
|
|
3376
|
+
},
|
|
3377
|
+
softDeletionPrune: {
|
|
3378
|
+
enable: true,
|
|
3379
|
+
expired: 14 * 24 * 3600 * 1000
|
|
3380
|
+
},
|
|
3381
|
+
dialects: {
|
|
3382
|
+
mysql: 'a-ormdialect.databaseDialect.mysql',
|
|
3383
|
+
mysql2: 'a-ormdialect.databaseDialect.mysql3',
|
|
3384
|
+
pg: 'a-ormdialect.databaseDialect.pg'
|
|
3385
|
+
},
|
|
3386
|
+
summer: {
|
|
3387
|
+
enable: true,
|
|
3388
|
+
meta: {},
|
|
3389
|
+
presetDefault: 'redis',
|
|
3390
|
+
preset: {
|
|
3391
|
+
redis: configRedis,
|
|
3392
|
+
redisWithIgnoreNull: configRedisWithIgnoreNull,
|
|
3393
|
+
all: configAll,
|
|
3394
|
+
allWithIgnoreNull: configAllWithIgnoreNull
|
|
3395
|
+
},
|
|
3396
|
+
redis: {
|
|
3397
|
+
client: 'model'
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
};
|
|
3401
|
+
}
|
|
3402
|
+
|
|
3403
|
+
var locale_en_us = {
|
|
3404
|
+
TableIdentity: 'ID',
|
|
3405
|
+
CreatedAt: 'Created At',
|
|
3406
|
+
UpdatedAt: 'Updated At',
|
|
3407
|
+
Deleted: 'Deleted',
|
|
3408
|
+
InstanceId: 'Instance ID',
|
|
3409
|
+
ShouldSpecifyTable: 'should specify the table name'
|
|
3410
|
+
};
|
|
3411
|
+
|
|
3412
|
+
var locale_zh_cn = {
|
|
3413
|
+
TableIdentity: '标识',
|
|
3414
|
+
CreatedAt: '创建时间',
|
|
3415
|
+
UpdatedAt: '修改时间',
|
|
3416
|
+
Deleted: '已删除',
|
|
3417
|
+
InstanceId: '实例标识',
|
|
3418
|
+
ShouldSpecifyTable: '应该指定表名'
|
|
3419
|
+
};
|
|
3420
|
+
|
|
3421
|
+
let Errors = /*#__PURE__*/function (Errors) {
|
|
3422
|
+
Errors[Errors["ShouldSpecifyTable"] = 1001] = "ShouldSpecifyTable";
|
|
3423
|
+
return Errors;
|
|
3424
|
+
}({});
|
|
3425
|
+
|
|
3426
|
+
function ExtendSchemaBuilder(app) {
|
|
3427
|
+
['fetchDatabases', 'createDatabase', 'dropDatabase', 'fetchIndexes'].forEach(method => {
|
|
3428
|
+
knex.SchemaBuilder.extend(method, async function (...args) {
|
|
3429
|
+
const client = cast(cast(this).client).config.client;
|
|
3430
|
+
const dialect = app.bean.scope('a-orm').service.database.getDialect(client);
|
|
3431
|
+
return await dialect[method](this, ...args);
|
|
3432
|
+
});
|
|
3433
|
+
});
|
|
3434
|
+
}
|
|
3435
|
+
|
|
3436
|
+
const __ThisModule__ = 'a-orm';
|
|
3437
|
+
|
|
3438
|
+
function ExtendTableBuilder(app) {
|
|
3439
|
+
const scope = app.bean.scope(__ThisModule__);
|
|
3440
|
+
function _basicFields(options, identityType) {
|
|
3441
|
+
options = options || {};
|
|
3442
|
+
if (options.id !== false) {
|
|
3443
|
+
const _identityType = identityType ?? scope.config.table.identityType;
|
|
3444
|
+
if (_identityType === 'string') {
|
|
3445
|
+
this.bigIncrements();
|
|
3446
|
+
} else if (_identityType === 'number') {
|
|
3447
|
+
this.increments();
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
if (options.timestamps !== false) this.timestamps(true, true, true);
|
|
3451
|
+
if (options.deleted !== false) this.boolean('deleted').defaultTo(false);
|
|
3452
|
+
if (options.iid !== false) this.integer('iid').defaultTo(0);
|
|
3453
|
+
return this;
|
|
3454
|
+
}
|
|
3455
|
+
knex.TableBuilder.extend('basicFields', function (options) {
|
|
3456
|
+
_basicFields.call(this, options, undefined);
|
|
3457
|
+
return this;
|
|
3458
|
+
});
|
|
3459
|
+
knex.TableBuilder.extend('basicFieldsSimple', function (options) {
|
|
3460
|
+
_basicFields.call(this, options, 'number');
|
|
3461
|
+
return this;
|
|
3462
|
+
});
|
|
3463
|
+
knex.TableBuilder.extend('tableIdentity', function (columnName) {
|
|
3464
|
+
const _identityType = scope.config.table.identityType;
|
|
3465
|
+
if (_identityType === 'string') {
|
|
3466
|
+
return this.bigInteger(columnName); // default value is null
|
|
3467
|
+
} else if (_identityType === 'number') {
|
|
3468
|
+
return this.integer(columnName); // default value is null
|
|
3469
|
+
}
|
|
3470
|
+
});
|
|
3471
|
+
knex.TableBuilder.extend('userId', function (columnName) {
|
|
3472
|
+
return this.tableIdentity(columnName ?? 'userId');
|
|
3473
|
+
});
|
|
3474
|
+
knex.TableBuilder.extend('int0', function (columnName) {
|
|
3475
|
+
return this.integer(columnName).defaultTo(0);
|
|
3476
|
+
});
|
|
3477
|
+
knex.TableBuilder.extend('int1', function (columnName) {
|
|
3478
|
+
return this.integer(columnName).defaultTo(1);
|
|
3479
|
+
});
|
|
3480
|
+
['description'].forEach(method => {
|
|
3481
|
+
knex.TableBuilder.extend(method, function (length = 255) {
|
|
3482
|
+
return this.string(method, length);
|
|
3483
|
+
});
|
|
3484
|
+
});
|
|
3485
|
+
['content'].forEach(method => {
|
|
3486
|
+
knex.TableBuilder.extend(method, function (useText) {
|
|
3487
|
+
return useText ? this.text(method) : this.json(method);
|
|
3488
|
+
});
|
|
3489
|
+
});
|
|
3490
|
+
}
|
|
3491
|
+
|
|
3492
|
+
function ExtendKnex(app) {
|
|
3493
|
+
ExtendSchemaBuilder(app);
|
|
3494
|
+
ExtendTableBuilder(app);
|
|
3495
|
+
}
|
|
3496
|
+
|
|
3497
|
+
const SymbolTransactionConsistency = Symbol('SymbolTransactionConsistency');
|
|
3498
|
+
class Main extends BeanSimple {
|
|
3499
|
+
async moduleLoading() {
|
|
3500
|
+
// config
|
|
3501
|
+
const _configDefault = await combineConfigDefault(this.app, configDefault, configDev, configProd, configTest);
|
|
3502
|
+
this.app.config.database = deepExtend({}, _configDefault, this.app.config.database);
|
|
3503
|
+
}
|
|
3504
|
+
async moduleLoaded() {
|
|
3505
|
+
// ExtendKnex
|
|
3506
|
+
ExtendKnex(this.app);
|
|
3507
|
+
// db
|
|
3508
|
+
Object.defineProperty(this.app.context, 'db', {
|
|
3509
|
+
enumerable: false,
|
|
3510
|
+
get() {
|
|
3511
|
+
return this.app.bean._getBean(ServiceDatabaseAsyncLocalStorage$1).current;
|
|
3512
|
+
}
|
|
3513
|
+
});
|
|
3514
|
+
// transactionConsistency
|
|
3515
|
+
Object.defineProperty(this.app.context, 'transactionConsistency', {
|
|
3516
|
+
enumerable: false,
|
|
3517
|
+
get() {
|
|
3518
|
+
if (!this[SymbolTransactionConsistency]) {
|
|
3519
|
+
this[SymbolTransactionConsistency] = this.app.bean._newBean(ServiceTransactionConsistency_);
|
|
3520
|
+
}
|
|
3521
|
+
return this[SymbolTransactionConsistency];
|
|
3522
|
+
}
|
|
3523
|
+
});
|
|
3524
|
+
// commit
|
|
3525
|
+
Object.defineProperty(this.app.context, 'commit', {
|
|
3526
|
+
enumerable: false,
|
|
3527
|
+
get() {
|
|
3528
|
+
return function (cb) {
|
|
3529
|
+
if (this.ctxCaller) {
|
|
3530
|
+
this.ctxCaller.commit(cb);
|
|
3531
|
+
} else {
|
|
3532
|
+
cast(this).transactionConsistency.commit(cb);
|
|
3533
|
+
}
|
|
3534
|
+
};
|
|
3535
|
+
}
|
|
3536
|
+
});
|
|
3537
|
+
Object.defineProperty(this.app.context, 'commitDone', {
|
|
3538
|
+
enumerable: false,
|
|
3539
|
+
get() {
|
|
3540
|
+
return function () {
|
|
3541
|
+
cast(this).transactionConsistency.commitDone();
|
|
3542
|
+
};
|
|
3543
|
+
}
|
|
3544
|
+
});
|
|
3545
|
+
}
|
|
3546
|
+
async configLoaded(_config) {}
|
|
3547
|
+
}
|
|
3548
|
+
async function configDefault(app) {
|
|
3549
|
+
return {
|
|
3550
|
+
testDatabase: false,
|
|
3551
|
+
defaultClient: app.meta.env.DATABASE_DEFAULT_CLIENT,
|
|
3552
|
+
clients: {
|
|
3553
|
+
pg: {
|
|
3554
|
+
client: 'pg',
|
|
3555
|
+
connection: {
|
|
3556
|
+
host: app.meta.env.DATABASE_CLIENT_PG_HOST,
|
|
3557
|
+
port: Number.parseInt(app.meta.env.DATABASE_CLIENT_PG_PORT),
|
|
3558
|
+
user: app.meta.env.DATABASE_CLIENT_PG_USER,
|
|
3559
|
+
password: app.meta.env.DATABASE_CLIENT_PG_PASSWORD,
|
|
3560
|
+
database: app.meta.env.DATABASE_CLIENT_PG_DATABASE
|
|
3561
|
+
}
|
|
3562
|
+
},
|
|
3563
|
+
mysql: {
|
|
3564
|
+
client: 'mysql2',
|
|
3565
|
+
connection: {
|
|
3566
|
+
host: app.meta.env.DATABASE_CLIENT_MYSQL_HOST,
|
|
3567
|
+
port: Number.parseInt(app.meta.env.DATABASE_CLIENT_MYSQL_PORT),
|
|
3568
|
+
user: app.meta.env.DATABASE_CLIENT_MYSQL_USER,
|
|
3569
|
+
password: app.meta.env.DATABASE_CLIENT_MYSQL_PASSWORD,
|
|
3570
|
+
database: app.meta.env.DATABASE_CLIENT_MYSQL_DATABASE
|
|
3571
|
+
}
|
|
3572
|
+
}
|
|
3573
|
+
},
|
|
3574
|
+
base: {
|
|
3575
|
+
pool: {
|
|
3576
|
+
min: 0,
|
|
3577
|
+
max: 5
|
|
3578
|
+
},
|
|
3579
|
+
acquireConnectionTimeout: 60000 * 10,
|
|
3580
|
+
asyncStackTraces: true
|
|
3581
|
+
}
|
|
3582
|
+
};
|
|
3583
|
+
}
|
|
3584
|
+
async function configDev(_app) {
|
|
3585
|
+
return {
|
|
3586
|
+
testDatabase: true,
|
|
3587
|
+
base: {
|
|
3588
|
+
pool: {
|
|
3589
|
+
min: 0,
|
|
3590
|
+
max: 1
|
|
3591
|
+
}
|
|
3592
|
+
}
|
|
3593
|
+
};
|
|
3594
|
+
}
|
|
3595
|
+
async function configProd(_app) {
|
|
3596
|
+
return {
|
|
3597
|
+
testDatabase: false,
|
|
3598
|
+
base: {
|
|
3599
|
+
asyncStackTraces: false
|
|
3600
|
+
}
|
|
3601
|
+
};
|
|
3602
|
+
}
|
|
3603
|
+
async function configTest(_app) {
|
|
3604
|
+
return {
|
|
3605
|
+
testDatabase: true,
|
|
3606
|
+
base: {
|
|
3607
|
+
pool: {
|
|
3608
|
+
min: 0,
|
|
3609
|
+
max: 1
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
};
|
|
3613
|
+
}
|
|
3614
|
+
|
|
3615
|
+
var _dec, _dec2, _class;
|
|
3616
|
+
const locales = {
|
|
3617
|
+
'en-us': locale_en_us,
|
|
3618
|
+
'zh-cn': locale_zh_cn
|
|
3619
|
+
};
|
|
3620
|
+
let ScopeModuleAOrm = (_dec = Scope(), _dec2 = BeanInfo({
|
|
3621
|
+
module: "a-orm"
|
|
3622
|
+
}), _dec(_class = _dec2(_class = class ScopeModuleAOrm extends BeanScopeBase {}) || _class) || _class);
|
|
3623
|
+
function $locale(key) {
|
|
3624
|
+
return `a-orm::${key}`;
|
|
3625
|
+
}
|
|
3626
|
+
/** scope: end */
|
|
3627
|
+
|
|
3628
|
+
function Transaction(options) {
|
|
3629
|
+
return Aspect.aopMethod('a-orm:transaction', options);
|
|
3630
|
+
}
|
|
3631
|
+
const Database = {
|
|
3632
|
+
transaction: Transaction
|
|
3633
|
+
};
|
|
3634
|
+
|
|
3635
|
+
function DatabaseDialect() {
|
|
3636
|
+
return createBeanDecorator('databaseDialect');
|
|
3637
|
+
}
|
|
3638
|
+
|
|
3639
|
+
function DtoAggregate(modelLike, aggrs) {
|
|
3640
|
+
return _DtoAggregate_raw(modelLike, aggrs);
|
|
3641
|
+
}
|
|
3642
|
+
function _DtoAggregate_raw(modelLike, aggrs) {
|
|
3643
|
+
class TargetClass {}
|
|
3644
|
+
return _DtoAggregate_inner(TargetClass, modelLike, aggrs);
|
|
3645
|
+
}
|
|
3646
|
+
function _DtoAggregate_inner(classTarget, _modelLike, aggrs) {
|
|
3647
|
+
for (const key in aggrs) {
|
|
3648
|
+
const columns = ensureArray(aggrs[key]);
|
|
3649
|
+
if (!columns) continue;
|
|
3650
|
+
for (const column of columns) {
|
|
3651
|
+
const column2 = `${key}_${column === '*' ? 'all' : column}`;
|
|
3652
|
+
Api.field(v.optional(), v.bigNumber())(classTarget.prototype, column2);
|
|
3653
|
+
}
|
|
3654
|
+
}
|
|
3655
|
+
return classTarget;
|
|
3656
|
+
}
|
|
3657
|
+
|
|
3658
|
+
function DtoGroup(modelLike, groups, aggrs, columns) {
|
|
3659
|
+
return _DtoGroup_raw(modelLike, groups, aggrs, columns);
|
|
3660
|
+
}
|
|
3661
|
+
function _DtoGroup_raw(modelLike, groups, aggrs, columns) {
|
|
3662
|
+
class TargetClass {}
|
|
3663
|
+
// model
|
|
3664
|
+
const modelClass = prepareClassModel(modelLike);
|
|
3665
|
+
// entity
|
|
3666
|
+
const entityClass = getClassEntityFromClassModel(modelClass);
|
|
3667
|
+
// columns/groups
|
|
3668
|
+
const displays = ensureArray(columns ?? groups);
|
|
3669
|
+
if (displays) {
|
|
3670
|
+
PickClassInner(TargetClass, entityClass, displays);
|
|
3671
|
+
}
|
|
3672
|
+
// aggrs
|
|
3673
|
+
if (aggrs) {
|
|
3674
|
+
_DtoAggregate_inner(TargetClass, modelLike, aggrs);
|
|
3675
|
+
}
|
|
3676
|
+
// ok
|
|
3677
|
+
return TargetClass;
|
|
3678
|
+
}
|
|
3679
|
+
|
|
3680
|
+
function DtoGet(modelLike, params) {
|
|
3681
|
+
return _DtoGet_raw(modelLike, params);
|
|
3682
|
+
}
|
|
3683
|
+
function _DtoGet_raw(modelLike, params) {
|
|
3684
|
+
// model
|
|
3685
|
+
const modelClass = prepareClassModel(modelLike);
|
|
3686
|
+
// entity
|
|
3687
|
+
let entityClass = getClassEntityFromClassModel(modelClass);
|
|
3688
|
+
// columns
|
|
3689
|
+
const columns = prepareColumns(params?.columns);
|
|
3690
|
+
// always create a new class, no matter if columns empty
|
|
3691
|
+
entityClass = $Class.pick(entityClass, columns);
|
|
3692
|
+
// relations
|
|
3693
|
+
_DtoGet_relations(modelClass, entityClass, params);
|
|
3694
|
+
return entityClass;
|
|
3695
|
+
}
|
|
3696
|
+
function _DtoGet_relations(modelClass, entityClass, includeWrapper, mutateTypeTopLevel) {
|
|
3697
|
+
// relations
|
|
3698
|
+
const relations = _DtoGet_relations_collection(modelClass, includeWrapper);
|
|
3699
|
+
if (!relations) return;
|
|
3700
|
+
for (const relation of relations) {
|
|
3701
|
+
_DtoGet_relation_handle(entityClass, relation, mutateTypeTopLevel);
|
|
3702
|
+
}
|
|
3703
|
+
}
|
|
3704
|
+
function _DtoGet_relation_handle(entityClass, relation, mutateTypeTopLevel) {
|
|
3705
|
+
const [relationName, relationReal, includeReal, withReal, autoload] = relation;
|
|
3706
|
+
const {
|
|
3707
|
+
type,
|
|
3708
|
+
model,
|
|
3709
|
+
options
|
|
3710
|
+
} = relationReal;
|
|
3711
|
+
const modelTarget = prepareClassModel(model);
|
|
3712
|
+
const optionsReal = Object.assign({}, options, {
|
|
3713
|
+
include: includeReal,
|
|
3714
|
+
with: withReal
|
|
3715
|
+
});
|
|
3716
|
+
const schemaLazy = _DtoGet_relation_handle_schemaLazy(modelTarget, optionsReal, autoload, mutateTypeTopLevel);
|
|
3717
|
+
if (mutateTypeTopLevel) {
|
|
3718
|
+
let schema;
|
|
3719
|
+
if (type === 'hasOne' || type === 'belongsTo') {
|
|
3720
|
+
schema = v.lazy(v.optional(), schemaLazy);
|
|
3721
|
+
} else {
|
|
3722
|
+
schema = v.array(v.lazy(schemaLazy));
|
|
3723
|
+
}
|
|
3724
|
+
Api.field(v.optional(), schema)(entityClass.prototype, relationName);
|
|
3725
|
+
} else {
|
|
3726
|
+
let schema;
|
|
3727
|
+
if (type === 'hasOne' || type === 'belongsTo') {
|
|
3728
|
+
schema = v.lazy(v.optional(), schemaLazy);
|
|
3729
|
+
} else {
|
|
3730
|
+
if (optionsReal.groups) {
|
|
3731
|
+
schema = v.array(v.lazy(schemaLazy));
|
|
3732
|
+
} else if (optionsReal.aggrs) {
|
|
3733
|
+
schema = v.lazy(v.optional(), schemaLazy);
|
|
3734
|
+
} else {
|
|
3735
|
+
schema = v.array(v.lazy(schemaLazy));
|
|
3736
|
+
}
|
|
3737
|
+
}
|
|
3738
|
+
Api.field(schema)(entityClass.prototype, relationName);
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3741
|
+
function _DtoGet_relation_handle_schemaLazy(modelTarget, optionsReal, autoload, mutateTypeTopLevel) {
|
|
3742
|
+
return () => {
|
|
3743
|
+
if (!autoload) {
|
|
3744
|
+
return _DtoGet_relation_handle_schemaLazy_raw(modelTarget, optionsReal, mutateTypeTopLevel);
|
|
3745
|
+
}
|
|
3746
|
+
// dynamic
|
|
3747
|
+
const entityClass = getClassEntityFromClassModel(modelTarget);
|
|
3748
|
+
const beanFullName = appResource.getBeanFullName(entityClass);
|
|
3749
|
+
const _hashkey = _DtoGet_relation_handle_schemaLazy_hashkey(optionsReal, mutateTypeTopLevel);
|
|
3750
|
+
const dynamicName = `${beanFullName}_${_hashkey}`;
|
|
3751
|
+
let entityTarget = getSchemaDynamic(dynamicName);
|
|
3752
|
+
if (!entityTarget) {
|
|
3753
|
+
entityTarget = _DtoGet_relation_handle_schemaLazy_raw(modelTarget, optionsReal, mutateTypeTopLevel);
|
|
3754
|
+
entityTarget[SymbolSchemaDynamicRefId] = dynamicName;
|
|
3755
|
+
addSchemaDynamic(dynamicName, entityTarget);
|
|
3756
|
+
}
|
|
3757
|
+
return entityTarget;
|
|
3758
|
+
};
|
|
3759
|
+
}
|
|
3760
|
+
function _DtoGet_relation_handle_schemaLazy_raw(modelTarget, optionsReal, mutateTypeTopLevel) {
|
|
3761
|
+
if (mutateTypeTopLevel) {
|
|
3762
|
+
return _DtoMutate_raw(modelTarget, optionsReal, mutateTypeTopLevel, undefined, false); // columnsOmitDefault: undefined
|
|
3763
|
+
} else {
|
|
3764
|
+
if (optionsReal.groups) {
|
|
3765
|
+
return DtoGroup(modelTarget, optionsReal.groups, optionsReal.aggrs, optionsReal.columns);
|
|
3766
|
+
} else if (optionsReal.aggrs) {
|
|
3767
|
+
return DtoAggregate(modelTarget, optionsReal.aggrs);
|
|
3768
|
+
} else {
|
|
3769
|
+
return _DtoGet_raw(modelTarget, optionsReal);
|
|
3770
|
+
}
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
function _DtoGet_relation_handle_schemaLazy_hashkey(optionsReal, mutateTypeTopLevel) {
|
|
3774
|
+
const columns = prepareColumns(optionsReal.columns);
|
|
3775
|
+
const aggrs = ensureArray(optionsReal.aggrs);
|
|
3776
|
+
const groups = ensureArray(optionsReal.groups);
|
|
3777
|
+
return columns || aggrs || groups || mutateTypeTopLevel ? hashkey({
|
|
3778
|
+
columns,
|
|
3779
|
+
aggrs,
|
|
3780
|
+
groups,
|
|
3781
|
+
mutate: mutateTypeTopLevel
|
|
3782
|
+
}) : 'none';
|
|
3783
|
+
}
|
|
3784
|
+
function _DtoGet_relations_collection(modelClass, includeWrapper) {
|
|
3785
|
+
const beanOptions = appResource.getBean(modelClass);
|
|
3786
|
+
const options = beanOptions.options;
|
|
3787
|
+
// collect
|
|
3788
|
+
const relations = [];
|
|
3789
|
+
// include
|
|
3790
|
+
if (options.relations) {
|
|
3791
|
+
for (const key in options.relations) {
|
|
3792
|
+
const relationDef = options.relations[key];
|
|
3793
|
+
const relationCur = includeWrapper?.include?.[key];
|
|
3794
|
+
let relationReal;
|
|
3795
|
+
let includeReal;
|
|
3796
|
+
let withReal;
|
|
3797
|
+
let autoload;
|
|
3798
|
+
if (relationCur === false) {
|
|
3799
|
+
continue;
|
|
3800
|
+
} else if (relationCur === true) {
|
|
3801
|
+
relationReal = relationDef;
|
|
3802
|
+
autoload = relationDef.options?.autoload;
|
|
3803
|
+
} else if (typeof relationCur === 'object') {
|
|
3804
|
+
relationReal = deepExtend({}, relationDef, {
|
|
3805
|
+
options: relationCur
|
|
3806
|
+
});
|
|
3807
|
+
includeReal = relationCur.include;
|
|
3808
|
+
withReal = relationCur.with;
|
|
3809
|
+
} else if (relationDef.options?.autoload) {
|
|
3810
|
+
relationReal = relationDef;
|
|
3811
|
+
autoload = relationDef.options?.autoload;
|
|
3812
|
+
} else {
|
|
3813
|
+
continue;
|
|
3814
|
+
}
|
|
3815
|
+
relations.push([key, relationReal, includeReal, withReal, autoload]);
|
|
3816
|
+
}
|
|
3817
|
+
}
|
|
3818
|
+
// with
|
|
3819
|
+
if (includeWrapper?.with) {
|
|
3820
|
+
for (const key in includeWrapper.with) {
|
|
3821
|
+
const relationReal = includeWrapper.with[key];
|
|
3822
|
+
if (!relationReal) continue;
|
|
3823
|
+
relations.push([key, relationReal, relationReal.options?.include, relationReal.options?.with, false]);
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
return relations;
|
|
3827
|
+
}
|
|
3828
|
+
|
|
3829
|
+
function _DtoMutate_raw(modelLike, params, mutateTypeTopLevel, columnsOmitDefault, topLevel) {
|
|
3830
|
+
// model
|
|
3831
|
+
const modelClass = prepareClassModel(modelLike);
|
|
3832
|
+
// entity
|
|
3833
|
+
let entityClass = getClassEntityFromClassModel(modelClass);
|
|
3834
|
+
// columns
|
|
3835
|
+
const columns = prepareColumns(params?.columns);
|
|
3836
|
+
if (columns) {
|
|
3837
|
+
if (!topLevel) {
|
|
3838
|
+
if (mutateTypeTopLevel === 'create') {
|
|
3839
|
+
for (const key of ['deleted', 'id']) {
|
|
3840
|
+
const index = columns.indexOf(key);
|
|
3841
|
+
if (index > -1) columns.splice(index, 1);
|
|
3842
|
+
}
|
|
3843
|
+
} else {
|
|
3844
|
+
for (const key of ['deleted', 'id']) {
|
|
3845
|
+
if (!columns.includes(key)) columns.unshift(key);
|
|
3846
|
+
}
|
|
3847
|
+
}
|
|
3848
|
+
}
|
|
3849
|
+
entityClass = $Class.pick(entityClass, prepareColumns(params?.columns));
|
|
3850
|
+
} else {
|
|
3851
|
+
const columns = columnsOmitDefault ?? (mutateTypeTopLevel === 'create' ? ['id', 'iid', 'deleted', 'createdAt', 'updatedAt'] : ['iid', 'createdAt', 'updatedAt']);
|
|
3852
|
+
entityClass = $Class.omit(entityClass, prepareColumns(columns));
|
|
3853
|
+
}
|
|
3854
|
+
if (!topLevel && mutateTypeTopLevel !== 'create') {
|
|
3855
|
+
entityClass = $Class.partial(entityClass, ['id', 'deleted']);
|
|
3856
|
+
}
|
|
3857
|
+
// relations
|
|
3858
|
+
_DtoGet_relations(modelClass, entityClass, params, mutateTypeTopLevel);
|
|
3859
|
+
return entityClass;
|
|
3860
|
+
}
|
|
3861
|
+
|
|
3862
|
+
function DtoCreate(modelLike, params) {
|
|
3863
|
+
return _DtoMutate_raw(modelLike, params, 'create', ['id', 'iid', 'deleted', 'createdAt', 'updatedAt'], true);
|
|
3864
|
+
}
|
|
3865
|
+
|
|
3866
|
+
function DtoUpdate(modelLike, params) {
|
|
3867
|
+
return $Class.partial(_DtoMutate_raw(modelLike, params, 'update', ['id', 'iid', 'deleted', 'createdAt', 'updatedAt'], true));
|
|
3868
|
+
}
|
|
3869
|
+
|
|
3870
|
+
const $Dto = {
|
|
3871
|
+
create: DtoCreate,
|
|
3872
|
+
update: DtoUpdate,
|
|
3873
|
+
get: DtoGet,
|
|
3874
|
+
aggregate: DtoAggregate,
|
|
3875
|
+
group: DtoGroup
|
|
3876
|
+
};
|
|
3877
|
+
|
|
3878
|
+
// const __tableNames = new Set();
|
|
3879
|
+
|
|
3880
|
+
function Entity(table, options) {
|
|
3881
|
+
if (typeof table === 'string') {
|
|
3882
|
+
options = Object.assign({}, options, {
|
|
3883
|
+
table
|
|
3884
|
+
});
|
|
3885
|
+
} else {
|
|
3886
|
+
options = table || {};
|
|
3887
|
+
}
|
|
3888
|
+
// // tableName
|
|
3889
|
+
// const tableName = options.table;
|
|
3890
|
+
// if (__tableNames.has(tableName)) {
|
|
3891
|
+
// throw new Error(`entity table exists: ${tableName}`);
|
|
3892
|
+
// }
|
|
3893
|
+
// __tableNames.add(tableName);
|
|
3894
|
+
return createBeanDecorator('entity', options, false, target => {
|
|
3895
|
+
mergeFieldsOpenapiMetadata(target);
|
|
3896
|
+
});
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3899
|
+
function Model(options) {
|
|
3900
|
+
return createBeanDecorator('model', options);
|
|
3901
|
+
}
|
|
3902
|
+
|
|
3903
|
+
function hasOne$2(classModel, key, options) {
|
|
3904
|
+
// : IModelRelationHasOne<MODEL, AUTOLOAD, COLUMNS> {
|
|
3905
|
+
return {
|
|
3906
|
+
type: 'hasOne',
|
|
3907
|
+
model: classModel,
|
|
3908
|
+
key,
|
|
3909
|
+
options
|
|
3910
|
+
};
|
|
3911
|
+
}
|
|
3912
|
+
function belongsTo$1(_classModelSelf, classModel, key, options) {
|
|
3913
|
+
// : IModelRelationBelongsTo<MODELSelf, MODEL, AUTOLOAD, COLUMNS> {
|
|
3914
|
+
return {
|
|
3915
|
+
type: 'belongsTo',
|
|
3916
|
+
model: classModel,
|
|
3917
|
+
key,
|
|
3918
|
+
options
|
|
3919
|
+
};
|
|
3920
|
+
}
|
|
3921
|
+
function hasMany$2(classModel, key, options, _modelJoins, _group) {
|
|
3922
|
+
// : IModelRelationHasMany<MODEL, AUTOLOAD, COLUMNS, ModelJoins> {
|
|
3923
|
+
return {
|
|
3924
|
+
type: 'hasMany',
|
|
3925
|
+
model: classModel,
|
|
3926
|
+
key,
|
|
3927
|
+
options
|
|
3928
|
+
};
|
|
3929
|
+
}
|
|
3930
|
+
function belongsToMany$2(classModelMiddle, classModel, keyFrom, keyTo, options, _modelJoins, _group) {
|
|
3931
|
+
// : IModelRelationBelongsToMany<MODELMiddle, MODEL, AUTOLOAD, COLUMNS, ModelJoins> {
|
|
3932
|
+
return {
|
|
3933
|
+
type: 'belongsToMany',
|
|
3934
|
+
modelMiddle: classModelMiddle,
|
|
3935
|
+
model: classModel,
|
|
3936
|
+
keyFrom,
|
|
3937
|
+
keyTo,
|
|
3938
|
+
options
|
|
3939
|
+
};
|
|
3940
|
+
}
|
|
3941
|
+
const $relation = {
|
|
3942
|
+
hasOne: hasOne$2,
|
|
3943
|
+
belongsTo: belongsTo$1,
|
|
3944
|
+
hasMany: hasMany$2,
|
|
3945
|
+
belongsToMany: belongsToMany$2
|
|
3946
|
+
};
|
|
3947
|
+
|
|
3948
|
+
// function hasMany<
|
|
3949
|
+
// MODEL extends BeanModelMeta | (keyof IModelClassRecord),
|
|
3950
|
+
// AUTOLOAD extends boolean = boolean,
|
|
3951
|
+
// COLUMNS
|
|
3952
|
+
// extends TypeModelColumn<TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]> = TypeModelColumn<TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]>,
|
|
3953
|
+
// ModelJoins extends TypeModelsClassLikeGeneral | undefined = undefined,
|
|
3954
|
+
// Aggrs extends TypeModelSelectAggrParamsAggrs<
|
|
3955
|
+
// TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]
|
|
3956
|
+
// > | undefined = undefined, // TypeModelSelectAggrParamsAggrs<TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]>,
|
|
3957
|
+
// Groups extends TypeModelColumnsStrict<
|
|
3958
|
+
// TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]
|
|
3959
|
+
// > | undefined = undefined, // TypeModelColumnsStrict<TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]>,
|
|
3960
|
+
// >(
|
|
3961
|
+
// classModel: TypeModelClassLike<MODEL>,
|
|
3962
|
+
// key: keyof TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity],
|
|
3963
|
+
// options?: IModelRelationOptionsMany<TypeModelOfModelLike<MODEL>, AUTOLOAD, COLUMNS, ModelJoins, Aggrs, Groups>,
|
|
3964
|
+
// _modelJoins?: ModelJoins,
|
|
3965
|
+
// _aggrs?: Aggrs,
|
|
3966
|
+
// _groups?: Groups,
|
|
3967
|
+
// ): any { // : IModelRelationHasMany<MODEL, AUTOLOAD, COLUMNS, ModelJoins> {
|
|
3968
|
+
// return { type: 'hasMany', model: classModel, key, options };
|
|
3969
|
+
// }
|
|
3970
|
+
|
|
3971
|
+
// function belongsToMany<
|
|
3972
|
+
// MODELMiddle extends BeanModelMeta | (keyof IModelClassRecord),
|
|
3973
|
+
// MODEL extends BeanModelMeta | (keyof IModelClassRecord),
|
|
3974
|
+
// AUTOLOAD extends boolean = boolean,
|
|
3975
|
+
// COLUMNS
|
|
3976
|
+
// extends TypeModelColumn<TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]> = TypeModelColumn<TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]>,
|
|
3977
|
+
// ModelJoins extends TypeModelsClassLikeGeneral | undefined = undefined,
|
|
3978
|
+
// Aggrs extends TypeModelSelectAggrParamsAggrs<
|
|
3979
|
+
// TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]
|
|
3980
|
+
// > | undefined = undefined, // TypeModelSelectAggrParamsAggrs<TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]>,
|
|
3981
|
+
// Groups extends TypeModelColumnsStrict<
|
|
3982
|
+
// TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]
|
|
3983
|
+
// > | undefined = undefined, // TypeModelColumnsStrict<TypeModelOfModelLike<MODEL>[TypeSymbolKeyEntity]>,
|
|
3984
|
+
// >(
|
|
3985
|
+
// classModelMiddle: TypeModelClassLike<MODELMiddle>,
|
|
3986
|
+
// classModel: TypeModelClassLike<MODEL>,
|
|
3987
|
+
// keyFrom: keyof TypeModelOfModelLike<MODELMiddle>[TypeSymbolKeyEntity],
|
|
3988
|
+
// keyTo: keyof TypeModelOfModelLike<MODELMiddle>[TypeSymbolKeyEntity],
|
|
3989
|
+
// options?: IModelRelationOptionsMany<TypeModelOfModelLike<MODEL>, AUTOLOAD, COLUMNS, ModelJoins, Aggrs, Groups>,
|
|
3990
|
+
// _modelJoins?: ModelJoins,
|
|
3991
|
+
// _aggrs?: Aggrs,
|
|
3992
|
+
// _groups?: Groups,
|
|
3993
|
+
// ): any { // : IModelRelationBelongsToMany<MODELMiddle, MODEL, AUTOLOAD, COLUMNS, ModelJoins> {
|
|
3994
|
+
// return { type: 'belongsToMany', modelMiddle: classModelMiddle, model: classModel, keyFrom, keyTo, options };
|
|
3995
|
+
// }
|
|
3996
|
+
|
|
3997
|
+
function hasOne$1(classModel, key, options) {
|
|
3998
|
+
return {
|
|
3999
|
+
type: 'hasOne',
|
|
4000
|
+
model: classModel,
|
|
4001
|
+
key,
|
|
4002
|
+
options
|
|
4003
|
+
};
|
|
4004
|
+
}
|
|
4005
|
+
function belongsTo(_classModelSelf, classModel, key, options) {
|
|
4006
|
+
return {
|
|
4007
|
+
type: 'belongsTo',
|
|
4008
|
+
model: classModel,
|
|
4009
|
+
key,
|
|
4010
|
+
options
|
|
4011
|
+
};
|
|
4012
|
+
}
|
|
4013
|
+
function hasMany$1(classModel, key, options, _modelJoins, _group) {
|
|
4014
|
+
return {
|
|
4015
|
+
type: 'hasMany',
|
|
4016
|
+
model: classModel,
|
|
4017
|
+
key,
|
|
4018
|
+
options
|
|
4019
|
+
};
|
|
4020
|
+
}
|
|
4021
|
+
function belongsToMany$1(classModelMiddle, classModel, keyFrom, keyTo, options, _modelJoins, _group) {
|
|
4022
|
+
return {
|
|
4023
|
+
type: 'belongsToMany',
|
|
4024
|
+
modelMiddle: classModelMiddle,
|
|
4025
|
+
model: classModel,
|
|
4026
|
+
keyFrom,
|
|
4027
|
+
keyTo,
|
|
4028
|
+
options
|
|
4029
|
+
};
|
|
4030
|
+
}
|
|
4031
|
+
const $relationDynamic = {
|
|
4032
|
+
hasOne: hasOne$1,
|
|
4033
|
+
belongsTo,
|
|
4034
|
+
hasMany: hasMany$1,
|
|
4035
|
+
belongsToMany: belongsToMany$1
|
|
4036
|
+
};
|
|
4037
|
+
|
|
4038
|
+
function hasOne(classModel, key, options) {
|
|
4039
|
+
return {
|
|
4040
|
+
type: 'hasOne',
|
|
4041
|
+
model: classModel,
|
|
4042
|
+
key,
|
|
4043
|
+
options
|
|
4044
|
+
};
|
|
4045
|
+
}
|
|
4046
|
+
|
|
4047
|
+
// function belongsTo<
|
|
4048
|
+
// MODELSelf extends BeanModelMeta | (keyof IModelClassRecord),
|
|
4049
|
+
// MODEL extends BeanModelMeta | (keyof IModelClassRecord),
|
|
4050
|
+
// OPTIONS extends IModelRelationOptionsOneMutate<TypeModelOfModelLike<MODEL>>,
|
|
4051
|
+
// >(
|
|
4052
|
+
// _classModelSelf: TypeModelClassLike<MODELSelf>,
|
|
4053
|
+
// classModel: TypeModelClassLike<MODEL>,
|
|
4054
|
+
// key: keyof TypeModelOfModelLike<MODELSelf>[TypeSymbolKeyEntity],
|
|
4055
|
+
// options?: OPTIONS,
|
|
4056
|
+
// ): IModelRelationBelongsToDynamic<MODELSelf, MODEL, OPTIONS> {
|
|
4057
|
+
// return { type: 'belongsTo', model: classModel, key, options };
|
|
4058
|
+
// }
|
|
4059
|
+
|
|
4060
|
+
function hasMany(classModel, key, options) {
|
|
4061
|
+
return {
|
|
4062
|
+
type: 'hasMany',
|
|
4063
|
+
model: classModel,
|
|
4064
|
+
key,
|
|
4065
|
+
options
|
|
4066
|
+
};
|
|
4067
|
+
}
|
|
4068
|
+
function belongsToMany(classModelMiddle, classModel, keyFrom, keyTo, options) {
|
|
4069
|
+
return {
|
|
4070
|
+
type: 'belongsToMany',
|
|
4071
|
+
modelMiddle: classModelMiddle,
|
|
4072
|
+
model: classModel,
|
|
4073
|
+
keyFrom,
|
|
4074
|
+
keyTo,
|
|
4075
|
+
options
|
|
4076
|
+
};
|
|
4077
|
+
}
|
|
4078
|
+
const $relationMutate = {
|
|
4079
|
+
hasOne,
|
|
4080
|
+
// belongsTo,
|
|
4081
|
+
hasMany,
|
|
4082
|
+
belongsToMany
|
|
4083
|
+
};
|
|
4084
|
+
|
|
4085
|
+
export { $Dto, $column, $columns, $columnsAll, $locale, $relation, $relationDynamic, $relationMutate, $tableColumns, $tableComments, $tableDefaults, $tableName, AopMethodTransaction, BeanDatabase, BeanDatabaseDialectBase, BeanModel, BeanModelBase, BeanModelMeta, BroadcastColumnsClear, BroadcastDatabaseClientReload, Database, DatabaseDialect, Entity, EntityBase, EntityBaseEmpty, EntityBaseInner, EntityBaseSimple, Errors, EventClientNameReal, EventColumnsClear, EventDatabaseClientReload, ExtendKnex, ExtendSchemaBuilder, ExtendTableBuilder, Main, Model, Op, OpAggrs, OpJoint, OpJointValues, OpNormal, OpNormalValues, OpValues, ScheduleSoftDeletionPrune, ScopeModuleAOrm, ServiceCacheEntity, ServiceCacheQuery, ServiceColumns, ServiceColumnsCache, ServiceDatabase, ServiceDatabaseAsyncLocalStorage, ServiceDatabaseClient, ServiceDb, ServiceEntityResolver, ServiceModelResolver, ServiceRelations, ServiceTransaction, ServiceTransactionAsyncLocalStorage, ServiceTransactionConsistency, ServiceTransactionFiber, ServiceTransactionState, SymbolKeyEntity, SymbolKeyEntityMeta, SymbolKeyFieldsMore, SymbolKeyModelOptions, TransactionIsolationLevelsMap, buildWhere, config, configDefault, getClassEntityFromClassModel, getTableOrTableAlias, getTargetColumnName, isAggrColumn, isRaw, locales, prepareClassModel, prepareColumns };
|