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
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
|
|
}
|