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

227 lines
6.6 KiB
Go

package repository
import (
"context"
libmongo "apps/backend/internal/lib/mongo"
"apps/backend/internal/module/scout/domain"
"github.com/zeromicro/go-zero/core/stores/mon"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
type MonStore struct {
brands *mon.Model
products *mon.Model
active *mon.Model
posts *mon.Model
hw *mon.Model
crawler *mon.Model
}
func NewMonStore(uri, database string) *MonStore {
uri = libmongo.MustMongoURI(uri)
return &MonStore{
brands: mon.MustNewModel(uri, database, "scout_brands"),
products: mon.MustNewModel(uri, database, "scout_products"),
active: mon.MustNewModel(uri, database, "scout_active_brand"),
posts: mon.MustNewModel(uri, database, "scout_posts"),
hw: mon.MustNewModel(uri, database, "scout_homework"),
crawler: mon.MustNewModel(uri, database, "scout_crawler_session"),
}
}
func (s *MonStore) SaveBrand(ctx context.Context, b *domain.Brand) error {
_, err := s.brands.ReplaceOne(ctx, bson.M{"_id": b.ID}, b, options.Replace().SetUpsert(true))
return err
}
func (s *MonStore) GetBrand(ctx context.Context, id string) (*domain.Brand, error) {
var b domain.Brand
err := s.brands.FindOne(ctx, &b, bson.M{"_id": id})
if err != nil {
if err == mon.ErrNotFound {
return nil, domain.ErrNotFound
}
return nil, err
}
return &b, nil
}
func (s *MonStore) ListBrands(ctx context.Context, ownerUID int64) ([]*domain.Brand, error) {
var list []*domain.Brand
err := s.brands.Find(ctx, &list, bson.M{"owner_uid": ownerUID})
return list, err
}
func (s *MonStore) DeleteBrand(ctx context.Context, id string) error {
res, err := s.brands.DeleteOne(ctx, bson.M{"_id": id})
if err != nil {
return err
}
if res == 0 {
return domain.ErrNotFound
}
return nil
}
func (s *MonStore) SaveProduct(ctx context.Context, p *domain.Product) error {
_, err := s.products.ReplaceOne(ctx, bson.M{"_id": p.ID}, p, options.Replace().SetUpsert(true))
return err
}
func (s *MonStore) GetProduct(ctx context.Context, id string) (*domain.Product, error) {
var p domain.Product
err := s.products.FindOne(ctx, &p, bson.M{"_id": id})
if err != nil {
if err == mon.ErrNotFound {
return nil, domain.ErrNotFound
}
return nil, err
}
return &p, nil
}
func (s *MonStore) ListProducts(ctx context.Context, ownerUID int64, brandID string) ([]*domain.Product, error) {
filter := bson.M{"owner_uid": ownerUID}
if brandID != "" {
filter["brand_id"] = brandID
}
var list []*domain.Product
err := s.products.Find(ctx, &list, filter)
return list, err
}
func (s *MonStore) DeleteProduct(ctx context.Context, id string) error {
res, err := s.products.DeleteOne(ctx, bson.M{"_id": id})
if err != nil {
return err
}
if res == 0 {
return domain.ErrNotFound
}
return nil
}
func (s *MonStore) GetActiveBrandID(ctx context.Context, ownerUID int64) (string, error) {
var a domain.ActiveBrand
err := s.active.FindOne(ctx, &a, bson.M{"_id": ownerUID})
if err != nil {
if err == mon.ErrNotFound {
return "", nil
}
return "", err
}
return a.BrandID, nil
}
func (s *MonStore) SetActiveBrandID(ctx context.Context, ownerUID int64, brandID string) error {
doc := &domain.ActiveBrand{OwnerUID: ownerUID, BrandID: brandID, UpdatedAt: domain.NowNano()}
_, err := s.active.ReplaceOne(ctx, bson.M{"_id": ownerUID}, doc, options.Replace().SetUpsert(true))
return err
}
func (s *MonStore) SavePost(ctx context.Context, p *domain.Post) error {
_, err := s.posts.ReplaceOne(ctx, bson.M{"_id": p.ID}, p, options.Replace().SetUpsert(true))
return err
}
func (s *MonStore) GetPost(ctx context.Context, id string) (*domain.Post, error) {
var p domain.Post
err := s.posts.FindOne(ctx, &p, bson.M{"_id": id})
if err != nil {
if err == mon.ErrNotFound {
return nil, domain.ErrNotFound
}
return nil, err
}
return &p, nil
}
func (s *MonStore) ListPosts(ctx context.Context, ownerUID int64, brandID string) ([]*domain.Post, error) {
filter := bson.M{"owner_uid": ownerUID}
if brandID != "" {
filter["brand_id"] = brandID
}
var list []*domain.Post
err := s.posts.Find(ctx, &list, filter, options.Find().SetSort(bson.D{{Key: "created_at", Value: -1}}))
return list, err
}
func (s *MonStore) DeletePost(ctx context.Context, id string) error {
res, err := s.posts.DeleteOne(ctx, bson.M{"_id": id})
if err != nil {
return err
}
if res == 0 {
return domain.ErrNotFound
}
return nil
}
func (s *MonStore) DeletePostsByTheme(ctx context.Context, ownerUID int64, themeKey string) error {
_, err := s.posts.DeleteMany(ctx, bson.M{"owner_uid": ownerUID, "theme_key": themeKey})
return err
}
func (s *MonStore) SaveHomework(ctx context.Context, h *domain.Homework) error {
// composite: store theme as id, filter by owner
docID := formatKey(h.OwnerUID, h.ThemeKey)
type hwDoc struct {
ID string `bson:"_id"`
*domain.Homework
}
_, err := s.hw.ReplaceOne(ctx, bson.M{"_id": docID}, &hwDoc{ID: docID, Homework: h}, options.Replace().SetUpsert(true))
return err
}
func (s *MonStore) GetHomework(ctx context.Context, ownerUID int64, themeKey string) (*domain.Homework, error) {
type hwDoc struct {
ID string `bson:"_id"`
domain.Homework `bson:",inline"`
}
var doc hwDoc
err := s.hw.FindOne(ctx, &doc, bson.M{"_id": formatKey(ownerUID, themeKey)})
if err != nil {
if err == mon.ErrNotFound {
return nil, domain.ErrNotFound
}
return nil, err
}
h := doc.Homework
return &h, nil
}
func (s *MonStore) ListHomework(ctx context.Context, ownerUID int64) ([]*domain.Homework, error) {
var list []*domain.Homework
err := s.hw.Find(ctx, &list, bson.M{"owner_uid": ownerUID})
return list, err
}
func (s *MonStore) DeleteHomework(ctx context.Context, ownerUID int64, themeKey string) error {
res, err := s.hw.DeleteOne(ctx, bson.M{"_id": formatKey(ownerUID, themeKey)})
if err != nil {
return err
}
if res == 0 {
return domain.ErrNotFound
}
return nil
}
func (s *MonStore) GetCrawlerSession(ctx context.Context, ownerUID int64) (*domain.CrawlerSession, error) {
var c domain.CrawlerSession
err := s.crawler.FindOne(ctx, &c, bson.M{"_id": ownerUID})
if err != nil {
if err == mon.ErrNotFound {
return nil, domain.ErrNotFound
}
return nil, err
}
if c.Token == "" {
return nil, domain.ErrNotFound
}
return &c, nil
}
func (s *MonStore) SetCrawlerSession(ctx context.Context, sess *domain.CrawlerSession) error {
_, err := s.crawler.ReplaceOne(ctx, bson.M{"_id": sess.OwnerUID}, sess, options.Replace().SetUpsert(true))
return err
}
func (s *MonStore) ClearCrawlerSession(ctx context.Context, ownerUID int64) error {
_, err := s.crawler.DeleteOne(ctx, bson.M{"_id": ownerUID})
return err
}
func formatKey(uid int64, theme string) string {
return formatUID(uid) + "|" + theme
}
var _ domain.Repository = (*MonStore)(nil)