mirror of
https://github.com/ThisTine/Snip.git
synced 2026-08-18 23:18:47 +07:00
61 lines
1.2 KiB
Go
61 lines
1.2 KiB
Go
package memory
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"sync"
|
|
|
|
"github.com/snip/backend/internal/domain"
|
|
)
|
|
|
|
type UserRepo struct {
|
|
mu sync.RWMutex
|
|
byID map[string]*domain.User
|
|
byKey map[string]string // provider|subject -> id
|
|
}
|
|
|
|
func NewUserRepo() *UserRepo {
|
|
return &UserRepo{byID: make(map[string]*domain.User), byKey: make(map[string]string)}
|
|
}
|
|
|
|
func (r *UserRepo) Upsert(_ context.Context, u *domain.User) (*domain.User, error) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
key := u.Provider + "|" + u.Subject
|
|
if id, ok := r.byKey[key]; ok {
|
|
existing := r.byID[id]
|
|
existing.Email = u.Email
|
|
existing.Name = u.Name
|
|
cp := *existing
|
|
return &cp, nil
|
|
}
|
|
id := randomID()
|
|
u.ID = id
|
|
r.byID[id] = u
|
|
r.byKey[key] = id
|
|
cp := *u
|
|
return &cp, nil
|
|
}
|
|
|
|
func (r *UserRepo) GetByID(_ context.Context, id string) (*domain.User, error) {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
u, ok := r.byID[id]
|
|
if !ok {
|
|
return nil, domain.ErrNotFound
|
|
}
|
|
cp := *u
|
|
return &cp, nil
|
|
}
|
|
|
|
func randomID() string {
|
|
const hex = "0123456789abcdef"
|
|
b := make([]byte, 16)
|
|
_, _ = rand.Read(b)
|
|
out := make([]byte, 16)
|
|
for i := range out {
|
|
out[i] = hex[int(b[i])%16]
|
|
}
|
|
return "u_" + string(out)
|
|
}
|