package store import ( "gorm.io/gorm" "strings" models2 "tercul/internal/models" ) // DB represents a database connection type DB struct { *gorm.DB } // Connect creates a new database connection func Connect() *DB { // In a real application, this would use configuration from environment variables // or a configuration file to connect to the database // For this example, we'll assume the DB connection is passed in from main.go return nil } // ListPendingWorks returns a list of works that need to be enriched func ListPendingWorks(db *DB) []Work { var works []Work // Query for works that haven't been enriched yet var modelWorks []models2.Work db.Where("id NOT IN (SELECT work_id FROM language_analyses)").Find(&modelWorks) // Convert to store.Work for _, work := range modelWorks { // Prefer original language translation; fallback to work language; then any var content string var t models2.Translation // Try original if err := db.Where("translatable_type = ? AND translatable_id = ? AND is_original_language = ?", "Work", work.ID, true). First(&t).Error; err == nil { content = t.Content } else { // Try same language if err := db.Where("translatable_type = ? AND translatable_id = ? AND language = ?", "Work", work.ID, work.Language). First(&t).Error; err == nil { content = t.Content } else { // Any translation if err := db.Where("translatable_type = ? AND translatable_id = ?", "Work", work.ID). First(&t).Error; err == nil { content = t.Content } } } works = append(works, Work{ ID: work.ID, Body: content, }) } return works } // UpsertWord creates or updates a word in the database func UpsertWord(db *DB, workID uint, text, lemma, pos, phonetic string) error { // Check if the word already exists var word models2.Word result := db.Where("text = ? AND language = ?", text, "auto").First(&word) if result.Error != nil && result.Error != gorm.ErrRecordNotFound { return result.Error } // Create or update the word if result.Error == gorm.ErrRecordNotFound { // Create new word word = models2.Word{ Text: text, Language: "auto", // This would be set to the detected language PartOfSpeech: pos, Lemma: lemma, } if err := db.Create(&word).Error; err != nil { return err } } else { // Update existing word word.PartOfSpeech = pos word.Lemma = lemma if err := db.Save(&word).Error; err != nil { return err } } // Associate the word with the work return db.Exec("INSERT INTO work_words (work_id, word_id) VALUES (?, ?) ON CONFLICT DO NOTHING", workID, word.ID).Error } // SaveKeywords saves keywords for a work func SaveKeywords(db *DB, workID uint, keywords []string) error { // Clear existing keywords if err := db.Exec("DELETE FROM work_topic_clusters WHERE work_id = ?", workID).Error; err != nil { return err } // Create a topic cluster for the keywords cluster := models2.TopicCluster{ Name: "Auto-generated", Description: "Automatically generated keywords", Keywords: strings.Join(keywords, ", "), } if err := db.Create(&cluster).Error; err != nil { return err } // Associate the cluster with the work return db.Exec("INSERT INTO work_topic_clusters (work_id, topic_cluster_id) VALUES (?, ?)", workID, cluster.ID).Error } // SavePoetics saves poetic analysis for a work func SavePoetics(db *DB, workID uint, metrics PoeticMetrics) error { poetics := models2.PoeticAnalysis{ WorkID: workID, Language: "auto", // This would be set to the detected language RhymeScheme: metrics.RhymeScheme, MeterType: metrics.MeterType, StanzaCount: metrics.StanzaCount, LineCount: metrics.LineCount, Structure: metrics.Structure, } return db.Create(&poetics).Error } // MarkEnriched marks a work as enriched with the detected language func MarkEnriched(db *DB, workID uint, language string) error { // Create a language analysis record to mark the work as processed analysis := models2.LanguageAnalysis{ WorkID: workID, Language: language, Analysis: models2.JSONB{ "enriched": true, "language": language, }, } return db.Create(&analysis).Error }