From 2322b9170d58ad04e81d5b6dc536726516335396 Mon Sep 17 00:00:00 2001 From: Dennis Date: Fri, 29 Aug 2025 14:12:21 +0200 Subject: [PATCH] chore: splits out article into db specific entity and generic struct --- internal/article.go | 37 ++++++++++++++++++++++++++++-------- internal/database/article.go | 16 ++++++++-------- internal/feed.go | 8 ++++---- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/internal/article.go b/internal/article.go index 8ed17f1..3875e80 100644 --- a/internal/article.go +++ b/internal/article.go @@ -2,29 +2,50 @@ package internal import ( "fmt" + "time" + "freed/internal/database" ) -func GetArticleUrlForToday() (string, error) { +type Article struct { + ID string + Name string + Url string + ReadAt *time.Time + FeedId int64 +} + +func GetArticleUrlForToday() (*Article, error) { count, err := database.CountArticlesReadToday() if err != nil { - return "", err + return nil, err } if count > 0 { - return "", fmt.Errorf("Already reached maximum number of articles for the day. Come back tomorrow!") + return nil, fmt.Errorf("Already reached maximum number of articles for the day. Come back tomorrow!") } - article, err := database.FindOneUnreadArticle() + articleEntity, err := database.FindOneUnreadArticle() if err != nil { - return "", err + return nil, err } - if err := article.MarkAsRead(); err != nil { - return "", err + // For now doing it at this point is enough + // In the future it might be better to gather user input + // on if the article was read + if err := articleEntity.MarkAsRead(); err != nil { + return nil, err } - return article.Url, nil + article := &Article{ + ID: articleEntity.ID, + Name: articleEntity.Name, + Url: articleEntity.Url, + ReadAt: articleEntity.ReadAt, + FeedId: articleEntity.FeedId, + } + + return article, nil } diff --git a/internal/database/article.go b/internal/database/article.go index f3044df..b6ee0d9 100644 --- a/internal/database/article.go +++ b/internal/database/article.go @@ -4,7 +4,7 @@ import ( "time" ) -type Article struct { +type ArticleEntity struct { ID string Name string Url string @@ -16,7 +16,7 @@ type InsertMultipleOptions struct { IgnoreDuplicates bool } -func (a Article) Insert() (int64, error) { +func (a ArticleEntity) Insert() (int64, error) { result, err := db.Exec("INSERT INTO article (name, url, readAt, feedId) VALUES (?, ?, ?, ?)", a.Name, a.Url, a.ReadAt, a.FeedId) if err != nil { @@ -32,7 +32,7 @@ func (a Article) Insert() (int64, error) { return id, nil } -func (a Article) MarkAsRead() error { +func (a ArticleEntity) MarkAsRead() error { result, err := db.Exec("UPDATE article SET readAt = datetime() WHERE id = ?;", a.ID) if err != nil { @@ -46,15 +46,15 @@ func (a Article) MarkAsRead() error { return nil } -func InsertMultipleArticles(articles []Article) error { +func InsertMultipleArticles(articles []ArticleEntity) error { return insertMultipleArticlesWithOpts(articles, InsertMultipleOptions{IgnoreDuplicates: false}) } -func InsertIgnoreMultipleArticles(articles []Article) error { +func InsertIgnoreMultipleArticles(articles []ArticleEntity) error { return insertMultipleArticlesWithOpts(articles, InsertMultipleOptions{IgnoreDuplicates: true}) } -func insertMultipleArticlesWithOpts(articles []Article, opts InsertMultipleOptions) error { +func insertMultipleArticlesWithOpts(articles []ArticleEntity, opts InsertMultipleOptions) error { if len(articles) == 0 { return nil } @@ -93,8 +93,8 @@ func insertMultipleArticlesWithOpts(articles []Article, opts InsertMultipleOptio return tx.Commit() } -func FindOneUnreadArticle() (*Article, error) { - var article Article +func FindOneUnreadArticle() (*ArticleEntity, error) { + var article ArticleEntity row := db.QueryRow("SELECT * FROM article WHERE readAt IS NULL ORDER BY RANDOM() LIMIT 1") err := row.Scan(&article.ID, &article.Name, &article.Url, &article.ReadAt, &article.FeedId) diff --git a/internal/feed.go b/internal/feed.go index e06884c..cea8407 100644 --- a/internal/feed.go +++ b/internal/feed.go @@ -34,14 +34,14 @@ func AddFeed(feedUrl string) (string, int, error) { } // TODO: Make the amount of articles configurable - articles := make([]database.Article, 0, 10) + articles := make([]database.ArticleEntity, 0, 10) for i, v := range feed.Items { if i > 10 { continue } - a := database.Article{ + a := database.ArticleEntity{ Name: v.Title, Url: v.Link, FeedId: feedId, @@ -143,14 +143,14 @@ func syncFeed( return } - var articles []database.Article + var articles []database.ArticleEntity for _, item := range gFeed.Items { if item.PublishedParsed.Before(*feed.LastSyncedAt) { continue } - article := database.Article{ + article := database.ArticleEntity{ Name: item.Title, Url: item.Link, FeedId: feed.ID,