add endpoints to get single blog article

Signed-off-by: Tobias Erbshäußer <tobias@tesoft.dev>
This commit is contained in:
2026-05-24 09:22:32 +02:00
parent 34fa523c9b
commit 712d92b810
2 changed files with 149 additions and 4 deletions
+101
View File
@@ -13,6 +13,8 @@ import (
_ "github.com/mattn/go-sqlite3"
)
var ErrNotFound = errors.New("not found")
type Database struct {
db *sql.DB
}
@@ -203,6 +205,105 @@ func (db *Database) GetBlogArticles(showAll bool, offset int, limit int) ([]Arti
return articles, nil
}
func (db *Database) GetBlogArticle(showAll bool, id int64) (*Article, error) {
filter := "WHERE blog_article.id = ?"
if !showAll {
filter = filter + " AND status = " + strconv.Itoa(ArticleStatusPublished)
}
statement := "SELECT blog_article.status, blog_article.title, blog_article.date, blog_article.modification_date, blog_article.content, blog_tag.name" +
" FROM blog_article" +
" LEFT JOIN blog_article_to_tag ON blog_article.id = blog_article_to_tag.article_id" +
" LEFT JOIN blog_tag ON blog_article_to_tag.tag_id = blog_tag.id" +
" " + filter +
" ORDER BY blog_tag.name"
rows, err := db.db.Query(statement, id)
if err != nil {
return nil, err
}
defer func() { _ = rows.Close() }()
if !rows.Next() {
return nil, ErrNotFound
}
var status ArticleStatus
var title string
var dateStr string
var modificationDateStr *string
var content string
var tag *string
err = rows.Scan(&status, &title, &dateStr, &modificationDateStr, &content, &tag)
if err != nil {
return nil, err
}
date, _ := time.Parse(time.DateOnly, dateStr)
var modificationDate *time.Time
if modificationDateStr != nil {
tmp, _ := time.Parse(time.DateOnly, *modificationDateStr)
modificationDate = &tmp
}
article := &Article{
ArticleProperties{
id,
title,
status,
make([]string, 0),
date,
modificationDate,
},
content,
nil,
}
if tag != nil {
article.Tags = append(article.Tags, *tag)
}
for rows.Next() {
err = rows.Scan(&status, &title, &dateStr, &modificationDateStr, &content, &tag)
if err != nil {
return nil, err
}
if tag != nil {
article.Tags = append(article.Tags, *tag)
}
}
return article, nil
}
func (db *Database) GetBlogArticleFile(showAll bool, articleId int64, fileId int64) (ArticleFile, error) {
filter := "WHERE blog_file.article_id = ? AND blog_file.id = ?"
if !showAll {
filter = filter + " AND blog_article.status = " + strconv.Itoa(ArticleStatusPublished)
}
statement := "SELECT blog_file.data FROM blog_file" +
" INNER JOIN blog_article ON blog_article.id = blog_file.article_id" +
" " + filter
var data []byte
err := db.db.QueryRow(statement, articleId, fileId).Scan(&data)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return ArticleFile{}, ErrNotFound
}
return ArticleFile{}, err
}
return ArticleFile{
fileId,
data,
}, nil
}
func migrate(db *sql.DB, rootPassword string) error {
tx, err := db.Begin()
if err != nil {