vona-module-a-orm 5.0.96 → 5.1.2
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 +0 -0
- package/cli/entity/metadata/generate.ts +2 -1
- package/cli/model/metadata/generate.ts +6 -2
- package/cli/model/metadata/magic.ts +15 -6
- package/dist/.metadata/index.d.ts +1 -0
- package/dist/.metadata/index.d.ts.map +1 -0
- package/dist/.metadata/locales.d.ts +1 -0
- package/dist/.metadata/locales.d.ts.map +1 -0
- package/dist/.metadata/this.d.ts +1 -0
- package/dist/.metadata/this.d.ts.map +1 -0
- package/dist/bean/aopMethod.transaction.d.ts +2 -1
- package/dist/bean/aopMethod.transaction.d.ts.map +1 -0
- package/dist/bean/bean.database.d.ts +2 -1
- package/dist/bean/bean.database.d.ts.map +1 -0
- package/dist/bean/bean.databaseDialectBase.d.ts +2 -1
- package/dist/bean/bean.databaseDialectBase.d.ts.map +1 -0
- package/dist/bean/bean.model/bean.model_cache.d.ts +5 -1
- package/dist/bean/bean.model/bean.model_cache.d.ts.map +1 -0
- package/dist/bean/bean.model/bean.model_crud.d.ts +1 -0
- package/dist/bean/bean.model/bean.model_crud.d.ts.map +1 -0
- package/dist/bean/bean.model/bean.model_crud_inner.d.ts +3 -1
- package/dist/bean/bean.model/bean.model_crud_inner.d.ts.map +1 -0
- package/dist/bean/bean.model/bean.model_crud_table.d.ts +1 -0
- package/dist/bean/bean.model/bean.model_crud_table.d.ts.map +1 -0
- package/dist/bean/bean.model/bean.model_knex.d.ts +1 -0
- package/dist/bean/bean.model/bean.model_knex.d.ts.map +1 -0
- package/dist/bean/bean.model/bean.model_meta.d.ts +3 -2
- package/dist/bean/bean.model/bean.model_meta.d.ts.map +1 -0
- package/dist/bean/bean.model/bean.model_utils.d.ts +5 -3
- package/dist/bean/bean.model/bean.model_utils.d.ts.map +1 -0
- package/dist/bean/bean.model/bean.model_view.d.ts +1 -0
- package/dist/bean/bean.model/bean.model_view.d.ts.map +1 -0
- package/dist/bean/bean.model.d.ts +1 -0
- package/dist/bean/bean.model.d.ts.map +1 -0
- package/dist/bean/bean.modelBase.d.ts +1 -0
- package/dist/bean/bean.modelBase.d.ts.map +1 -0
- package/dist/bean/broadcast.columnsClear.d.ts +2 -1
- package/dist/bean/broadcast.columnsClear.d.ts.map +1 -0
- package/dist/bean/event.clientNameReal.d.ts +2 -1
- package/dist/bean/event.clientNameReal.d.ts.map +1 -0
- package/dist/bean/event.columnsClear.d.ts +2 -1
- package/dist/bean/event.columnsClear.d.ts.map +1 -0
- package/dist/bean/hmr.entity.d.ts +1 -0
- package/dist/bean/hmr.entity.d.ts.map +1 -0
- package/dist/bean/hmr.model.d.ts +1 -0
- package/dist/bean/hmr.model.d.ts.map +1 -0
- package/dist/bean/queue.doubleDelete.d.ts +2 -1
- package/dist/bean/queue.doubleDelete.d.ts.map +1 -0
- package/dist/bean/schedule.softDeletionPrune.d.ts +1 -0
- package/dist/bean/schedule.softDeletionPrune.d.ts.map +1 -0
- package/dist/common/buildWhere.d.ts +1 -0
- package/dist/common/buildWhere.d.ts.map +1 -0
- package/dist/common/checkWhere.d.ts +1 -0
- package/dist/common/checkWhere.d.ts.map +1 -0
- package/dist/common/index.d.ts +1 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/utils.d.ts +2 -1
- package/dist/common/utils.d.ts.map +1 -0
- package/dist/config/config.d.ts +1 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/errors.d.ts +1 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/locale/en-us.d.ts +1 -0
- package/dist/config/locale/en-us.d.ts.map +1 -0
- package/dist/config/locale/zh-cn.d.ts +1 -0
- package/dist/config/locale/zh-cn.d.ts.map +1 -0
- package/dist/extend/index.d.ts +1 -0
- package/dist/extend/index.d.ts.map +1 -0
- package/dist/extend/schemaBuilder.d.ts +1 -0
- package/dist/extend/schemaBuilder.d.ts.map +1 -0
- package/dist/extend/tableBuilder.d.ts +1 -0
- package/dist/extend/tableBuilder.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +94 -15
- package/dist/index.js.map +1 -0
- package/dist/lib/const.d.ts +1 -0
- package/dist/lib/const.d.ts.map +1 -0
- package/dist/lib/databaseDialect.d.ts +1 -0
- package/dist/lib/databaseDialect.d.ts.map +1 -0
- package/dist/lib/dto/dto.d.ts +3 -0
- package/dist/lib/dto/dto.d.ts.map +1 -0
- package/dist/lib/dto/dtoAggregate.d.ts +3 -2
- package/dist/lib/dto/dtoAggregate.d.ts.map +1 -0
- package/dist/lib/dto/dtoCreate.d.ts +2 -1
- package/dist/lib/dto/dtoCreate.d.ts.map +1 -0
- package/dist/lib/dto/dtoGet.d.ts +2 -1
- package/dist/lib/dto/dtoGet.d.ts.map +1 -0
- package/dist/lib/dto/dtoGroup.d.ts +2 -1
- package/dist/lib/dto/dtoGroup.d.ts.map +1 -0
- package/dist/lib/dto/dtoListAndCount.d.ts +4 -0
- package/dist/lib/dto/dtoListAndCount.d.ts.map +1 -0
- package/dist/lib/dto/dtoMutate.d.ts +3 -2
- package/dist/lib/dto/dtoMutate.d.ts.map +1 -0
- package/dist/lib/dto/dtoQuery.d.ts +1 -0
- package/dist/lib/dto/dtoQuery.d.ts.map +1 -0
- package/dist/lib/dto/dtoQueryPage.d.ts +1 -0
- package/dist/lib/dto/dtoQueryPage.d.ts.map +1 -0
- package/dist/lib/dto/dtoSelectAndCount.d.ts +2 -1
- package/dist/lib/dto/dtoSelectAndCount.d.ts.map +1 -0
- package/dist/lib/dto/dtoUpdate.d.ts +2 -1
- package/dist/lib/dto/dtoUpdate.d.ts.map +1 -0
- package/dist/lib/dto/index.d.ts +1 -0
- package/dist/lib/dto/index.d.ts.map +1 -0
- package/dist/lib/entity.d.ts +1 -0
- package/dist/lib/entity.d.ts.map +1 -0
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/model.d.ts +1 -0
- package/dist/lib/model.d.ts.map +1 -0
- package/dist/lib/modelCacheBase.d.ts +2 -1
- package/dist/lib/modelCacheBase.d.ts.map +1 -0
- package/dist/lib/relations.d.ts +5 -4
- package/dist/lib/relations.d.ts.map +1 -0
- package/dist/lib/relationsDynamic.d.ts +5 -4
- package/dist/lib/relationsDynamic.d.ts.map +1 -0
- package/dist/lib/relationsMutate.d.ts +4 -3
- package/dist/lib/relationsMutate.d.ts.map +1 -0
- package/dist/lib/relationsStatic.d.ts +1 -0
- package/dist/lib/relationsStatic.d.ts.map +1 -0
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/main.d.ts +2 -1
- package/dist/main.d.ts.map +1 -0
- package/dist/service/cacheEntity_.d.ts +1 -0
- package/dist/service/cacheEntity_.d.ts.map +1 -0
- package/dist/service/cacheQuery_.d.ts +1 -0
- package/dist/service/cacheQuery_.d.ts.map +1 -0
- package/dist/service/columnsCache_.d.ts +2 -1
- package/dist/service/columnsCache_.d.ts.map +1 -0
- package/dist/service/columns_.d.ts +2 -1
- package/dist/service/columns_.d.ts.map +1 -0
- package/dist/service/database.d.ts +2 -1
- package/dist/service/database.d.ts.map +1 -0
- package/dist/service/databaseAsyncLocalStorage_.d.ts +1 -0
- package/dist/service/databaseAsyncLocalStorage_.d.ts.map +1 -0
- package/dist/service/databaseClient_.d.ts +2 -1
- package/dist/service/databaseClient_.d.ts.map +1 -0
- package/dist/service/db_.d.ts +2 -1
- package/dist/service/db_.d.ts.map +1 -0
- package/dist/service/entityResolver_.d.ts +1 -0
- package/dist/service/entityResolver_.d.ts.map +1 -0
- package/dist/service/modelResolver_.d.ts +1 -0
- package/dist/service/modelResolver_.d.ts.map +1 -0
- package/dist/service/relations_.d.ts +2 -1
- package/dist/service/relations_.d.ts.map +1 -0
- package/dist/service/transactionAsyncLocalStorage_.d.ts +1 -0
- package/dist/service/transactionAsyncLocalStorage_.d.ts.map +1 -0
- package/dist/service/transactionConsistency/342/200/214_.d.ts +1 -0
- package/dist/service/transactionConsistency/342/200/214_.d.ts.map +1 -0
- package/dist/service/transactionFiber_.d.ts +1 -0
- package/dist/service/transactionFiber_.d.ts.map +1 -0
- package/dist/service/transactionState_.d.ts +2 -1
- package/dist/service/transactionState_.d.ts.map +1 -0
- package/dist/service/transaction_.d.ts +2 -1
- package/dist/service/transaction_.d.ts.map +1 -0
- package/dist/types/columns.d.ts +1 -0
- package/dist/types/columns.d.ts.map +1 -0
- package/dist/types/config.d.ts +1 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/database.d.ts +1 -0
- package/dist/types/database.d.ts.map +1 -0
- package/dist/types/depth.d.ts +1 -0
- package/dist/types/depth.d.ts.map +1 -0
- package/dist/types/dialect.d.ts +1 -0
- package/dist/types/dialect.d.ts.map +1 -0
- package/dist/types/dto/dtoAggregate.d.ts +1 -0
- package/dist/types/dto/dtoAggregate.d.ts.map +1 -0
- package/dist/types/dto/dtoGet.d.ts +3 -2
- package/dist/types/dto/dtoGet.d.ts.map +1 -0
- package/dist/types/dto/dtoGroup.d.ts +1 -0
- package/dist/types/dto/dtoGroup.d.ts.map +1 -0
- package/dist/types/dto/dtoListAndCount.d.ts +8 -0
- package/dist/types/dto/dtoListAndCount.d.ts.map +1 -0
- package/dist/types/dto/dtoMutate.d.ts +8 -9
- package/dist/types/dto/dtoMutate.d.ts.map +1 -0
- package/dist/types/dto/dtoQueryBase.d.ts +1 -0
- package/dist/types/dto/dtoQueryBase.d.ts.map +1 -0
- package/dist/types/dto/dtoQueryPageBase.d.ts +1 -0
- package/dist/types/dto/dtoQueryPageBase.d.ts.map +1 -0
- package/dist/types/dto/dtoSelectAndCount.d.ts +2 -1
- package/dist/types/dto/dtoSelectAndCount.d.ts.map +1 -0
- package/dist/types/dto/index.d.ts +2 -0
- package/dist/types/dto/index.d.ts.map +1 -0
- package/dist/types/entity.d.ts +1 -0
- package/dist/types/entity.d.ts.map +1 -0
- package/dist/types/entityBase.d.ts +1 -0
- package/dist/types/entityBase.d.ts.map +1 -0
- package/dist/types/entityBaseEmpty.d.ts +1 -0
- package/dist/types/entityBaseEmpty.d.ts.map +1 -0
- package/dist/types/entityBaseInner.d.ts +1 -0
- package/dist/types/entityBaseInner.d.ts.map +1 -0
- package/dist/types/entityBaseSimple.d.ts +1 -0
- package/dist/types/entityBaseSimple.d.ts.map +1 -0
- package/dist/types/extra.d.ts +1 -0
- package/dist/types/extra.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/logger.d.ts +1 -0
- package/dist/types/logger.d.ts.map +1 -0
- package/dist/types/model.d.ts +3 -2
- package/dist/types/model.d.ts.map +1 -0
- package/dist/types/modelAggr.d.ts +2 -1
- package/dist/types/modelAggr.d.ts.map +1 -0
- package/dist/types/modelCount.d.ts +2 -1
- package/dist/types/modelCount.d.ts.map +1 -0
- package/dist/types/modelGeneral.d.ts +4 -3
- package/dist/types/modelGeneral.d.ts.map +1 -0
- package/dist/types/modelGroup.d.ts +2 -1
- package/dist/types/modelGroup.d.ts.map +1 -0
- package/dist/types/modelIncrement.d.ts +19 -0
- package/dist/types/modelIncrement.d.ts.map +1 -0
- package/dist/types/modelWhere.d.ts +2 -1
- package/dist/types/modelWhere.d.ts.map +1 -0
- package/dist/types/onion/databaseDialect.d.ts +1 -0
- package/dist/types/onion/databaseDialect.d.ts.map +1 -0
- package/dist/types/onion/entity.d.ts +1 -0
- package/dist/types/onion/entity.d.ts.map +1 -0
- package/dist/types/onion/index.d.ts +1 -0
- package/dist/types/onion/index.d.ts.map +1 -0
- package/dist/types/onion/model.d.ts +1 -0
- package/dist/types/onion/model.d.ts.map +1 -0
- package/dist/types/onion/table.d.ts +1 -0
- package/dist/types/onion/table.d.ts.map +1 -0
- package/dist/types/relations.d.ts +10 -11
- package/dist/types/relations.d.ts.map +1 -0
- package/dist/types/relationsAggr.d.ts +2 -1
- package/dist/types/relationsAggr.d.ts.map +1 -0
- package/dist/types/relationsColumns.d.ts +5 -4
- package/dist/types/relationsColumns.d.ts.map +1 -0
- package/dist/types/relationsDef.d.ts +5 -4
- package/dist/types/relationsDef.d.ts.map +1 -0
- package/dist/types/relationsDefDynamic.d.ts +6 -5
- package/dist/types/relationsDefDynamic.d.ts.map +1 -0
- package/dist/types/relationsDefMutate.d.ts +1 -0
- package/dist/types/relationsDefMutate.d.ts.map +1 -0
- package/dist/types/relationsGroup.d.ts +1 -0
- package/dist/types/relationsGroup.d.ts.map +1 -0
- package/dist/types/relationsMutate.d.ts +4 -3
- package/dist/types/relationsMutate.d.ts.map +1 -0
- package/dist/types/relationsTables.d.ts +1 -0
- package/dist/types/relationsTables.d.ts.map +1 -0
- package/dist/types/transaction.d.ts +1 -0
- package/dist/types/transaction.d.ts.map +1 -0
- package/dist-cli/entity/metadata/generate.js +1 -1
- package/dist-cli/model/metadata/generate.js +4 -2
- package/dist-cli/model/metadata/magic.js +2 -2
- package/package.json +40 -36
- package/src/.metadata/index.ts +348 -0
- package/src/.metadata/locales.ts +13 -0
- package/src/.metadata/this.ts +2 -0
- package/src/bean/aopMethod.transaction.ts +18 -0
- package/src/bean/bean.database.ts +57 -0
- package/src/bean/bean.databaseDialectBase.ts +149 -0
- package/src/bean/bean.model/bean.model_cache.ts +815 -0
- package/src/bean/bean.model/bean.model_crud.ts +46 -0
- package/src/bean/bean.model/bean.model_crud_inner.ts +281 -0
- package/src/bean/bean.model/bean.model_crud_table.ts +59 -0
- package/src/bean/bean.model/bean.model_knex.ts +60 -0
- package/src/bean/bean.model/bean.model_meta.ts +204 -0
- package/src/bean/bean.model/bean.model_utils.ts +275 -0
- package/src/bean/bean.model/bean.model_view.ts +129 -0
- package/src/bean/bean.model.ts +8 -0
- package/src/bean/bean.modelBase.ts +8 -0
- package/src/bean/broadcast.columnsClear.ts +24 -0
- package/src/bean/event.clientNameReal.ts +10 -0
- package/src/bean/event.columnsClear.ts +13 -0
- package/src/bean/hmr.entity.ts +12 -0
- package/src/bean/hmr.model.ts +16 -0
- package/src/bean/queue.doubleDelete.ts +29 -0
- package/src/bean/schedule.softDeletionPrune.ts +45 -0
- package/src/common/buildWhere.ts +238 -0
- package/src/common/checkWhere.ts +128 -0
- package/src/common/index.ts +3 -0
- package/src/common/utils.ts +74 -0
- package/src/config/config.ts +60 -0
- package/src/config/errors.ts +3 -0
- package/src/config/locale/en-us.ts +8 -0
- package/src/config/locale/zh-cn.ts +8 -0
- package/src/extend/index.ts +12 -0
- package/src/extend/schemaBuilder.ts +29 -0
- package/src/extend/tableBuilder.ts +87 -0
- package/src/index.ts +10 -0
- package/src/lib/const.ts +58 -0
- package/src/lib/databaseDialect.ts +7 -0
- package/src/lib/dto/dto.ts +21 -0
- package/src/lib/dto/dtoAggregate.ts +51 -0
- package/src/lib/dto/dtoCreate.ts +14 -0
- package/src/lib/dto/dtoGet.ts +159 -0
- package/src/lib/dto/dtoGroup.ts +57 -0
- package/src/lib/dto/dtoListAndCount.ts +16 -0
- package/src/lib/dto/dtoMutate.ts +82 -0
- package/src/lib/dto/dtoQuery.ts +9 -0
- package/src/lib/dto/dtoQueryPage.ts +9 -0
- package/src/lib/dto/dtoSelectAndCount.ts +20 -0
- package/src/lib/dto/dtoUpdate.ts +16 -0
- package/src/lib/dto/index.ts +1 -0
- package/src/lib/entity.ts +25 -0
- package/src/lib/index.ts +9 -0
- package/src/lib/model.ts +7 -0
- package/src/lib/modelCacheBase.ts +98 -0
- package/src/lib/relations.ts +118 -0
- package/src/lib/relationsDynamic.ts +75 -0
- package/src/lib/relationsMutate.ts +60 -0
- package/src/lib/relationsStatic.ts +18 -0
- package/src/lib/utils.ts +45 -0
- package/src/main.ts +79 -0
- package/src/service/cacheEntity_.ts +37 -0
- package/src/service/cacheQuery_.ts +20 -0
- package/src/service/columnsCache_.ts +69 -0
- package/src/service/columns_.ts +64 -0
- package/src/service/database.ts +126 -0
- package/src/service/databaseAsyncLocalStorage_.ts +29 -0
- package/src/service/databaseClient_.ts +124 -0
- package/src/service/db_.ts +77 -0
- package/src/service/entityResolver_.ts +25 -0
- package/src/service/modelResolver_.ts +19 -0
- package/src/service/relations_.ts +444 -0
- package/src/service/transactionAsyncLocalStorage_.ts +31 -0
- package/src/service/transactionConsistency/342/200/214_.ts +37 -0
- package/src/service/transactionFiber_.ts +42 -0
- package/src/service/transactionState_.ts +35 -0
- package/src/service/transaction_.ts +147 -0
- package/src/types/columns.ts +8 -0
- package/src/types/config.ts +23 -0
- package/src/types/database.ts +64 -0
- package/src/types/depth.ts +55 -0
- package/src/types/dialect.ts +17 -0
- package/src/types/dto/dtoAggregate.ts +3 -0
- package/src/types/dto/dtoGet.ts +23 -0
- package/src/types/dto/dtoGroup.ts +3 -0
- package/src/types/dto/dtoListAndCount.ts +7 -0
- package/src/types/dto/dtoMutate.ts +231 -0
- package/src/types/dto/dtoQueryBase.ts +18 -0
- package/src/types/dto/dtoQueryPageBase.ts +18 -0
- package/src/types/dto/dtoSelectAndCount.ts +11 -0
- package/src/types/dto/index.ts +8 -0
- package/src/types/entity.ts +15 -0
- package/src/types/entityBase.ts +11 -0
- package/src/types/entityBaseEmpty.ts +1 -0
- package/src/types/entityBaseInner.ts +18 -0
- package/src/types/entityBaseSimple.ts +9 -0
- package/src/types/extra.ts +23 -0
- package/src/types/index.ts +30 -0
- package/src/types/logger.ts +6 -0
- package/src/types/model.ts +152 -0
- package/src/types/modelAggr.ts +69 -0
- package/src/types/modelCount.ts +40 -0
- package/src/types/modelGeneral.ts +61 -0
- package/src/types/modelGroup.ts +48 -0
- package/src/types/modelIncrement.ts +50 -0
- package/src/types/modelWhere.ts +85 -0
- package/src/types/onion/databaseDialect.ts +22 -0
- package/src/types/onion/entity.ts +33 -0
- package/src/types/onion/index.ts +4 -0
- package/src/types/onion/model.ts +68 -0
- package/src/types/onion/table.ts +1 -0
- package/src/types/relations.ts +243 -0
- package/src/types/relationsAggr.ts +31 -0
- package/src/types/relationsColumns.ts +116 -0
- package/src/types/relationsDef.ts +152 -0
- package/src/types/relationsDefDynamic.ts +128 -0
- package/src/types/relationsDefMutate.ts +11 -0
- package/src/types/relationsGroup.ts +58 -0
- package/src/types/relationsMutate.ts +118 -0
- package/src/types/relationsTables.ts +38 -0
- package/src/types/transaction.ts +23 -0
|
@@ -0,0 +1,815 @@
|
|
|
1
|
+
import type { TableIdentity } from 'table-identity';
|
|
2
|
+
|
|
3
|
+
import { isNil } from '@cabloy/utils';
|
|
4
|
+
import { parseFirstWord, toLowerCaseFirstChar } from '@cabloy/word-utils';
|
|
5
|
+
import BigNumber from 'bignumber.js';
|
|
6
|
+
import { cast, deepExtend, disposeInstance } from 'vona';
|
|
7
|
+
|
|
8
|
+
import type { ServiceDb } from '../../service/db_.ts';
|
|
9
|
+
import type {
|
|
10
|
+
IDatabaseClientRecord,
|
|
11
|
+
IModelDeleteOptions,
|
|
12
|
+
IModelGetOptions,
|
|
13
|
+
IModelIncrementParams,
|
|
14
|
+
IModelInsertOptions,
|
|
15
|
+
IModelMethodOptions,
|
|
16
|
+
IModelMethodOptionsGeneral,
|
|
17
|
+
IModelMutateOptions,
|
|
18
|
+
IModelRecord,
|
|
19
|
+
IModelSelectAggrParams,
|
|
20
|
+
IModelSelectCountParams,
|
|
21
|
+
IModelSelectGroupParams,
|
|
22
|
+
IModelSelectParams,
|
|
23
|
+
IModelUpdateOptions,
|
|
24
|
+
ITableRecord,
|
|
25
|
+
TypeModelAggrRelationResult,
|
|
26
|
+
TypeModelClassLikeGeneral,
|
|
27
|
+
TypeModelColumn,
|
|
28
|
+
TypeModelColumns,
|
|
29
|
+
TypeModelGroupRelationResult,
|
|
30
|
+
TypeModelIncrementParamsColumns,
|
|
31
|
+
TypeModelsClassLikeGeneral,
|
|
32
|
+
TypeModelWhere,
|
|
33
|
+
} from '../../types/index.ts';
|
|
34
|
+
import type { TypeQueueDoubleDeleteJobData } from '../queue.doubleDelete.ts';
|
|
35
|
+
|
|
36
|
+
import { getTargetColumnName } from '../../common/utils.ts';
|
|
37
|
+
import { getCacheModelsClear } from '../../lib/const.ts';
|
|
38
|
+
import { ServiceCacheEntity } from '../../service/cacheEntity_.ts';
|
|
39
|
+
import { ServiceCacheQuery } from '../../service/cacheQuery_.ts';
|
|
40
|
+
import { ServiceRelations } from '../../service/relations_.ts';
|
|
41
|
+
import { BeanModelCrud } from './bean.model_crud.ts';
|
|
42
|
+
|
|
43
|
+
export class BeanModelCache<TRecord extends {} = {}> extends BeanModelCrud<TRecord> {
|
|
44
|
+
public cacheQuery: ServiceCacheQuery;
|
|
45
|
+
public cacheEntity: ServiceCacheEntity;
|
|
46
|
+
protected relations: ServiceRelations;
|
|
47
|
+
|
|
48
|
+
protected __init__(clientName?: keyof IDatabaseClientRecord | ServiceDb, table?: keyof ITableRecord) {
|
|
49
|
+
super.__init__(clientName, table);
|
|
50
|
+
this.cacheQuery = this.bean._newBean(ServiceCacheQuery, this);
|
|
51
|
+
this.cacheEntity = this.bean._newBean(ServiceCacheEntity, this);
|
|
52
|
+
this.relations = this.bean._newBean(ServiceRelations, this);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
protected async __dispose__() {
|
|
56
|
+
await disposeInstance(this.cacheQuery);
|
|
57
|
+
await disposeInstance(this.cacheEntity);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async insert<T extends IModelInsertOptions<TRecord>>(data?: Partial<TRecord>, options?: T): Promise<TRecord> {
|
|
61
|
+
if (!data) data = {};
|
|
62
|
+
const items = await this.insertBulk([data], options);
|
|
63
|
+
return items[0];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async insertBulk<T extends IModelInsertOptions<TRecord>>(items: Partial<TRecord>[], options?: T): Promise<TRecord[]> {
|
|
67
|
+
const itemsResult = await this.__insertBulk_raw(undefined, items, options);
|
|
68
|
+
const itemsNew = items.map((item, index) => {
|
|
69
|
+
return Object.assign({}, item, { id: cast(itemsResult[index]).id });
|
|
70
|
+
});
|
|
71
|
+
return await this.relations.handleRelationsMutate(itemsResult, itemsNew as any, options as any, options);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async __insertBulk_raw(
|
|
75
|
+
table: keyof ITableRecord | undefined,
|
|
76
|
+
items: Partial<TRecord>[],
|
|
77
|
+
options?: IModelMutateOptions<TRecord>,
|
|
78
|
+
): Promise<TRecord[]> {
|
|
79
|
+
if (items.length === 0) return [];
|
|
80
|
+
// table
|
|
81
|
+
table = table || this.getTable(items[0]);
|
|
82
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
83
|
+
// insert
|
|
84
|
+
const res = (await this._insertBulk(table, items, options)) as TRecord[];
|
|
85
|
+
// delete cache
|
|
86
|
+
const ids = res.map(item => cast(item).id);
|
|
87
|
+
await this.cacheEntityDel(ids, table);
|
|
88
|
+
return res;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async mutate<T extends IModelMutateOptions<TRecord>>(data?: Partial<TRecord>, options?: T): Promise<Partial<TRecord>> {
|
|
92
|
+
if (!data) data = {};
|
|
93
|
+
const items = await this.mutateBulk([data], options);
|
|
94
|
+
return items[0];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async mutateBulk<T extends IModelMutateOptions<TRecord>>(items: Partial<TRecord>[], options?: T): Promise<Partial<TRecord>[]> {
|
|
98
|
+
return await this.__mutateBulk_raw(undefined, items, options);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async __mutateBulk_raw(
|
|
102
|
+
table: keyof ITableRecord | undefined,
|
|
103
|
+
items: Partial<TRecord>[],
|
|
104
|
+
options?: IModelMutateOptions<TRecord>,
|
|
105
|
+
): Promise<TRecord[]> {
|
|
106
|
+
// table
|
|
107
|
+
table = table || this.getTable(items[0]);
|
|
108
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
109
|
+
// check
|
|
110
|
+
const indexesInsert: number[] = [];
|
|
111
|
+
const indexesUpdate: number[] = [];
|
|
112
|
+
const indexesDelete: number[] = [];
|
|
113
|
+
const itemsInsert: Partial<TRecord>[] = [];
|
|
114
|
+
const itemsUpdate: Partial<TRecord>[] = [];
|
|
115
|
+
const itemsDelete: Partial<TRecord>[] = [];
|
|
116
|
+
for (let index = 0; index < items.length; index++) {
|
|
117
|
+
const item = items[index];
|
|
118
|
+
if (cast(item).deleted) {
|
|
119
|
+
if (!isNil(cast(item).id)) {
|
|
120
|
+
itemsDelete.push(item);
|
|
121
|
+
indexesDelete.push(index);
|
|
122
|
+
} else {
|
|
123
|
+
// donothing, rather than throw error
|
|
124
|
+
}
|
|
125
|
+
} else if (!isNil(cast(item).id)) {
|
|
126
|
+
itemsUpdate.push(item);
|
|
127
|
+
indexesUpdate.push(index);
|
|
128
|
+
} else {
|
|
129
|
+
itemsInsert.push(item);
|
|
130
|
+
indexesInsert.push(index);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// insert/update
|
|
134
|
+
const itemsInsertNew = await this.__insertBulk_raw(table, itemsInsert, options);
|
|
135
|
+
await this.__updateBulk_raw(table, itemsUpdate, options);
|
|
136
|
+
const itemsMutate = itemsInsert
|
|
137
|
+
.map((item, index) => {
|
|
138
|
+
return Object.assign({}, item, { id: cast(itemsInsertNew[index]).id });
|
|
139
|
+
})
|
|
140
|
+
.concat(itemsUpdate as any);
|
|
141
|
+
let itemsMutateResult = itemsInsertNew.concat(itemsUpdate as any);
|
|
142
|
+
const indexesMutate = indexesInsert.concat(indexesUpdate);
|
|
143
|
+
itemsMutateResult = await this.relations.handleRelationsMutate(itemsMutateResult, itemsMutate as any, options as any, options);
|
|
144
|
+
let result: TRecord[] = [];
|
|
145
|
+
for (let index = 0; index < indexesMutate.length; index++) {
|
|
146
|
+
result[indexesMutate[index]] = itemsMutateResult[index] as any;
|
|
147
|
+
}
|
|
148
|
+
result = result.filter(item => !!item); // fitler deleted items
|
|
149
|
+
// delete
|
|
150
|
+
const idsDelete = itemsDelete.map(item => cast(item).id);
|
|
151
|
+
await this.__deleteBulk_raw_with_relations(table, idsDelete, options);
|
|
152
|
+
// ok
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async mget<T extends IModelGetOptions<TRecord>>(ids: TableIdentity[], options?: T): Promise<Partial<TRecord>[]> {
|
|
157
|
+
if (ids.length === 0) return [];
|
|
158
|
+
const relations = this.relations.handleRelationsCollection(options as any);
|
|
159
|
+
const [options2, refKeys] = this.relations.prepareColumnsByRelations(relations, options);
|
|
160
|
+
let items = await this.__mget_raw(undefined, ids, options2);
|
|
161
|
+
if (items.length === 0) return items;
|
|
162
|
+
items = await this.relations.handleRelationsMany(relations, items, options as any, options);
|
|
163
|
+
if (refKeys) {
|
|
164
|
+
for (const item of items) {
|
|
165
|
+
for (const refKey of refKeys) {
|
|
166
|
+
delete item![refKey];
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return items;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private async __mget_raw(table: keyof ITableRecord | undefined, ids: TableIdentity[], options?: IModelGetOptions<TRecord>): Promise<TRecord[]> {
|
|
174
|
+
// table
|
|
175
|
+
table = table || this.getTable(undefined);
|
|
176
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
177
|
+
// check if cache
|
|
178
|
+
if (this._checkDisableCacheEntityByOptions(options)) {
|
|
179
|
+
return (await super._mget(table, ids, options)) as TRecord[];
|
|
180
|
+
}
|
|
181
|
+
// cache
|
|
182
|
+
const cache = this.cacheEntity.getInstance(table);
|
|
183
|
+
let items = await cache.mget(ids, {
|
|
184
|
+
mget: async ids => {
|
|
185
|
+
return await super._mget_original(table, ids, { disableDeleted: true });
|
|
186
|
+
},
|
|
187
|
+
db: this.db,
|
|
188
|
+
});
|
|
189
|
+
// filter disableDeleted
|
|
190
|
+
items = items.filter(item => {
|
|
191
|
+
if (!item) return false;
|
|
192
|
+
if (!this._checkIfEntityValidByDeleted(item, options)) return false;
|
|
193
|
+
return true;
|
|
194
|
+
});
|
|
195
|
+
return this.__filterMGetColumns(items, options?.columns);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async count<T extends IModelSelectCountParams<TRecord>, ModelJoins extends TypeModelsClassLikeGeneral | undefined>(
|
|
199
|
+
params?: T,
|
|
200
|
+
options?: IModelMethodOptions,
|
|
201
|
+
_modelJoins?: ModelJoins,
|
|
202
|
+
): Promise<string | undefined> {
|
|
203
|
+
const column = params?.column ?? '*';
|
|
204
|
+
const params2 = Object.assign({}, params, { aggrs: { count: column }, column: undefined });
|
|
205
|
+
const item = await this.aggregate(params2, options);
|
|
206
|
+
return this.extractFirstValue(item);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async increment<T extends IModelIncrementParams<TRecord>, ModelJoins extends TypeModelsClassLikeGeneral | undefined>(
|
|
210
|
+
params: T,
|
|
211
|
+
options?: IModelMethodOptions,
|
|
212
|
+
_modelJoins?: ModelJoins,
|
|
213
|
+
): Promise<number> {
|
|
214
|
+
return await this.__increment_raw(undefined, params, options);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async decrement<T extends IModelIncrementParams<TRecord>, ModelJoins extends TypeModelsClassLikeGeneral | undefined>(
|
|
218
|
+
params: T,
|
|
219
|
+
options?: IModelMethodOptions,
|
|
220
|
+
_modelJoins?: ModelJoins,
|
|
221
|
+
): Promise<number> {
|
|
222
|
+
const columns = {} as TypeModelIncrementParamsColumns<TRecord>;
|
|
223
|
+
for (const key in params.columns) {
|
|
224
|
+
columns[key] = -params.columns[key]!;
|
|
225
|
+
}
|
|
226
|
+
const params2 = Object.assign({}, params, { columns });
|
|
227
|
+
return await this.__increment_raw(undefined, params2, options);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private async __increment_raw(
|
|
231
|
+
table: keyof ITableRecord | undefined,
|
|
232
|
+
params?: IModelIncrementParams<TRecord>,
|
|
233
|
+
options?: IModelMethodOptions,
|
|
234
|
+
): Promise<number> {
|
|
235
|
+
// table
|
|
236
|
+
table = table || this.getTable(params?.where);
|
|
237
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
238
|
+
// check if cache
|
|
239
|
+
if (this._checkDisableCacheEntityByOptions(options)) {
|
|
240
|
+
return await super._increment(table, params, options);
|
|
241
|
+
}
|
|
242
|
+
const where = params?.where;
|
|
243
|
+
const items = await this.__select_raw(table, { where, columns: ['id'] as any }, options);
|
|
244
|
+
if (items.length === 0) {
|
|
245
|
+
// donothing
|
|
246
|
+
return 0;
|
|
247
|
+
}
|
|
248
|
+
let id;
|
|
249
|
+
if (items.length === 1) {
|
|
250
|
+
id = cast(items[0]).id;
|
|
251
|
+
} else {
|
|
252
|
+
id = items.map(item => cast(item).id);
|
|
253
|
+
}
|
|
254
|
+
// update by id/ids
|
|
255
|
+
params = Object.assign({}, params, { where: { id } });
|
|
256
|
+
const res = await this._increment(table, params, options);
|
|
257
|
+
// delete cache
|
|
258
|
+
await this.cacheEntityDel(id, table);
|
|
259
|
+
return res;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async aggregate<T extends IModelSelectAggrParams<TRecord>, ModelJoins extends TypeModelsClassLikeGeneral | undefined>(
|
|
263
|
+
params?: T,
|
|
264
|
+
options?: IModelMethodOptions,
|
|
265
|
+
_modelJoins?: ModelJoins,
|
|
266
|
+
): Promise<TypeModelAggrRelationResult<T>> {
|
|
267
|
+
const items = await this.__aggregate_raw(undefined, params, options);
|
|
268
|
+
return items[0] as any;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private async __aggregate_raw(
|
|
272
|
+
table: keyof ITableRecord | undefined,
|
|
273
|
+
params?: IModelSelectParams<TRecord>,
|
|
274
|
+
options?: IModelMethodOptions,
|
|
275
|
+
): Promise<TRecord[]> {
|
|
276
|
+
// table
|
|
277
|
+
table = table || this.getTable(params?.where);
|
|
278
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
279
|
+
const items = await this.__select_cache(table, params, options);
|
|
280
|
+
return items;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async group<T extends IModelSelectGroupParams<TRecord>, ModelJoins extends TypeModelsClassLikeGeneral | undefined>(
|
|
284
|
+
params?: T,
|
|
285
|
+
options?: IModelMethodOptions,
|
|
286
|
+
_modelJoins?: ModelJoins,
|
|
287
|
+
): Promise<TypeModelGroupRelationResult<TRecord, T>[]> {
|
|
288
|
+
return (await this.__group_raw(undefined, params, options)) as any;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private async __group_raw(
|
|
292
|
+
table: keyof ITableRecord | undefined,
|
|
293
|
+
params?: IModelSelectGroupParams<TRecord>,
|
|
294
|
+
options?: IModelMethodOptions,
|
|
295
|
+
): Promise<TRecord[]> {
|
|
296
|
+
// table
|
|
297
|
+
table = table || this.getTable(params?.where);
|
|
298
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
299
|
+
const items = await this.__select_cache(table, params as any, options);
|
|
300
|
+
return items;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
async selectAndCount<T extends IModelSelectParams<TRecord>, ModelJoins extends TypeModelsClassLikeGeneral | undefined>(
|
|
304
|
+
params?: T,
|
|
305
|
+
options?: IModelMethodOptions,
|
|
306
|
+
modelJoins?: ModelJoins,
|
|
307
|
+
): Promise<any> {
|
|
308
|
+
// pageNo/pageSize
|
|
309
|
+
const pageSize = params?.limit ?? this.scopeOrm.config.rest.query.pageSize.default;
|
|
310
|
+
const pageNo = Math.floor((params?.offset ?? 0) / pageSize) + 1;
|
|
311
|
+
// count
|
|
312
|
+
const paramsCount = Object.assign({}, params, { columns: undefined, orders: undefined, limit: undefined, offset: undefined });
|
|
313
|
+
let count = await this.count(paramsCount, options, modelJoins);
|
|
314
|
+
if (!count) count = '0';
|
|
315
|
+
// list
|
|
316
|
+
let list;
|
|
317
|
+
if (count === '0') {
|
|
318
|
+
list = [];
|
|
319
|
+
} else {
|
|
320
|
+
list = await this.select(params, options, modelJoins);
|
|
321
|
+
}
|
|
322
|
+
// pageNo/pageSize/pageCount
|
|
323
|
+
const pageCount = Math.ceil(BigNumber(count).div(pageSize).toNumber());
|
|
324
|
+
// ok
|
|
325
|
+
return { list, total: count, pageCount, pageSize, pageNo };
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async select<T extends IModelSelectParams<TRecord>, ModelJoins extends TypeModelsClassLikeGeneral | undefined>(
|
|
329
|
+
params?: T,
|
|
330
|
+
options?: IModelMethodOptions,
|
|
331
|
+
_modelJoins?: ModelJoins,
|
|
332
|
+
): Promise<any[]> {
|
|
333
|
+
const relations = this.relations.handleRelationsCollection(params as any);
|
|
334
|
+
const [params2, refKeys] = this.relations.prepareColumnsByRelations(relations, params);
|
|
335
|
+
let items = await this.__select_raw(undefined, params2, options);
|
|
336
|
+
if (items.length === 0) return items;
|
|
337
|
+
items = await this.relations.handleRelationsMany(relations, items, params as any, options);
|
|
338
|
+
if (refKeys) {
|
|
339
|
+
for (const item of items) {
|
|
340
|
+
for (const refKey of refKeys) {
|
|
341
|
+
delete item![refKey];
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return items;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
private async __select_raw(
|
|
349
|
+
table: keyof ITableRecord | undefined,
|
|
350
|
+
params?: IModelSelectParams<TRecord>,
|
|
351
|
+
options?: IModelMethodOptions,
|
|
352
|
+
): Promise<TRecord[]> {
|
|
353
|
+
// table
|
|
354
|
+
table = table || this.getTable(params?.where);
|
|
355
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
356
|
+
// check if cache
|
|
357
|
+
if (this._checkDisableCacheEntityByOptions(options)) {
|
|
358
|
+
return await this.__select_cache(table, params, options);
|
|
359
|
+
}
|
|
360
|
+
// 1: select id
|
|
361
|
+
const columnId = `${table}.id`;
|
|
362
|
+
const params2: IModelSelectParams<TRecord> = Object.assign({}, params, { columns: [columnId] });
|
|
363
|
+
const items = await this.__select_cache(table, params2, options);
|
|
364
|
+
if (items.length === 0) {
|
|
365
|
+
// donothing
|
|
366
|
+
return [] as TRecord[];
|
|
367
|
+
}
|
|
368
|
+
// 1: special check
|
|
369
|
+
if (params?.columns) {
|
|
370
|
+
const columnsTarget = Array.isArray(params?.columns) ? params?.columns : [params?.columns];
|
|
371
|
+
if (this.__checkIfOnlyKey(columnsTarget as any, table)) {
|
|
372
|
+
// just return
|
|
373
|
+
return items;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
// 2: mget
|
|
377
|
+
const ids = items.map(item => cast(item).id);
|
|
378
|
+
const options3 = params?.columns ? Object.assign({}, options, { columns: params?.columns }) : options;
|
|
379
|
+
return await this.__mget_raw(table, ids, options3);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
private async __select_cache(table: keyof ITableRecord, params?: IModelSelectParams<TRecord>, options?: IModelMethodOptions): Promise<TRecord[]> {
|
|
383
|
+
// check if cache
|
|
384
|
+
if (this._checkDisableCacheQueryByOptions(options)) {
|
|
385
|
+
return await super._select(table, params, options);
|
|
386
|
+
}
|
|
387
|
+
// builder
|
|
388
|
+
const builder = this._select_buildParams(table, params as any, options);
|
|
389
|
+
const sql = builder.toQuery();
|
|
390
|
+
const key = { sql };
|
|
391
|
+
// cache
|
|
392
|
+
const cache = this.cacheQuery.getInstance(table);
|
|
393
|
+
const items = await cache.get(key, {
|
|
394
|
+
...options?.cache,
|
|
395
|
+
get: async () => {
|
|
396
|
+
return await super._select(table, params, options, builder);
|
|
397
|
+
},
|
|
398
|
+
db: this.db,
|
|
399
|
+
});
|
|
400
|
+
return items;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
async get<T extends IModelGetOptions<TRecord>>(where: TypeModelWhere<TRecord>, options?: T): Promise<Partial<TRecord> | undefined> {
|
|
404
|
+
const relations = this.relations.handleRelationsCollection(options);
|
|
405
|
+
const [options2, refKeys] = this.relations.prepareColumnsByRelations(relations, options);
|
|
406
|
+
let item: TRecord | undefined = await this.__get_raw(undefined, where, options2);
|
|
407
|
+
if (!item) return item;
|
|
408
|
+
item = await this.relations.handleRelationsOne(relations, item, options as any, options);
|
|
409
|
+
if (refKeys) {
|
|
410
|
+
for (const refKey of refKeys) {
|
|
411
|
+
delete item![refKey];
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return item;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
private async __get_raw(
|
|
418
|
+
table: keyof ITableRecord | undefined,
|
|
419
|
+
where: TypeModelWhere<TRecord>,
|
|
420
|
+
options?: IModelGetOptions<TRecord>,
|
|
421
|
+
): Promise<TRecord | undefined> {
|
|
422
|
+
// table
|
|
423
|
+
table = table || this.getTable(where);
|
|
424
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
425
|
+
// check if cache
|
|
426
|
+
if (this._checkDisableCacheEntityByOptions(options)) {
|
|
427
|
+
return await super._get(table, where, options);
|
|
428
|
+
}
|
|
429
|
+
const id = this.__checkCacheKeyValid(where, table);
|
|
430
|
+
if (isNil(id)) {
|
|
431
|
+
// not key
|
|
432
|
+
if (this._checkDisableCacheQueryByOptions(options)) {
|
|
433
|
+
return await super._get(table, where, options);
|
|
434
|
+
}
|
|
435
|
+
// by cache query
|
|
436
|
+
// params
|
|
437
|
+
const params: IModelSelectParams<TRecord> = { where };
|
|
438
|
+
if (options?.columns) {
|
|
439
|
+
params.columns = options?.columns as any;
|
|
440
|
+
}
|
|
441
|
+
// select
|
|
442
|
+
const options2 = deepExtend({}, options, { columns: undefined });
|
|
443
|
+
const items = await this.__select_raw(table, params, options2);
|
|
444
|
+
return items[0];
|
|
445
|
+
}
|
|
446
|
+
// key
|
|
447
|
+
return this.__filterGetColumns(await this.__get_key(id, table, where, options), options?.columns);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
async update<T extends IModelUpdateOptions<TRecord>>(data: Partial<TRecord>, options?: T): Promise<Partial<TRecord>> {
|
|
451
|
+
const ids = await this.__update_raw(undefined, data, options);
|
|
452
|
+
if (!ids || ids.length !== 1) return data;
|
|
453
|
+
// only support =1
|
|
454
|
+
const dataNew = [Object.assign({}, data, { id: ids[0] })];
|
|
455
|
+
const items = await this.relations.handleRelationsMutate(dataNew, dataNew, options as any, options);
|
|
456
|
+
return items[0];
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
async updateBulk<T extends IModelUpdateOptions<TRecord>>(items: Partial<TRecord>[], options?: T): Promise<Partial<TRecord>[]> {
|
|
460
|
+
await this.__updateBulk_raw(undefined, items, options);
|
|
461
|
+
return await this.relations.handleRelationsMutate(items, items, options as any, options);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
async __updateBulk_raw<T extends IModelUpdateOptions<TRecord>>(
|
|
465
|
+
table: keyof ITableRecord | undefined,
|
|
466
|
+
items: Partial<TRecord>[],
|
|
467
|
+
options?: T,
|
|
468
|
+
): Promise<void> {
|
|
469
|
+
if (items.length === 0) return;
|
|
470
|
+
for (const item of items) {
|
|
471
|
+
await this.__update_raw(table, item, options);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
async __update_raw(
|
|
476
|
+
table: keyof ITableRecord | undefined,
|
|
477
|
+
data: Partial<TRecord>,
|
|
478
|
+
options?: IModelUpdateOptions<TRecord>,
|
|
479
|
+
): Promise<TableIdentity[] | void> {
|
|
480
|
+
// table
|
|
481
|
+
table = table || this.getTable(data);
|
|
482
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
483
|
+
// check if cache
|
|
484
|
+
if (this._checkDisableCacheEntityByOptions(options)) {
|
|
485
|
+
await super._update(table, data, options);
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
// check where and get id
|
|
489
|
+
let id = this.__checkCacheKeyValid(data, table, true);
|
|
490
|
+
if (!options?.where) {
|
|
491
|
+
if (isNil(id)) {
|
|
492
|
+
throw new Error('id should be specified for update method');
|
|
493
|
+
}
|
|
494
|
+
if (Array.isArray(id) && id.length === 0) return;
|
|
495
|
+
const id2 = this.__checkCacheKeyValid(data, table, false);
|
|
496
|
+
if (!isNil(id2)) {
|
|
497
|
+
// donothing
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
} else {
|
|
501
|
+
const id2 = this.__checkCacheKeyValid(options?.where, table, false);
|
|
502
|
+
if (id2) {
|
|
503
|
+
id = id2;
|
|
504
|
+
} else {
|
|
505
|
+
const where = !isNil(id) ? Object.assign({}, options?.where, { id }) : options?.where;
|
|
506
|
+
const options2 = deepExtend({}, options, { where: undefined });
|
|
507
|
+
const items = await this.__select_raw(table, { where, columns: ['id'] as any }, options2);
|
|
508
|
+
if (items.length === 0) {
|
|
509
|
+
// donothing
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
if (items.length === 1) {
|
|
513
|
+
id = cast(items[0]).id;
|
|
514
|
+
} else {
|
|
515
|
+
id = items.map(item => cast(item).id);
|
|
516
|
+
}
|
|
517
|
+
// update by id/ids
|
|
518
|
+
options = Object.assign({}, options, { where: { id } });
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
await super._update(table, data, options);
|
|
522
|
+
// delete cache
|
|
523
|
+
await this.cacheEntityDel(id, table);
|
|
524
|
+
// id
|
|
525
|
+
return Array.isArray(id) ? id : [id];
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
async delete<T extends IModelDeleteOptions<TRecord>>(where?: TypeModelWhere<TRecord>, options?: T): Promise<void> {
|
|
529
|
+
const ids = await this.__delete_raw(undefined, where, options);
|
|
530
|
+
if (!isNil(ids)) {
|
|
531
|
+
await this.relations.handleRelationsDelete(ids as [], options as any, options);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
async deleteBulk<T extends IModelDeleteOptions<TRecord>>(ids: TableIdentity[], options?: T): Promise<void> {
|
|
536
|
+
return await this.__deleteBulk_raw_with_relations(undefined, ids, options);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
async __deleteBulk_raw_with_relations<T extends IModelDeleteOptions<TRecord>>(
|
|
540
|
+
table: keyof ITableRecord | undefined,
|
|
541
|
+
ids: TableIdentity[],
|
|
542
|
+
options?: T,
|
|
543
|
+
): Promise<void> {
|
|
544
|
+
if (ids.length === 0) return;
|
|
545
|
+
await this.__delete_raw(table, { id: ids } as any, options);
|
|
546
|
+
await this.relations.handleRelationsDelete(ids, options as any, options);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
async __delete_raw(
|
|
550
|
+
table: keyof ITableRecord | undefined,
|
|
551
|
+
where?: TypeModelWhere<TRecord>,
|
|
552
|
+
options?: IModelMethodOptions,
|
|
553
|
+
): Promise<TableIdentity[] | void> {
|
|
554
|
+
// table
|
|
555
|
+
table = table || this.getTable(where);
|
|
556
|
+
if (!table) return this.scopeOrm.error.ShouldSpecifyTable.throw();
|
|
557
|
+
// check if cache
|
|
558
|
+
if (this._checkDisableCacheEntityByOptions(options)) {
|
|
559
|
+
return await super._delete(table, where, options);
|
|
560
|
+
}
|
|
561
|
+
// id
|
|
562
|
+
let id = this.__checkCacheKeyValid(where, table);
|
|
563
|
+
if (isNil(id)) {
|
|
564
|
+
// check where and get id
|
|
565
|
+
const items = await this.__select_raw(table, { where, columns: ['id'] as any }, options);
|
|
566
|
+
if (items.length === 0) {
|
|
567
|
+
// donothing
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
if (items.length === 1) {
|
|
571
|
+
id = cast(items[0]).id;
|
|
572
|
+
} else {
|
|
573
|
+
id = items.map(item => cast(item).id);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
if (Array.isArray(id) && id.length === 0) return;
|
|
577
|
+
// delete by id/ids
|
|
578
|
+
await super._delete(table, { id } as any, options);
|
|
579
|
+
// delete cache
|
|
580
|
+
await this.cacheEntityDel(id, table);
|
|
581
|
+
// id
|
|
582
|
+
return Array.isArray(id) ? id : [id];
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
private async __get_key(
|
|
586
|
+
id: any,
|
|
587
|
+
table: keyof ITableRecord,
|
|
588
|
+
where: TypeModelWhere<TRecord>,
|
|
589
|
+
options?: IModelMethodOptions,
|
|
590
|
+
): Promise<TRecord | undefined> {
|
|
591
|
+
// cache
|
|
592
|
+
const cache = this.cacheEntity.getInstance(table);
|
|
593
|
+
const item: TRecord | undefined = await cache.get(id, {
|
|
594
|
+
get: async () => {
|
|
595
|
+
// where: maybe contain aux key
|
|
596
|
+
return await super._get(table, where, { disableDeleted: true });
|
|
597
|
+
},
|
|
598
|
+
db: this.db,
|
|
599
|
+
});
|
|
600
|
+
if (!item || !this._checkIfEntityValidByDeleted(item, options)) return undefined;
|
|
601
|
+
return item;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
private __filterMGetColumns(items: any[], columns?: TypeModelColumns<TRecord>) {
|
|
605
|
+
if (items.length === 0 || !columns) return items;
|
|
606
|
+
return items.map(item => {
|
|
607
|
+
return this.__filterGetColumns(item, columns);
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
private __filterGetColumns(data, columns?: TypeModelColumns<TRecord>) {
|
|
612
|
+
if (!data || !columns) return data;
|
|
613
|
+
if (!Array.isArray(columns)) columns = cast(columns).split(',');
|
|
614
|
+
const data2 = {};
|
|
615
|
+
for (let column of cast(columns)) {
|
|
616
|
+
column = getTargetColumnName(column);
|
|
617
|
+
if (column === '*') return data;
|
|
618
|
+
if (data[column] !== undefined) {
|
|
619
|
+
data2[column] = data[column];
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
return data2;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
public async cacheEntityDel(id: TableIdentity | TableIdentity[], table?: keyof ITableRecord) {
|
|
626
|
+
await this.cacheEntityDelInner(id, table);
|
|
627
|
+
this.db.commit(
|
|
628
|
+
async () => {
|
|
629
|
+
await this.cacheEntityDelInner(id, table);
|
|
630
|
+
},
|
|
631
|
+
{ ignoreIfNotInTransaction: true },
|
|
632
|
+
);
|
|
633
|
+
this._shardingCacheDoubleDelete({
|
|
634
|
+
beanFullName: this.$beanFullName,
|
|
635
|
+
clientName: this.db.clientName,
|
|
636
|
+
table,
|
|
637
|
+
method: 'cacheEntityDelInner',
|
|
638
|
+
args: [id, table],
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
public async cacheEntityDelInner(id: TableIdentity | TableIdentity[], table?: keyof ITableRecord) {
|
|
643
|
+
await this.cacheEntity.del(id, table);
|
|
644
|
+
await this.cacheQueryClearInner(table);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
public async cacheEntityClear(table?: keyof ITableRecord) {
|
|
648
|
+
await this.cacheEntityClearInner(table);
|
|
649
|
+
this.db.commit(
|
|
650
|
+
async () => {
|
|
651
|
+
await this.cacheEntityClearInner(table);
|
|
652
|
+
},
|
|
653
|
+
{ ignoreIfNotInTransaction: true },
|
|
654
|
+
);
|
|
655
|
+
this._shardingCacheDoubleDelete({
|
|
656
|
+
beanFullName: this.$beanFullName,
|
|
657
|
+
clientName: this.db.clientName,
|
|
658
|
+
table,
|
|
659
|
+
method: 'cacheEntityClearInner',
|
|
660
|
+
args: [table],
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
public async cacheEntityClearInner(table?: keyof ITableRecord) {
|
|
665
|
+
await this.cacheEntity.clear(table);
|
|
666
|
+
await this.cacheQueryClearInner(table);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
public async cacheQueryClear(table?: keyof ITableRecord) {
|
|
670
|
+
await this.cacheQueryClearInner(table);
|
|
671
|
+
this.db.commit(
|
|
672
|
+
async () => {
|
|
673
|
+
await this.cacheQueryClearInner(table);
|
|
674
|
+
},
|
|
675
|
+
{ ignoreIfNotInTransaction: true },
|
|
676
|
+
);
|
|
677
|
+
this._shardingCacheDoubleDelete({
|
|
678
|
+
beanFullName: this.$beanFullName,
|
|
679
|
+
clientName: this.db.clientName,
|
|
680
|
+
table,
|
|
681
|
+
method: 'cacheQueryClearInner',
|
|
682
|
+
args: [table],
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
public async cacheQueryClearInner(table?: keyof ITableRecord) {
|
|
687
|
+
await this.cacheQuery.clear(table);
|
|
688
|
+
await this._cacheQueryClearModelsClear();
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
private _shardingCacheDoubleDelete(jobData: TypeQueueDoubleDeleteJobData) {
|
|
692
|
+
const doubleDelete = this.scopeOrm.config.sharding.cache.doubleDelete;
|
|
693
|
+
if (!doubleDelete) return;
|
|
694
|
+
this.db.commit(() => {
|
|
695
|
+
this.scopeOrm.queue.doubleDelete.push(jobData);
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
private async _cacheQueryClearModelsClear() {
|
|
700
|
+
const modelsClear = this._getModelsClear();
|
|
701
|
+
if (!modelsClear || modelsClear.length === 0) return;
|
|
702
|
+
for (const modelClear of modelsClear) {
|
|
703
|
+
const modelTarget = this.newInstanceTarget(modelClear as any) as typeof this;
|
|
704
|
+
const modelsClearedByFn = modelTarget.options.cache?.modelsClearedByFn;
|
|
705
|
+
if (modelsClearedByFn) {
|
|
706
|
+
await modelsClearedByFn(this.ctx, modelTarget, this);
|
|
707
|
+
} else {
|
|
708
|
+
await modelTarget.cacheQueryClearInner();
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
private _getModelsClear(modelName?: keyof IModelRecord): TypeModelClassLikeGeneral[] {
|
|
714
|
+
const modelsClearAll = getCacheModelsClear(this.app);
|
|
715
|
+
return modelsClearAll[modelName ?? this.$onionName];
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
protected _checkDisableCacheQueryByOptions(options?: IModelMethodOptionsGeneral) {
|
|
719
|
+
if (options?.disableCacheQuery === true || options?.disableCacheQuery === false) {
|
|
720
|
+
return options?.disableCacheQuery;
|
|
721
|
+
}
|
|
722
|
+
return !(options?.cache?.enable ?? this.cacheQuery.enabled);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
protected _checkDisableCacheEntityByOptions(options?: IModelMethodOptionsGeneral) {
|
|
726
|
+
if (options?.disableCacheEntity === true || options?.disableCacheEntity === false) {
|
|
727
|
+
return options?.disableCacheEntity;
|
|
728
|
+
}
|
|
729
|
+
return !(options?.cache?.enable ?? this.cacheEntity.enabled);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
private __checkIfOnlyKey(keys: (string | TypeModelColumn<TRecord>)[], table: keyof ITableRecord, noCheckLength?: boolean): string | false {
|
|
733
|
+
const columnId = `${table}.id`;
|
|
734
|
+
if (!noCheckLength) {
|
|
735
|
+
const keysAux = this.cacheEntity.keysAux;
|
|
736
|
+
if (keysAux) {
|
|
737
|
+
const keysAux2 = Array.isArray(keysAux) ? keysAux : [keysAux];
|
|
738
|
+
keys = keys.filter(item => !keysAux2.includes(String(item)));
|
|
739
|
+
}
|
|
740
|
+
if (keys.length !== 1) return false;
|
|
741
|
+
if (keys[0] === 'id') return 'id';
|
|
742
|
+
if (keys[0] === columnId) return columnId;
|
|
743
|
+
return false;
|
|
744
|
+
} else {
|
|
745
|
+
if (keys.includes('id')) return 'id';
|
|
746
|
+
if (keys.includes(columnId)) return columnId;
|
|
747
|
+
return false;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
private __checkCacheKeyValid(where: {} | undefined, table: keyof ITableRecord, noCheckLength?: boolean) {
|
|
752
|
+
if (!where) return undefined;
|
|
753
|
+
const columnId = this.__checkIfOnlyKey(Object.keys(where), table, noCheckLength);
|
|
754
|
+
if (!columnId) return undefined;
|
|
755
|
+
return ['number', 'string', 'bigint', 'array'].includes(typeof where[columnId]) ? where[columnId] : undefined;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
protected __get__(prop: string) {
|
|
759
|
+
if (prop.startsWith('getBy')) {
|
|
760
|
+
const [fieldName, op] = __parseMagicField(prop.substring('getBy'.length));
|
|
761
|
+
if (!fieldName) throw new Error(`invalid magic method: ${prop}`);
|
|
762
|
+
return (fieldValue?: any, options?: any) => {
|
|
763
|
+
const where = __combineMagicWhere(fieldName, op!, fieldValue);
|
|
764
|
+
return this.get(where as any, options);
|
|
765
|
+
};
|
|
766
|
+
} else if (prop.startsWith('selectBy')) {
|
|
767
|
+
const [fieldName, op] = __parseMagicField(prop.substring('selectBy'.length));
|
|
768
|
+
if (!fieldName) throw new Error(`invalid magic method: ${prop}`);
|
|
769
|
+
return (fieldValue?: any, params?: any, options?: any, modelJoins?: any) => {
|
|
770
|
+
const where = __combineMagicWhere(fieldName, op!, fieldValue);
|
|
771
|
+
const params2 = params ? deepExtend({}, params, { where }) : { where };
|
|
772
|
+
return this.select(params2, options, modelJoins);
|
|
773
|
+
};
|
|
774
|
+
} else if (prop.startsWith('updateBy')) {
|
|
775
|
+
const [fieldName, op] = __parseMagicField(prop.substring('updateBy'.length));
|
|
776
|
+
if (!fieldName) throw new Error(`invalid magic method: ${prop}`);
|
|
777
|
+
return (fieldValue: any, data: any, options?: any) => {
|
|
778
|
+
const where = __combineMagicWhere(fieldName, op!, fieldValue);
|
|
779
|
+
if (fieldName === 'id') {
|
|
780
|
+
data = Object.assign({}, data, where);
|
|
781
|
+
} else {
|
|
782
|
+
options = deepExtend({}, options, { where });
|
|
783
|
+
}
|
|
784
|
+
return this.update(data, options);
|
|
785
|
+
};
|
|
786
|
+
} else if (prop.startsWith('deleteBy')) {
|
|
787
|
+
const [fieldName, op] = __parseMagicField(prop.substring('deleteBy'.length));
|
|
788
|
+
if (!fieldName) throw new Error(`invalid magic method: ${prop}`);
|
|
789
|
+
return (fieldValue: any, options?: any) => {
|
|
790
|
+
const where = __combineMagicWhere(fieldName, op!, fieldValue);
|
|
791
|
+
return this.delete(where as any, options);
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
function __combineMagicWhere(fieldName: string, op: string, fieldValue?: any) {
|
|
798
|
+
return {
|
|
799
|
+
[fieldName]:
|
|
800
|
+
fieldValue === undefined
|
|
801
|
+
? undefined
|
|
802
|
+
: op === 'eq'
|
|
803
|
+
? fieldValue
|
|
804
|
+
: {
|
|
805
|
+
[`_${op}_`]: fieldValue,
|
|
806
|
+
},
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
function __parseMagicField(str: string) {
|
|
811
|
+
const fieldName = parseFirstWord(str, true);
|
|
812
|
+
if (!fieldName) return [fieldName, undefined];
|
|
813
|
+
const op = toLowerCaseFirstChar(str.substring(fieldName.length)) || 'eq';
|
|
814
|
+
return [fieldName, op];
|
|
815
|
+
}
|