You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
1.2 KiB
Go

package hashid
import (
"context"
"joybuywork/internal/app"
"joybuywork/internal/consts/ckey"
"fmt"
"gorm.io/gen/field"
"time"
)
type IDbId interface {
TableName() string
GetFieldByName(fieldName string) (field.OrderExpr, bool)
}
// IncrDbId 借助redis来做自增主键
func IncrDbId(ctx context.Context, table IDbId, pks ...string) (id int64, err error) {
key := fmt.Sprintf("joybuywork:dbid:%s", table.TableName())
defer func() {
if err != nil {
return
}
id, err = app.Redis.Incr(ctx, key)
}()
exist, _ := app.Redis.Exists(ctx, key)
if exist {
return
}
lc := app.NewFollower(ctx, ckey.ForLock(key)).Lock()
defer lc.Release()
if lc.Error() != nil {
err = lc.Error()
return
}
exist, _ = app.Redis.Exists(ctx, key)
if exist {
return
}
var MaxId struct {
Id int64 `json:"id"`
}
var pkField = "id"
for _, pk := range pks {
_, ok := table.GetFieldByName(pk)
if ok {
pkField = pk
break
}
}
err = app.DB.Client.WithContext(ctx).Table(table.TableName()).Select(fmt.Sprintf("MAX(%s) as id", pkField)).Scan(&MaxId).Error
if err != nil {
return
}
err = app.Redis.Cache.IncrBy(ctx, key, MaxId.Id).Err()
app.Redis.Cache.ExpireAt(ctx, key, time.Now().AddDate(0, 6, 0))
return
}