168 lines
5.4 KiB
Go
168 lines
5.4 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
"go.mongodb.org/mongo-driver/v2/mongo"
|
|
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
|
)
|
|
|
|
type LetterRepo struct {
|
|
col *mongo.Collection
|
|
}
|
|
|
|
func NewLetterRepo(db *MongoDB) *LetterRepo {
|
|
return &LetterRepo{col: db.Collection("letters")}
|
|
}
|
|
|
|
type LetterDoc struct {
|
|
ID bson.ObjectID `bson:"_id" json:"id"`
|
|
Slug string `bson:"slug" json:"slug"`
|
|
Recipients []string `bson:"recipients" json:"recipients"`
|
|
RecipientDisplay string `bson:"recipientDisplay" json:"recipient_display"`
|
|
Date *string `bson:"date,omitempty" json:"date,omitempty"`
|
|
DateRef *string `bson:"dateRef,omitempty" json:"date_ref,omitempty"`
|
|
Year *int `bson:"year,omitempty" json:"year,omitempty"`
|
|
Month *int `bson:"month,omitempty" json:"month,omitempty"`
|
|
Day *int `bson:"day,omitempty" json:"day,omitempty"`
|
|
Location *string `bson:"location,omitempty" json:"location,omitempty"`
|
|
Salutation *string `bson:"salutation,omitempty" json:"salutation,omitempty"`
|
|
Paragraphs []string `bson:"paragraphs" json:"paragraphs"`
|
|
}
|
|
|
|
type LetterSummaryDoc struct {
|
|
ID bson.ObjectID `bson:"_id" json:"id"`
|
|
Slug string `bson:"slug" json:"slug"`
|
|
Recipients []string `bson:"recipients,omitempty" json:"recipients"`
|
|
RecipientDisplay string `bson:"recipientDisplay" json:"recipient_display"`
|
|
Date *string `bson:"date,omitempty" json:"date,omitempty"`
|
|
Year *int `bson:"year,omitempty" json:"year,omitempty"`
|
|
Month *int `bson:"month,omitempty" json:"month,omitempty"`
|
|
Day *int `bson:"day,omitempty" json:"day,omitempty"`
|
|
Location *string `bson:"location,omitempty" json:"location,omitempty"`
|
|
}
|
|
|
|
var letterSummaryProjection = bson.M{
|
|
"slug": 1, "recipients": 1, "recipientDisplay": 1,
|
|
"date": 1, "year": 1, "month": 1, "day": 1, "location": 1,
|
|
}
|
|
|
|
func (r *LetterRepo) GetBySlug(ctx context.Context, slug string) (*LetterDoc, error) {
|
|
var doc LetterDoc
|
|
err := r.col.FindOne(ctx, bson.M{"slug": slug}).Decode(&doc)
|
|
if err != nil {
|
|
if err == mongo.ErrNoDocuments {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
return &doc, nil
|
|
}
|
|
|
|
func (r *LetterRepo) GetByYear(ctx context.Context, year int) ([]LetterSummaryDoc, error) {
|
|
opts := options.Find().
|
|
SetSort(bson.D{{Key: "month", Value: 1}, {Key: "day", Value: 1}}).
|
|
SetProjection(letterSummaryProjection)
|
|
cursor, err := r.col.Find(ctx, bson.M{"year": year}, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
var results []LetterSummaryDoc
|
|
if err := cursor.All(ctx, &results); err != nil {
|
|
return nil, err
|
|
}
|
|
return results, nil
|
|
}
|
|
|
|
func (r *LetterRepo) GetByRecipient(ctx context.Context, name string) ([]LetterSummaryDoc, error) {
|
|
opts := options.Find().
|
|
SetSort(bson.D{{Key: "year", Value: 1}, {Key: "month", Value: 1}, {Key: "day", Value: 1}}).
|
|
SetProjection(letterSummaryProjection)
|
|
cursor, err := r.col.Find(ctx, bson.M{"recipients": name}, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
var results []LetterSummaryDoc
|
|
if err := cursor.All(ctx, &results); err != nil {
|
|
return nil, err
|
|
}
|
|
return results, nil
|
|
}
|
|
|
|
func (r *LetterRepo) GetByLocation(ctx context.Context, location string) ([]LetterSummaryDoc, error) {
|
|
opts := options.Find().
|
|
SetSort(bson.D{{Key: "year", Value: 1}, {Key: "month", Value: 1}, {Key: "day", Value: 1}}).
|
|
SetProjection(letterSummaryProjection)
|
|
cursor, err := r.col.Find(ctx, bson.M{"location": location}, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
var results []LetterSummaryDoc
|
|
if err := cursor.All(ctx, &results); err != nil {
|
|
return nil, err
|
|
}
|
|
return results, nil
|
|
}
|
|
|
|
func (r *LetterRepo) GetYears(ctx context.Context) ([]bson.M, error) {
|
|
pipeline := bson.A{
|
|
bson.M{"$match": bson.M{"year": bson.M{"$ne": nil}}},
|
|
bson.M{"$group": bson.M{"_id": "$year", "count": bson.M{"$sum": 1}}},
|
|
bson.M{"$sort": bson.M{"_id": 1}},
|
|
}
|
|
cursor, err := r.col.Aggregate(ctx, pipeline)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
var results []bson.M
|
|
if err := cursor.All(ctx, &results); err != nil {
|
|
return nil, err
|
|
}
|
|
return results, nil
|
|
}
|
|
|
|
func (r *LetterRepo) GetRecipients(ctx context.Context) ([]bson.M, error) {
|
|
pipeline := bson.A{
|
|
bson.M{"$unwind": "$recipients"},
|
|
bson.M{"$group": bson.M{"_id": "$recipients", "count": bson.M{"$sum": 1}}},
|
|
bson.M{"$sort": bson.M{"count": -1}},
|
|
}
|
|
cursor, err := r.col.Aggregate(ctx, pipeline)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
var results []bson.M
|
|
if err := cursor.All(ctx, &results); err != nil {
|
|
return nil, err
|
|
}
|
|
return results, nil
|
|
}
|
|
|
|
func (r *LetterRepo) GetLocations(ctx context.Context) ([]bson.M, error) {
|
|
pipeline := bson.A{
|
|
bson.M{"$match": bson.M{"location": bson.M{"$ne": nil}}},
|
|
bson.M{"$group": bson.M{"_id": "$location", "count": bson.M{"$sum": 1}}},
|
|
bson.M{"$sort": bson.M{"count": -1}},
|
|
}
|
|
cursor, err := r.col.Aggregate(ctx, pipeline)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
var results []bson.M
|
|
if err := cursor.All(ctx, &results); err != nil {
|
|
return nil, err
|
|
}
|
|
return results, nil
|
|
}
|
|
|
|
func (r *LetterRepo) Count(ctx context.Context) (int64, error) {
|
|
return r.col.CountDocuments(ctx, bson.M{})
|
|
}
|