|
|
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 }
|