212 lines
5.9 KiB
Go
212 lines
5.9 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 BookRepo struct {
|
|
meta *mongo.Collection
|
|
verses *mongo.Collection
|
|
proseChapters *mongo.Collection
|
|
}
|
|
|
|
func NewBookRepo(db *MongoDB) *BookRepo {
|
|
return &BookRepo{
|
|
meta: db.Collection("book_meta"),
|
|
verses: db.Collection("verses"),
|
|
proseChapters: db.Collection("prose_chapters"),
|
|
}
|
|
}
|
|
|
|
// --- Book Meta ---
|
|
|
|
type BookMetaDoc struct {
|
|
ID bson.ObjectID `bson:"_id" json:"id"`
|
|
Book string `bson:"book" json:"book"`
|
|
Data interface{} `bson:"data" json:"data"`
|
|
}
|
|
|
|
func (r *BookRepo) GetAllBookMetas(ctx context.Context) ([]BookMetaDoc, error) {
|
|
cursor, err := r.meta.Find(ctx, bson.M{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
var results []BookMetaDoc
|
|
if err := cursor.All(ctx, &results); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return results, nil
|
|
}
|
|
|
|
func (r *BookRepo) GetBookMeta(ctx context.Context, book string) (*BookMetaDoc, error) {
|
|
var doc BookMetaDoc
|
|
err := r.meta.FindOne(ctx, bson.M{"book": book}).Decode(&doc)
|
|
if err != nil {
|
|
if err == mongo.ErrNoDocuments {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
return &doc, nil
|
|
}
|
|
|
|
// --- Verses ---
|
|
|
|
type SynonymDoc struct {
|
|
Word string `bson:"word" json:"word"`
|
|
Meanings []string `bson:"meanings" json:"meanings"`
|
|
}
|
|
|
|
type VerseDoc struct {
|
|
ID bson.ObjectID `bson:"_id" json:"id"`
|
|
Book string `bson:"book" json:"book"`
|
|
Division *string `bson:"division,omitempty" json:"division,omitempty"`
|
|
Chapter int `bson:"chapter" json:"chapter"`
|
|
Verse int `bson:"verse" json:"verse"`
|
|
VerseEnd *int `bson:"verseEnd,omitempty" json:"verse_end,omitempty"`
|
|
Reference string `bson:"reference" json:"reference"`
|
|
BookTitle string `bson:"bookTitle" json:"book_title"`
|
|
Devanagari string `bson:"devanagari" json:"devanagari"`
|
|
Bengali *string `bson:"bengali,omitempty" json:"bengali,omitempty"`
|
|
Transliteration string `bson:"transliteration" json:"transliteration"`
|
|
Synonyms []SynonymDoc `bson:"synonyms" json:"synonyms"`
|
|
Translation string `bson:"translation" json:"translation"`
|
|
Purport []string `bson:"purport" json:"purport"`
|
|
}
|
|
|
|
type VerseIndexDoc struct {
|
|
Verse int `bson:"verse" json:"verse"`
|
|
VerseEnd *int `bson:"verseEnd,omitempty" json:"verse_end,omitempty"`
|
|
Reference string `bson:"reference" json:"reference"`
|
|
}
|
|
|
|
func (r *BookRepo) GetVerseIndex(ctx context.Context, book string, division *string, chapter int) ([]VerseIndexDoc, error) {
|
|
filter := bson.M{"book": book, "chapter": chapter}
|
|
if division != nil {
|
|
filter["division"] = *division
|
|
} else {
|
|
filter["division"] = nil
|
|
}
|
|
|
|
opts := options.Find().
|
|
SetSort(bson.M{"verse": 1}).
|
|
SetProjection(bson.M{"_id": 0, "verse": 1, "verseEnd": 1, "reference": 1})
|
|
|
|
cursor, err := r.verses.Find(ctx, filter, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
var results []VerseIndexDoc
|
|
if err := cursor.All(ctx, &results); err != nil {
|
|
return nil, err
|
|
}
|
|
return results, nil
|
|
}
|
|
|
|
func (r *BookRepo) GetVerses(ctx context.Context, book string, division *string, chapter int, page, limit int) ([]VerseDoc, int64, error) {
|
|
filter := bson.M{"book": book, "chapter": chapter}
|
|
if division != nil {
|
|
filter["division"] = *division
|
|
} else {
|
|
filter["division"] = nil
|
|
}
|
|
|
|
total, err := r.verses.CountDocuments(ctx, filter)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
skip := int64((page - 1) * limit)
|
|
opts := options.Find().
|
|
SetSort(bson.M{"verse": 1}).
|
|
SetSkip(skip).
|
|
SetLimit(int64(limit))
|
|
|
|
cursor, err := r.verses.Find(ctx, filter, opts)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
var results []VerseDoc
|
|
if err := cursor.All(ctx, &results); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return results, total, nil
|
|
}
|
|
|
|
func (r *BookRepo) GetSingleVerse(ctx context.Context, book string, division *string, chapter, verse int) (*VerseDoc, error) {
|
|
filter := bson.M{"book": book, "chapter": chapter, "verse": verse}
|
|
if division != nil {
|
|
filter["division"] = *division
|
|
} else {
|
|
filter["division"] = nil
|
|
}
|
|
|
|
var doc VerseDoc
|
|
err := r.verses.FindOne(ctx, filter).Decode(&doc)
|
|
if err != nil {
|
|
if err == mongo.ErrNoDocuments {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
return &doc, nil
|
|
}
|
|
|
|
// --- Prose Chapters ---
|
|
|
|
type ProseChapterDoc struct {
|
|
ID bson.ObjectID `bson:"_id" json:"id"`
|
|
Book string `bson:"book" json:"book"`
|
|
Volume int `bson:"volume" json:"volume"`
|
|
Chapter *int `bson:"chapter,omitempty" json:"chapter,omitempty"`
|
|
Title string `bson:"title" json:"title"`
|
|
Type string `bson:"type" json:"type"`
|
|
Slug string `bson:"slug" json:"slug"`
|
|
Order int `bson:"order" json:"order"`
|
|
Paragraphs []string `bson:"paragraphs" json:"paragraphs"`
|
|
}
|
|
|
|
func (r *BookRepo) GetProseChapters(ctx context.Context, book string, volume int, chapterType *string) ([]ProseChapterDoc, error) {
|
|
filter := bson.M{"book": book, "volume": volume}
|
|
if chapterType != nil {
|
|
filter["type"] = *chapterType
|
|
}
|
|
|
|
opts := options.Find().SetSort(bson.M{"order": 1})
|
|
cursor, err := r.proseChapters.Find(ctx, filter, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer cursor.Close(ctx)
|
|
|
|
var results []ProseChapterDoc
|
|
if err := cursor.All(ctx, &results); err != nil {
|
|
return nil, err
|
|
}
|
|
return results, nil
|
|
}
|
|
|
|
func (r *BookRepo) GetProseChapter(ctx context.Context, book string, volume int, slug string) (*ProseChapterDoc, error) {
|
|
filter := bson.M{"book": book, "volume": volume, "slug": slug}
|
|
var doc ProseChapterDoc
|
|
err := r.proseChapters.FindOne(ctx, filter).Decode(&doc)
|
|
if err != nil {
|
|
if err == mongo.ErrNoDocuments {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
return &doc, nil
|
|
}
|