You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
1.7 KiB
78 lines
1.7 KiB
package mongodb
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
"strings"
|
|
|
|
"git.aiterp.net/rpdata/api/models"
|
|
"git.aiterp.net/rpdata/api/repositories"
|
|
"github.com/globalsign/mgo"
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
)
|
|
|
|
type tagRepository struct {
|
|
stories *mgo.Collection
|
|
}
|
|
|
|
func newTagRepository(db *mgo.Database) repositories.TagRepository {
|
|
return &tagRepository{
|
|
stories: db.C("story.stories"),
|
|
}
|
|
}
|
|
|
|
func (r *tagRepository) Find(ctx context.Context, kind models.TagKind, name string) (*models.Tag, error) {
|
|
tags := make([]*models.Tag, 0, 1)
|
|
err := r.stories.Find(bson.M{"listed": true, "tags": bson.M{"kind": kind, "name": name}}).Distinct("tag", &tags)
|
|
if err != nil {
|
|
return nil, err
|
|
} else if len(tags) == 0 {
|
|
return nil, repositories.ErrNotFound
|
|
}
|
|
|
|
for _, tag := range tags {
|
|
if tag.Kind == kind && tag.Name == name {
|
|
return tag, nil
|
|
}
|
|
}
|
|
|
|
return nil, repositories.ErrNotFound
|
|
}
|
|
|
|
func (r *tagRepository) List(ctx context.Context, filter models.TagFilter) ([]*models.Tag, error) {
|
|
tags := make([]*models.Tag, 0, 64)
|
|
|
|
query := bson.M{"listed": true, "tags": bson.M{"$ne": nil}}
|
|
if filter.Kind != nil {
|
|
query["tags.kind"] = *filter.Kind
|
|
}
|
|
|
|
err := r.stories.Find(query).Distinct("tags", &tags)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if filter.Kind != nil {
|
|
// While it's unsorted, delete any incorrect tags with replacement.
|
|
for i := 0; i < len(tags); i++ {
|
|
if tags[i].Kind != *filter.Kind {
|
|
tags[i] = tags[len(tags)-1]
|
|
tags = tags[:len(tags)-1]
|
|
i--
|
|
}
|
|
}
|
|
}
|
|
|
|
sort.Slice(tags, func(i, j int) bool {
|
|
if filter.Kind == nil {
|
|
kindCmp := strings.Compare(string(tags[i].Kind), string(tags[j].Kind))
|
|
if kindCmp != 0 {
|
|
return kindCmp < 0
|
|
}
|
|
}
|
|
|
|
return strings.Compare(tags[i].Name, tags[j].Name) < 0
|
|
})
|
|
|
|
return tags, nil
|
|
}
|