116 lines
2.4 KiB
Go
116 lines
2.4 KiB
Go
|
|
package repository
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"sync"
|
||
|
|
|
||
|
|
"apps/backend/internal/module/threads/domain"
|
||
|
|
)
|
||
|
|
|
||
|
|
// MemoryStore for unit tests.
|
||
|
|
type MemoryStore struct {
|
||
|
|
mu sync.Mutex
|
||
|
|
byID map[string]*domain.Account
|
||
|
|
state map[string]*domain.OAuthState
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewMemory() *MemoryStore {
|
||
|
|
return &MemoryStore{
|
||
|
|
byID: map[string]*domain.Account{},
|
||
|
|
state: map[string]*domain.OAuthState{},
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *MemoryStore) Insert(_ context.Context, a *domain.Account) error {
|
||
|
|
s.mu.Lock()
|
||
|
|
defer s.mu.Unlock()
|
||
|
|
cp := *a
|
||
|
|
s.byID[a.ID] = &cp
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *MemoryStore) Update(_ context.Context, a *domain.Account) error {
|
||
|
|
s.mu.Lock()
|
||
|
|
defer s.mu.Unlock()
|
||
|
|
if _, ok := s.byID[a.ID]; !ok {
|
||
|
|
return domain.ErrNotFound
|
||
|
|
}
|
||
|
|
cp := *a
|
||
|
|
s.byID[a.ID] = &cp
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *MemoryStore) FindByID(_ context.Context, id string) (*domain.Account, error) {
|
||
|
|
s.mu.Lock()
|
||
|
|
defer s.mu.Unlock()
|
||
|
|
a, ok := s.byID[id]
|
||
|
|
if !ok {
|
||
|
|
return nil, domain.ErrNotFound
|
||
|
|
}
|
||
|
|
cp := *a
|
||
|
|
return &cp, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *MemoryStore) FindByOwnerAndThreadsUser(_ context.Context, ownerUID int64, threadsUserID string) (*domain.Account, error) {
|
||
|
|
s.mu.Lock()
|
||
|
|
defer s.mu.Unlock()
|
||
|
|
if threadsUserID == "" {
|
||
|
|
return nil, domain.ErrNotFound
|
||
|
|
}
|
||
|
|
for _, a := range s.byID {
|
||
|
|
if a.OwnerUID == ownerUID && a.ThreadsUserID == threadsUserID {
|
||
|
|
cp := *a
|
||
|
|
return &cp, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nil, domain.ErrNotFound
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *MemoryStore) ListByOwner(_ context.Context, ownerUID int64) ([]*domain.Account, error) {
|
||
|
|
s.mu.Lock()
|
||
|
|
defer s.mu.Unlock()
|
||
|
|
var out []*domain.Account
|
||
|
|
for _, a := range s.byID {
|
||
|
|
if a.OwnerUID == ownerUID {
|
||
|
|
cp := *a
|
||
|
|
out = append(out, &cp)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return out, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *MemoryStore) Delete(_ context.Context, id string) error {
|
||
|
|
s.mu.Lock()
|
||
|
|
defer s.mu.Unlock()
|
||
|
|
if _, ok := s.byID[id]; !ok {
|
||
|
|
return domain.ErrNotFound
|
||
|
|
}
|
||
|
|
delete(s.byID, id)
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *MemoryStore) SaveState(_ context.Context, st *domain.OAuthState) error {
|
||
|
|
s.mu.Lock()
|
||
|
|
defer s.mu.Unlock()
|
||
|
|
cp := *st
|
||
|
|
s.state[st.State] = &cp
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *MemoryStore) TakeState(_ context.Context, state string) (*domain.OAuthState, error) {
|
||
|
|
s.mu.Lock()
|
||
|
|
defer s.mu.Unlock()
|
||
|
|
st, ok := s.state[state]
|
||
|
|
if !ok {
|
||
|
|
return nil, domain.ErrInvalidState
|
||
|
|
}
|
||
|
|
delete(s.state, state)
|
||
|
|
if st.ExpiresAt > 0 && domain.NowNano() > st.ExpiresAt {
|
||
|
|
return nil, domain.ErrInvalidState
|
||
|
|
}
|
||
|
|
cp := *st
|
||
|
|
return &cp, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
var _ domain.Repository = (*MemoryStore)(nil)
|