chore: splits out article into db specific entity and generic struct

This commit is contained in:
Dennis Schoepf 2025-08-29 14:12:21 +02:00
parent 5a4a4d387a
commit 2322b9170d
3 changed files with 41 additions and 20 deletions

View file

@ -2,29 +2,50 @@ package internal
import ( import (
"fmt" "fmt"
"time"
"freed/internal/database" "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() count, err := database.CountArticlesReadToday()
if err != nil { if err != nil {
return "", err return nil, err
} }
if count > 0 { 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 { if err != nil {
return "", err return nil, err
} }
if err := article.MarkAsRead(); err != nil { // For now doing it at this point is enough
return "", err // 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
} }

View file

@ -4,7 +4,7 @@ import (
"time" "time"
) )
type Article struct { type ArticleEntity struct {
ID string ID string
Name string Name string
Url string Url string
@ -16,7 +16,7 @@ type InsertMultipleOptions struct {
IgnoreDuplicates bool 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) result, err := db.Exec("INSERT INTO article (name, url, readAt, feedId) VALUES (?, ?, ?, ?)", a.Name, a.Url, a.ReadAt, a.FeedId)
if err != nil { if err != nil {
@ -32,7 +32,7 @@ func (a Article) Insert() (int64, error) {
return id, nil 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) result, err := db.Exec("UPDATE article SET readAt = datetime() WHERE id = ?;", a.ID)
if err != nil { if err != nil {
@ -46,15 +46,15 @@ func (a Article) MarkAsRead() error {
return nil return nil
} }
func InsertMultipleArticles(articles []Article) error { func InsertMultipleArticles(articles []ArticleEntity) error {
return insertMultipleArticlesWithOpts(articles, InsertMultipleOptions{IgnoreDuplicates: false}) return insertMultipleArticlesWithOpts(articles, InsertMultipleOptions{IgnoreDuplicates: false})
} }
func InsertIgnoreMultipleArticles(articles []Article) error { func InsertIgnoreMultipleArticles(articles []ArticleEntity) error {
return insertMultipleArticlesWithOpts(articles, InsertMultipleOptions{IgnoreDuplicates: true}) return insertMultipleArticlesWithOpts(articles, InsertMultipleOptions{IgnoreDuplicates: true})
} }
func insertMultipleArticlesWithOpts(articles []Article, opts InsertMultipleOptions) error { func insertMultipleArticlesWithOpts(articles []ArticleEntity, opts InsertMultipleOptions) error {
if len(articles) == 0 { if len(articles) == 0 {
return nil return nil
} }
@ -93,8 +93,8 @@ func insertMultipleArticlesWithOpts(articles []Article, opts InsertMultipleOptio
return tx.Commit() return tx.Commit()
} }
func FindOneUnreadArticle() (*Article, error) { func FindOneUnreadArticle() (*ArticleEntity, error) {
var article Article var article ArticleEntity
row := db.QueryRow("SELECT * FROM article WHERE readAt IS NULL ORDER BY RANDOM() LIMIT 1") 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) err := row.Scan(&article.ID, &article.Name, &article.Url, &article.ReadAt, &article.FeedId)

View file

@ -34,14 +34,14 @@ func AddFeed(feedUrl string) (string, int, error) {
} }
// TODO: Make the amount of articles configurable // 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 { for i, v := range feed.Items {
if i > 10 { if i > 10 {
continue continue
} }
a := database.Article{ a := database.ArticleEntity{
Name: v.Title, Name: v.Title,
Url: v.Link, Url: v.Link,
FeedId: feedId, FeedId: feedId,
@ -143,14 +143,14 @@ func syncFeed(
return return
} }
var articles []database.Article var articles []database.ArticleEntity
for _, item := range gFeed.Items { for _, item := range gFeed.Items {
if item.PublishedParsed.Before(*feed.LastSyncedAt) { if item.PublishedParsed.Before(*feed.LastSyncedAt) {
continue continue
} }
article := database.Article{ article := database.ArticleEntity{
Name: item.Title, Name: item.Title,
Url: item.Link, Url: item.Link,
FeedId: feed.ID, FeedId: feed.ID,