42 lines
1.0 KiB
Go
42 lines
1.0 KiB
Go
|
|
package repository
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"fmt"
|
||
|
|
"strconv"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
redislib "gateway/internal/library/redis"
|
||
|
|
member "gateway/internal/model/member/domain"
|
||
|
|
domrepo "gateway/internal/model/member/domain/repository"
|
||
|
|
)
|
||
|
|
|
||
|
|
type uidGenerator struct {
|
||
|
|
redis *redislib.Client
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewRedisUIDGenerator allocates readable UIDs using Redis INCR.
|
||
|
|
func NewRedisUIDGenerator(rds *redislib.Client) domrepo.UIDGenerator {
|
||
|
|
return &uidGenerator{redis: rds}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (g *uidGenerator) Next(ctx context.Context, tenantID, uidPrefix string) (string, error) {
|
||
|
|
if tenantID == "" || uidPrefix == "" {
|
||
|
|
return "", fmt.Errorf("member: tenant_id and uid_prefix are required")
|
||
|
|
}
|
||
|
|
key := member.GetMemberSeqRedisKey(tenantID)
|
||
|
|
seq, err := g.redis.Zero().IncrCtx(ctx, key)
|
||
|
|
if err != nil {
|
||
|
|
return "", err
|
||
|
|
}
|
||
|
|
if seq == 1 {
|
||
|
|
seq, err = g.redis.Zero().IncrbyCtx(ctx, key, member.UIDSequenceStart-1)
|
||
|
|
if err != nil {
|
||
|
|
return "", err
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return strings.ToUpper(uidPrefix) + "-" + strconv.FormatInt(seq, 10), nil
|
||
|
|
}
|
||
|
|
|
||
|
|
var _ domrepo.UIDGenerator = (*uidGenerator)(nil)
|