thread-master/apps/backend/internal/module/threads/repository/mongo.go

120 lines
2.9 KiB
Go

package repository
import (
"context"
"time"
libmongo "apps/backend/internal/lib/mongo"
"apps/backend/internal/module/threads/domain"
"github.com/zeromicro/go-zero/core/stores/mon"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
const (
colAccounts = "threads_accounts"
colStates = "threads_oauth_states"
)
// MonStore uses go-zero mon (no entity cache for tokens).
type MonStore struct {
accounts *mon.Model
states *mon.Model
}
func NewMonStore(uri, database string) *MonStore {
uri = libmongo.MustMongoURI(uri)
return &MonStore{
accounts: mon.MustNewModel(uri, database, colAccounts),
states: mon.MustNewModel(uri, database, colStates),
}
}
func (s *MonStore) Insert(ctx context.Context, a *domain.Account) error {
_, err := s.accounts.InsertOne(ctx, a)
return err
}
func (s *MonStore) Update(ctx context.Context, a *domain.Account) error {
a.UpdatedAt = domain.NowNano()
res, err := s.accounts.ReplaceOne(ctx, bson.M{"_id": a.ID}, a)
if err != nil {
return err
}
if res.MatchedCount == 0 {
return domain.ErrNotFound
}
return nil
}
func (s *MonStore) FindByID(ctx context.Context, id string) (*domain.Account, error) {
var a domain.Account
err := s.accounts.FindOne(ctx, &a, bson.M{"_id": id})
if err != nil {
if err == mon.ErrNotFound {
return nil, domain.ErrNotFound
}
return nil, err
}
return &a, nil
}
func (s *MonStore) FindByOwnerAndThreadsUser(ctx context.Context, ownerUID int64, threadsUserID string) (*domain.Account, error) {
if threadsUserID == "" {
return nil, domain.ErrNotFound
}
var a domain.Account
err := s.accounts.FindOne(ctx, &a, bson.M{"owner_uid": ownerUID, "threads_user_id": threadsUserID})
if err != nil {
if err == mon.ErrNotFound {
return nil, domain.ErrNotFound
}
return nil, err
}
return &a, nil
}
func (s *MonStore) ListByOwner(ctx context.Context, ownerUID int64) ([]*domain.Account, error) {
var list []*domain.Account
err := s.accounts.Find(ctx, &list, bson.M{"owner_uid": ownerUID},
options.Find().SetSort(bson.D{{Key: "created_at", Value: -1}}))
if err != nil {
return nil, err
}
return list, nil
}
func (s *MonStore) Delete(ctx context.Context, id string) error {
res, err := s.accounts.DeleteOne(ctx, bson.M{"_id": id})
if err != nil {
return err
}
if res == 0 {
return domain.ErrNotFound
}
return nil
}
func (s *MonStore) SaveState(ctx context.Context, st *domain.OAuthState) error {
_, err := s.states.InsertOne(ctx, st)
return err
}
func (s *MonStore) TakeState(ctx context.Context, state string) (*domain.OAuthState, error) {
var st domain.OAuthState
err := s.states.FindOneAndDelete(ctx, &st, bson.M{"_id": state})
if err != nil {
if err == mon.ErrNotFound {
return nil, domain.ErrInvalidState
}
return nil, err
}
if st.ExpiresAt > 0 && time.Now().UTC().UnixNano() > st.ExpiresAt {
return nil, domain.ErrInvalidState
}
return &st, nil
}
var _ domain.Repository = (*MonStore)(nil)