2023-10-26 17:15:49 +08:00
|
|
|
|
package base
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2023-11-07 21:05:21 +08:00
|
|
|
|
"context"
|
|
|
|
|
|
"mayfly-go/pkg/contextx"
|
2023-10-26 17:15:49 +08:00
|
|
|
|
"mayfly-go/pkg/gormx"
|
2023-11-07 21:05:21 +08:00
|
|
|
|
"mayfly-go/pkg/model"
|
2024-01-05 22:16:38 +08:00
|
|
|
|
|
|
|
|
|
|
"gorm.io/gorm"
|
2023-10-26 17:15:49 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 基础repo接口
|
2023-11-07 21:05:21 +08:00
|
|
|
|
type Repo[T model.ModelI] interface {
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-01-05 08:55:34 +08:00
|
|
|
|
// GetModel 获取表的模型实例
|
|
|
|
|
|
GetModel() T
|
|
|
|
|
|
|
2023-10-26 17:15:49 +08:00
|
|
|
|
// 新增一个实体
|
2023-11-07 21:05:21 +08:00
|
|
|
|
Insert(ctx context.Context, e T) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 使用指定gorm db执行,主要用于事务执行
|
2023-11-07 21:05:21 +08:00
|
|
|
|
InsertWithDb(ctx context.Context, db *gorm.DB, e T) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 批量新增实体
|
2024-01-17 08:37:22 +00:00
|
|
|
|
BatchInsert(ctx context.Context, models []T) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 使用指定gorm db执行,主要用于事务执行
|
2024-01-17 08:37:22 +00:00
|
|
|
|
BatchInsertWithDb(ctx context.Context, db *gorm.DB, models []T) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 根据实体id更新实体信息
|
2024-01-05 08:55:34 +08:00
|
|
|
|
UpdateById(ctx context.Context, e T, columns ...string) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 使用指定gorm db执行,主要用于事务执行
|
2024-01-05 08:55:34 +08:00
|
|
|
|
UpdateByIdWithDb(ctx context.Context, db *gorm.DB, e T, columns ...string) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// UpdateByCond 更新满足条件的数据
|
|
|
|
|
|
// @param cond 条件
|
|
|
|
|
|
UpdateByCond(ctx context.Context, e T, cond any) error
|
2024-04-09 12:55:51 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// UpdateByCondWithDb 更新满足条件的数据
|
|
|
|
|
|
UpdateByCondWithDb(ctx context.Context, db *gorm.DB, e T, cond any) error
|
2024-04-09 12:55:51 +08:00
|
|
|
|
|
2024-01-07 21:46:25 +08:00
|
|
|
|
// 保存实体,实体IsCreate返回true则新增,否则更新
|
|
|
|
|
|
Save(ctx context.Context, e T) error
|
|
|
|
|
|
|
|
|
|
|
|
// 保存实体,实体IsCreate返回true则新增,否则更新。
|
|
|
|
|
|
// 使用指定gorm db执行,主要用于事务执行
|
|
|
|
|
|
SaveWithDb(ctx context.Context, db *gorm.DB, e T) error
|
|
|
|
|
|
|
2023-10-26 17:15:49 +08:00
|
|
|
|
// 根据实体主键删除实体
|
2023-11-07 21:05:21 +08:00
|
|
|
|
DeleteById(ctx context.Context, id uint64) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 使用指定gorm db执行,主要用于事务执行
|
2023-11-07 21:05:21 +08:00
|
|
|
|
DeleteByIdWithDb(ctx context.Context, db *gorm.DB, id uint64) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 根据实体条件,更新参数udpateFields指定字段
|
|
|
|
|
|
Updates(cond any, udpateFields map[string]any) error
|
|
|
|
|
|
|
|
|
|
|
|
// 根据实体条件删除实体
|
2023-11-07 21:05:21 +08:00
|
|
|
|
DeleteByCond(ctx context.Context, cond any) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 使用指定gorm db执行,主要用于事务执行
|
2023-11-07 21:05:21 +08:00
|
|
|
|
DeleteByCondWithDb(ctx context.Context, db *gorm.DB, cond any) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
|
|
|
|
|
// 根据实体id查询
|
|
|
|
|
|
GetById(e T, id uint64, cols ...string) error
|
|
|
|
|
|
|
|
|
|
|
|
// 根据实体id数组查询对应实体列表,并将响应结果映射至list
|
|
|
|
|
|
GetByIdIn(list any, ids []uint64, orderBy ...string) error
|
|
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// GetByCond 根据实体条件查询实体信息(单个结果集)
|
|
|
|
|
|
GetByCond(cond any) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// SelectByCond 根据实体条件查询数据映射至res
|
|
|
|
|
|
SelectByCond(cond any, res any) error
|
2024-04-09 12:55:51 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// PageByCond 根据查询条件分页查询
|
|
|
|
|
|
PageByCond(cond any, pageParam *model.PageParam, toModels any) (*model.PageResult[any], error)
|
2024-04-09 12:55:51 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// SelectBySql 根据sql语句查询数据
|
|
|
|
|
|
SelectBySql(sql string, res any, params ...any) error
|
2023-10-26 17:15:49 +08:00
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
// 根据指定条件统计model表的数量
|
2023-10-26 17:15:49 +08:00
|
|
|
|
CountByCond(cond any) int64
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 基础repo接口
|
2023-11-07 21:05:21 +08:00
|
|
|
|
type RepoImpl[T model.ModelI] struct {
|
2023-12-05 23:03:51 +08:00
|
|
|
|
M T // 模型实例
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-07 21:05:21 +08:00
|
|
|
|
func (br *RepoImpl[T]) Insert(ctx context.Context, e T) error {
|
2023-12-05 23:03:51 +08:00
|
|
|
|
if db := contextx.GetDb(ctx); db != nil {
|
|
|
|
|
|
return br.InsertWithDb(ctx, db, e)
|
|
|
|
|
|
}
|
2024-01-09 17:31:21 +08:00
|
|
|
|
return gormx.Insert(br.fillBaseInfo(ctx, e))
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-07 21:05:21 +08:00
|
|
|
|
func (br *RepoImpl[T]) InsertWithDb(ctx context.Context, db *gorm.DB, e T) error {
|
2024-01-09 17:31:21 +08:00
|
|
|
|
return gormx.InsertWithDb(db, br.fillBaseInfo(ctx, e))
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-17 08:37:22 +00:00
|
|
|
|
func (br *RepoImpl[T]) BatchInsert(ctx context.Context, es []T) error {
|
2023-12-05 23:03:51 +08:00
|
|
|
|
if db := contextx.GetDb(ctx); db != nil {
|
|
|
|
|
|
return br.BatchInsertWithDb(ctx, db, es)
|
|
|
|
|
|
}
|
2024-01-17 08:37:22 +00:00
|
|
|
|
for _, e := range es {
|
2024-01-09 17:31:21 +08:00
|
|
|
|
br.fillBaseInfo(ctx, e)
|
2023-11-07 21:05:21 +08:00
|
|
|
|
}
|
2024-01-11 11:35:51 +08:00
|
|
|
|
return gormx.BatchInsert[T](es)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 使用指定gorm db执行,主要用于事务执行
|
2024-01-17 08:37:22 +00:00
|
|
|
|
func (br *RepoImpl[T]) BatchInsertWithDb(ctx context.Context, db *gorm.DB, es []T) error {
|
|
|
|
|
|
for _, e := range es {
|
2024-01-09 17:31:21 +08:00
|
|
|
|
br.fillBaseInfo(ctx, e)
|
2023-11-07 21:05:21 +08:00
|
|
|
|
}
|
2024-01-11 11:35:51 +08:00
|
|
|
|
return gormx.BatchInsertWithDb[T](db, es)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-05 08:55:34 +08:00
|
|
|
|
func (br *RepoImpl[T]) UpdateById(ctx context.Context, e T, columns ...string) error {
|
2023-12-05 23:03:51 +08:00
|
|
|
|
if db := contextx.GetDb(ctx); db != nil {
|
2024-01-05 08:55:34 +08:00
|
|
|
|
return br.UpdateByIdWithDb(ctx, db, e, columns...)
|
2023-12-05 23:03:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-09 17:31:21 +08:00
|
|
|
|
return gormx.UpdateById(br.fillBaseInfo(ctx, e), columns...)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-05 08:55:34 +08:00
|
|
|
|
func (br *RepoImpl[T]) UpdateByIdWithDb(ctx context.Context, db *gorm.DB, e T, columns ...string) error {
|
2024-01-09 17:31:21 +08:00
|
|
|
|
return gormx.UpdateByIdWithDb(db, br.fillBaseInfo(ctx, e), columns...)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
func (br *RepoImpl[T]) UpdateByCond(ctx context.Context, e T, cond any) error {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
if db := contextx.GetDb(ctx); db != nil {
|
2024-04-28 23:45:57 +08:00
|
|
|
|
return br.UpdateByCondWithDb(ctx, db, e, cond)
|
2024-04-09 12:55:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
e = br.fillBaseInfo(ctx, e)
|
|
|
|
|
|
// model的主键值需为空,否则会带上主键条件
|
|
|
|
|
|
e.SetId(0)
|
2024-04-28 23:45:57 +08:00
|
|
|
|
return gormx.UpdateByCond(e, toQueryCond(cond))
|
2024-04-09 12:55:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
func (br *RepoImpl[T]) UpdateByCondWithDb(ctx context.Context, db *gorm.DB, e T, cond any) error {
|
2024-04-09 12:55:51 +08:00
|
|
|
|
e = br.fillBaseInfo(ctx, e)
|
|
|
|
|
|
// model的主键值需为空,否则会带上主键条件
|
|
|
|
|
|
e.SetId(0)
|
2024-04-28 23:45:57 +08:00
|
|
|
|
return gormx.UpdateByCondWithDb(db, br.fillBaseInfo(ctx, e), toQueryCond(cond))
|
2024-04-09 12:55:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-26 17:15:49 +08:00
|
|
|
|
func (br *RepoImpl[T]) Updates(cond any, udpateFields map[string]any) error {
|
2023-12-27 22:59:20 +08:00
|
|
|
|
return gormx.Updates(br.GetModel(), cond, udpateFields)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-07 21:46:25 +08:00
|
|
|
|
func (br *RepoImpl[T]) Save(ctx context.Context, e T) error {
|
|
|
|
|
|
if e.IsCreate() {
|
|
|
|
|
|
return br.Insert(ctx, e)
|
|
|
|
|
|
}
|
|
|
|
|
|
return br.UpdateById(ctx, e)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (br *RepoImpl[T]) SaveWithDb(ctx context.Context, db *gorm.DB, e T) error {
|
|
|
|
|
|
if e.IsCreate() {
|
|
|
|
|
|
return br.InsertWithDb(ctx, db, e)
|
|
|
|
|
|
}
|
|
|
|
|
|
return br.UpdateByIdWithDb(ctx, db, e)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-07 21:05:21 +08:00
|
|
|
|
func (br *RepoImpl[T]) DeleteById(ctx context.Context, id uint64) error {
|
2023-12-05 23:03:51 +08:00
|
|
|
|
if db := contextx.GetDb(ctx); db != nil {
|
|
|
|
|
|
return br.DeleteByIdWithDb(ctx, db, id)
|
|
|
|
|
|
}
|
2024-01-07 21:46:25 +08:00
|
|
|
|
return gormx.DeleteById(br.GetModel(), id)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-07 21:05:21 +08:00
|
|
|
|
func (br *RepoImpl[T]) DeleteByIdWithDb(ctx context.Context, db *gorm.DB, id uint64) error {
|
2024-04-28 23:45:57 +08:00
|
|
|
|
return gormx.DeleteByIdWithDb(db, br.GetModel(), id)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-07 21:05:21 +08:00
|
|
|
|
func (br *RepoImpl[T]) DeleteByCond(ctx context.Context, cond any) error {
|
2023-12-05 23:03:51 +08:00
|
|
|
|
if db := contextx.GetDb(ctx); db != nil {
|
|
|
|
|
|
return br.DeleteByCondWithDb(ctx, db, cond)
|
|
|
|
|
|
}
|
2024-04-28 23:45:57 +08:00
|
|
|
|
return gormx.DeleteByCond(br.GetModel(), toQueryCond(cond))
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-07 21:05:21 +08:00
|
|
|
|
func (br *RepoImpl[T]) DeleteByCondWithDb(ctx context.Context, db *gorm.DB, cond any) error {
|
2024-04-28 23:45:57 +08:00
|
|
|
|
return gormx.DeleteByCondWithDb(db, br.GetModel(), toQueryCond(cond))
|
2024-04-09 12:55:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-10-26 17:15:49 +08:00
|
|
|
|
func (br *RepoImpl[T]) GetById(e T, id uint64, cols ...string) error {
|
|
|
|
|
|
if err := gormx.GetById(e, id, cols...); err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (br *RepoImpl[T]) GetByIdIn(list any, ids []uint64, orderBy ...string) error {
|
2024-04-28 23:45:57 +08:00
|
|
|
|
return br.SelectByCond(model.NewCond().In(model.IdColumn, ids).OrderBy(orderBy...), list)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
func (br *RepoImpl[T]) GetByCond(cond any) error {
|
|
|
|
|
|
return gormx.GetByCond(br.GetModel(), toQueryCond(cond))
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
func (br *RepoImpl[T]) SelectByCond(cond any, res any) error {
|
|
|
|
|
|
return gormx.SelectByCond(br.GetModel(), toQueryCond(cond).Dest(res))
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
func (br *RepoImpl[T]) PageByCond(cond any, pageParam *model.PageParam, toModels any) (*model.PageResult[any], error) {
|
|
|
|
|
|
return gormx.PageByCond(br.GetModel(), toQueryCond(cond), pageParam, toModels)
|
2024-04-09 12:55:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-28 23:45:57 +08:00
|
|
|
|
func (br *RepoImpl[T]) SelectBySql(sql string, res any, params ...any) error {
|
|
|
|
|
|
return gormx.SelectBySql(sql, res, params...)
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (br *RepoImpl[T]) CountByCond(cond any) int64 {
|
2024-04-28 23:45:57 +08:00
|
|
|
|
return gormx.CountByCond(br.GetModel(), toQueryCond(cond))
|
2023-10-26 17:15:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-12-27 22:59:20 +08:00
|
|
|
|
// GetModel 获取表的模型实例
|
|
|
|
|
|
func (br *RepoImpl[T]) GetModel() T {
|
2024-01-07 21:46:25 +08:00
|
|
|
|
return br.M
|
2023-12-27 22:59:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-07 21:05:21 +08:00
|
|
|
|
// 从上下文获取登录账号信息,并赋值至实体
|
2024-01-09 17:31:21 +08:00
|
|
|
|
func (br *RepoImpl[T]) fillBaseInfo(ctx context.Context, e T) T {
|
2024-01-23 09:27:05 +08:00
|
|
|
|
// 默认使用数据库id策略, 若要改变则实体结构体自行覆盖FillBaseInfo方法。可参考 sys/entity.Resource
|
|
|
|
|
|
e.FillBaseInfo(model.IdGenTypeNone, contextx.GetLoginAccount(ctx))
|
2023-11-07 21:05:21 +08:00
|
|
|
|
return e
|
|
|
|
|
|
}
|
2024-04-28 23:45:57 +08:00
|
|
|
|
|
|
|
|
|
|
func toQueryCond(cond any) *model.QueryCond {
|
|
|
|
|
|
if qc, ok := cond.(*model.QueryCond); ok {
|
|
|
|
|
|
return qc
|
|
|
|
|
|
}
|
|
|
|
|
|
return model.NewModelCond(cond)
|
|
|
|
|
|
}
|