2023-10-26 17:15:49 +08:00
|
|
|
|
package base
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2023-11-07 21:05:21 +08:00
|
|
|
|
"context"
|
2023-12-05 23:03:51 +08:00
|
|
|
|
"fmt"
|
|
|
|
|
|
"mayfly-go/pkg/contextx"
|
|
|
|
|
|
"mayfly-go/pkg/global"
|
2023-11-07 21:05:21 +08:00
|
|
|
|
"mayfly-go/pkg/model"
|
|
|
|
|
|
|
2023-10-26 17:15:49 +08:00
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 基础application接口
|
2023-11-07 21:05:21 +08:00
|
|
|
|
type App[T model.ModelI] interface {
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// Insert 新增一个实体
|
2023-11-07 21:05:21 +08:00
|
|
|
|
Insert(ctx context.Context, e T) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// BatchInsert 批量新增实体
|
2023-11-07 21:05:21 +08:00
|
|
|
|
BatchInsert(ctx context.Context, models []T) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// UpdateById 根据实体id更新实体信息
|
2023-11-07 21:05:21 +08:00
|
|
|
|
UpdateById(ctx context.Context, e T) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// UpdateByCond 更新满足条件的数据
|
2024-04-29 12:29:56 +08:00
|
|
|
|
// @param values 需为模型结构体指针或map(更新零值等)
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// @param cond 可为*model.QueryCond也可以为普通查询model
|
2024-04-29 12:29:56 +08:00
|
|
|
|
UpdateByCond(ctx context.Context, values any, cond any) error
|
2024-04-09 12:55:51 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// DeleteById 根据实体主键删除实体
|
2024-04-29 12:29:56 +08:00
|
|
|
|
DeleteById(ctx context.Context, id ...uint64) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// DeleteByCond 根据条件进行删除
|
2024-05-05 14:53:30 +08:00
|
|
|
|
// @param cond 可为*model.QueryCond也可以为普通查询model
|
2024-04-28 23:45:57 +08:00
|
|
|
|
DeleteByCond(ctx context.Context, cond any) error
|
2024-04-09 12:55:51 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// Save 保存实体,实体IsCreate返回true则新增,否则更新
|
2024-01-07 21:46:25 +08:00
|
|
|
|
Save(ctx context.Context, e T) error
|
|
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// GetById 根据实体id查询
|
2024-05-05 14:53:30 +08:00
|
|
|
|
GetById(id uint64, cols ...string) (T, error)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-04-29 12:29:56 +08:00
|
|
|
|
// GetByIds 根据实体id数组查询
|
2024-05-05 14:53:30 +08:00
|
|
|
|
GetByIds(ids []uint64, cols ...string) ([]T, error)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// GetByCond 根据实体条件查询实体信息(获取单个实体)
|
2024-05-05 14:53:30 +08:00
|
|
|
|
// @param cond 可为*model.QueryCond也可以为普通查询model
|
2024-04-28 23:45:57 +08:00
|
|
|
|
GetByCond(cond any) error
|
2024-04-12 17:07:28 +08:00
|
|
|
|
|
2024-05-05 14:53:30 +08:00
|
|
|
|
// ListByCondToAny 根据条件查询数据映射至res
|
|
|
|
|
|
// @param cond 可为*model.QueryCond也可以为普通查询model
|
|
|
|
|
|
ListByCondToAny(cond any, res any) error
|
|
|
|
|
|
|
|
|
|
|
|
// ListByCond 根据条件查询
|
|
|
|
|
|
// @param cond 可为*model.QueryCond也可以为普通查询model
|
|
|
|
|
|
ListByCond(cond any, cols ...string) ([]T, error)
|
|
|
|
|
|
|
|
|
|
|
|
// PageByCondToAny 分页查询并绑定至指定toModels
|
|
|
|
|
|
// @param cond 可为*model.QueryCond也可以为普通查询model
|
|
|
|
|
|
PageByCondToAny(cond any, pageParam *model.PageParam, toModels any) (*model.PageResult[any], error)
|
2024-04-09 12:55:51 +08:00
|
|
|
|
|
2024-05-05 14:53:30 +08:00
|
|
|
|
// PageByCond 根据指定条件分页查询
|
|
|
|
|
|
// @param cond 可为*model.QueryCond也可以为普通查询model
|
|
|
|
|
|
PageByCond(cond any, pageParam *model.PageParam, cols ...string) (*model.PageResult[[]T], error)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// CountByCond 根据指定条件统计model表的数量
|
2024-05-05 14:53:30 +08:00
|
|
|
|
// @param cond 可为*model.QueryCond也可以为普通查询model
|
2023-10-26 17:15:49 +08:00
|
|
|
|
CountByCond(cond any) int64
|
2023-12-05 23:03:51 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// Tx 执行事务操作
|
2023-12-05 23:03:51 +08:00
|
|
|
|
Tx(ctx context.Context, funcs ...func(context.Context) error) (err error)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 基础application接口实现
|
2023-11-07 21:05:21 +08:00
|
|
|
|
type AppImpl[T model.ModelI, R Repo[T]] struct {
|
2023-10-26 17:15:49 +08:00
|
|
|
|
Repo R // repo接口
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取repo
|
|
|
|
|
|
func (ai *AppImpl[T, R]) GetRepo() R {
|
|
|
|
|
|
return ai.Repo
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 新增一个实体 (单纯新增,不做其他业务逻辑处理)
|
2023-11-07 21:05:21 +08:00
|
|
|
|
func (ai *AppImpl[T, R]) Insert(ctx context.Context, e T) error {
|
|
|
|
|
|
return ai.GetRepo().Insert(ctx, e)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 批量新增实体 (单纯新增,不做其他业务逻辑处理)
|
2023-11-07 21:05:21 +08:00
|
|
|
|
func (ai *AppImpl[T, R]) BatchInsert(ctx context.Context, es []T) error {
|
|
|
|
|
|
return ai.GetRepo().BatchInsert(ctx, es)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据实体id更新实体信息 (单纯更新,不做其他业务逻辑处理)
|
2023-11-07 21:05:21 +08:00
|
|
|
|
func (ai *AppImpl[T, R]) UpdateById(ctx context.Context, e T) error {
|
|
|
|
|
|
return ai.GetRepo().UpdateById(ctx, e)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-29 12:29:56 +08:00
|
|
|
|
// UpdateByCond 更新满足条件的数据
|
|
|
|
|
|
// @param values 需为模型结构体指针或map(更新零值等)
|
|
|
|
|
|
// @param cond 可为*model.QueryCond也可以为普通查询model
|
|
|
|
|
|
func (ai *AppImpl[T, R]) UpdateByCond(ctx context.Context, values any, cond any) error {
|
|
|
|
|
|
return ai.GetRepo().UpdateByCond(ctx, values, cond)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-07 21:46:25 +08:00
|
|
|
|
// 保存实体,实体IsCreate返回true则新增,否则更新
|
|
|
|
|
|
func (ai *AppImpl[T, R]) Save(ctx context.Context, e T) error {
|
|
|
|
|
|
return ai.GetRepo().Save(ctx, e)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 保存实体,实体IsCreate返回true则新增,否则更新。
|
|
|
|
|
|
// 使用指定gorm db执行,主要用于事务执行
|
|
|
|
|
|
func (ai *AppImpl[T, R]) SaveWithDb(ctx context.Context, db *gorm.DB, e T) error {
|
|
|
|
|
|
return ai.GetRepo().SaveWithDb(ctx, db, e)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-26 17:15:49 +08:00
|
|
|
|
// 根据实体主键删除实体 (单纯删除实体,不做其他业务逻辑处理)
|
2024-04-29 12:29:56 +08:00
|
|
|
|
func (ai *AppImpl[T, R]) DeleteById(ctx context.Context, id ...uint64) error {
|
|
|
|
|
|
return ai.GetRepo().DeleteById(ctx, id...)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据指定条件删除实体 (单纯删除实体,不做其他业务逻辑处理)
|
2023-11-07 21:05:21 +08:00
|
|
|
|
func (ai *AppImpl[T, R]) DeleteByCond(ctx context.Context, cond any) error {
|
|
|
|
|
|
return ai.GetRepo().DeleteByCond(ctx, cond)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据实体id查询
|
2024-05-05 14:53:30 +08:00
|
|
|
|
func (ai *AppImpl[T, R]) GetById(id uint64, cols ...string) (T, error) {
|
|
|
|
|
|
return ai.GetRepo().GetById(id, cols...)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-05 14:53:30 +08:00
|
|
|
|
func (ai *AppImpl[T, R]) GetByIds(ids []uint64, cols ...string) ([]T, error) {
|
|
|
|
|
|
return ai.GetRepo().GetByIds(ids, cols...)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据实体条件查询实体信息
|
2024-04-28 23:45:57 +08:00
|
|
|
|
func (ai *AppImpl[T, R]) GetByCond(cond any) error {
|
|
|
|
|
|
return ai.GetRepo().GetByCond(cond)
|
2024-04-12 17:07:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-05 14:53:30 +08:00
|
|
|
|
func (ai *AppImpl[T, R]) ListByCondToAny(cond any, res any) error {
|
|
|
|
|
|
return ai.GetRepo().SelectByCondToAny(cond, res)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (ai *AppImpl[T, R]) ListByCond(cond any, cols ...string) ([]T, error) {
|
|
|
|
|
|
return ai.GetRepo().SelectByCond(cond, cols...)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// PageByCondToAny 分页查询
|
|
|
|
|
|
func (ai *AppImpl[T, R]) PageByCondToAny(cond any, pageParam *model.PageParam, toModels any) (*model.PageResult[any], error) {
|
|
|
|
|
|
return ai.GetRepo().PageByCondToAny(cond, pageParam, toModels)
|
2024-04-09 12:55:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-05-05 14:53:30 +08:00
|
|
|
|
func (ai *AppImpl[T, R]) PageByCond(cond any, pageParam *model.PageParam, cols ...string) (*model.PageResult[[]T], error) {
|
|
|
|
|
|
return ai.GetRepo().PageByCond(cond, pageParam, cols...)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据指定条件统计model表的数量, cond为条件可以为map等
|
|
|
|
|
|
func (ai *AppImpl[T, R]) CountByCond(cond any) int64 {
|
|
|
|
|
|
return ai.GetRepo().CountByCond(cond)
|
|
|
|
|
|
}
|
2023-12-05 23:03:51 +08:00
|
|
|
|
|
2024-10-30 12:17:55 +08:00
|
|
|
|
// Tx 执行事务操作
|
2023-12-05 23:03:51 +08:00
|
|
|
|
func (ai *AppImpl[T, R]) Tx(ctx context.Context, funcs ...func(context.Context) error) (err error) {
|
2024-10-30 12:17:55 +08:00
|
|
|
|
tx := contextx.GetTx(ctx)
|
|
|
|
|
|
dbCtx := ctx
|
|
|
|
|
|
var txDb *gorm.DB
|
|
|
|
|
|
|
|
|
|
|
|
if tx == nil {
|
|
|
|
|
|
txDb = global.Db.Begin()
|
|
|
|
|
|
dbCtx, tx = contextx.WithTxDb(ctx, txDb)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
txDb = tx.DB
|
|
|
|
|
|
tx.Count++
|
|
|
|
|
|
}
|
2023-12-05 23:03:51 +08:00
|
|
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
|
|
if r := recover(); r != nil {
|
2024-10-30 12:17:55 +08:00
|
|
|
|
txDb.Rollback()
|
|
|
|
|
|
contextx.RmDb(ctx)
|
|
|
|
|
|
err = fmt.Errorf("%v", r)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tx.Count--
|
2024-10-30 19:59:45 +08:00
|
|
|
|
if tx.Count == 0 {
|
2024-10-30 12:17:55 +08:00
|
|
|
|
// 移除当前已执行完成的的数据库事务实例
|
|
|
|
|
|
contextx.RmDb(ctx)
|
2023-12-05 23:03:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
for _, f := range funcs {
|
|
|
|
|
|
err = f(dbCtx)
|
2024-10-30 19:59:45 +08:00
|
|
|
|
if err != nil && tx.Count > 0 {
|
|
|
|
|
|
tx.Count = 1
|
2024-10-30 12:17:55 +08:00
|
|
|
|
txDb.Rollback()
|
2023-12-05 23:03:51 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-10-30 12:17:55 +08:00
|
|
|
|
|
|
|
|
|
|
if tx.Count == 1 {
|
|
|
|
|
|
err = txDb.Commit().Error
|
|
|
|
|
|
}
|
2023-12-05 23:03:51 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|