extend blog articles endpoint to allow to query for tags
Signed-off-by: Tobias Erbshäußer <tobias@tesoft.dev>
This commit is contained in:
+11
-2
@@ -155,6 +155,7 @@ func (h *ApiHandler) ServeBlogGet(writer http.ResponseWriter, request *http.Requ
|
|||||||
var err error
|
var err error
|
||||||
var offset int
|
var offset int
|
||||||
var limit int
|
var limit int
|
||||||
|
tags := make([]string, 0)
|
||||||
|
|
||||||
offsetStr := query.Get("offset")
|
offsetStr := query.Get("offset")
|
||||||
if offsetStr == "" {
|
if offsetStr == "" {
|
||||||
@@ -178,13 +179,21 @@ func (h *ApiHandler) ServeBlogGet(writer http.ResponseWriter, request *http.Requ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
articles, err := h.db.GetBlogArticles(IsAuthorized(request), offset, limit)
|
tagsStr := query.Get("tags")
|
||||||
|
if tagsStr != "" {
|
||||||
|
tags = strings.Split(tagsStr, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
articles, total, err := h.db.GetBlogArticles(IsAuthorized(request), offset, limit, tags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
WriteError(writer, http.StatusInternalServerError, "failed to query database", err)
|
WriteError(writer, http.StatusInternalServerError, "failed to query database", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteResponse(writer, http.StatusOK, articles)
|
WriteResponse(writer, http.StatusOK, map[string]interface{}{
|
||||||
|
"articles": articles,
|
||||||
|
"total": total,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ApiHandler) ServeBlogPut(writer http.ResponseWriter, request *http.Request) {
|
func (h *ApiHandler) ServeBlogPut(writer http.ResponseWriter, request *http.Request) {
|
||||||
|
|||||||
+43
-18
@@ -8,6 +8,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
@@ -134,29 +135,53 @@ func (db *Database) CreateBlogArticle() (int64, func(*Article) error, error) {
|
|||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Database) GetBlogArticles(showAll bool, offset int, limit int) ([]ArticleProperties, error) {
|
func (db *Database) GetBlogArticles(showAll bool, offset int, limit int, tags []string) ([]ArticleProperties, int64, error) {
|
||||||
inner := "SELECT id FROM blog_article"
|
filters := make([]string, 0)
|
||||||
|
filterArgs := make([]interface{}, 0)
|
||||||
|
|
||||||
if !showAll {
|
if !showAll {
|
||||||
inner = inner + " WHERE status = " + strconv.Itoa(ArticleStatusPublished)
|
filters = append(filters, "blog_article.status = ?")
|
||||||
|
filterArgs = append(filterArgs, ArticleStatusPublished)
|
||||||
}
|
}
|
||||||
inner = inner + " ORDER BY date DESC LIMIT ? OFFSET ?"
|
if len(tags) > 0 {
|
||||||
outer := "SELECT blog_article.id, blog_article.status, blog_article.title, blog_article.date, blog_article.modification_date, blog_tag.name" +
|
filters = append(filters, "blog_tag.name IN (?"+strings.Repeat(", ?", len(tags)-1)+") GROUP BY blog_article.id HAVING COUNT(DISTINCT blog_tag.id) = ?")
|
||||||
" FROM blog_article" +
|
for _, tag := range tags {
|
||||||
" LEFT JOIN blog_article_to_tag ON blog_article.id = blog_article_to_tag.article_id" +
|
filterArgs = append(filterArgs, tag)
|
||||||
" LEFT JOIN blog_tag ON blog_article_to_tag.tag_id = blog_tag.id" +
|
}
|
||||||
" WHERE blog_article.id IN (" + inner + ")" +
|
filterArgs = append(filterArgs, len(tags))
|
||||||
" ORDER BY blog_article.date DESC, blog_article.id"
|
}
|
||||||
|
|
||||||
|
filter := ""
|
||||||
|
if len(filters) > 0 {
|
||||||
|
filter = " WHERE " + strings.Join(filters, " AND ")
|
||||||
|
}
|
||||||
|
|
||||||
|
joins := " 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"
|
||||||
|
|
||||||
|
args := make([]interface{}, 0, len(filterArgs)*2+2)
|
||||||
|
args = append(args, filterArgs...)
|
||||||
|
args = append(args, filterArgs...)
|
||||||
|
args = append(args, limit)
|
||||||
|
args = append(args, offset)
|
||||||
|
|
||||||
rows, err := db.db.Query(
|
rows, err := db.db.Query(
|
||||||
outer,
|
"SELECT blog_article.id, blog_article.status, blog_article.title, blog_article.date, blog_article.modification_date, blog_tag.name,"+
|
||||||
limit,
|
" (SELECT COUNT(DISTINCT blog_article.id) FROM blog_article"+joins+filter+")"+
|
||||||
offset,
|
" FROM blog_article"+joins+
|
||||||
|
" WHERE blog_article.id IN ("+
|
||||||
|
" SELECT blog_article.id FROM blog_article"+joins+filter+" ORDER BY date DESC LIMIT ? OFFSET ?"+
|
||||||
|
" )"+
|
||||||
|
" ORDER BY blog_article.date DESC, blog_article.id",
|
||||||
|
args...,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
articles := make([]ArticleProperties, 0)
|
articles := make([]ArticleProperties, 0)
|
||||||
|
var total int64
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var id int64
|
var id int64
|
||||||
var status ArticleStatus
|
var status ArticleStatus
|
||||||
@@ -164,10 +189,10 @@ func (db *Database) GetBlogArticles(showAll bool, offset int, limit int) ([]Arti
|
|||||||
var dateStr string
|
var dateStr string
|
||||||
var modificationDateStr *string
|
var modificationDateStr *string
|
||||||
var tag *string
|
var tag *string
|
||||||
err := rows.Scan(&id, &status, &title, &dateStr, &modificationDateStr, &tag)
|
err := rows.Scan(&id, &status, &title, &dateStr, &modificationDateStr, &tag, &total)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = rows.Close()
|
_ = rows.Close()
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if tag != nil && len(articles) > 0 && articles[len(articles)-1].Id == id {
|
if tag != nil && len(articles) > 0 && articles[len(articles)-1].Id == id {
|
||||||
@@ -199,10 +224,10 @@ func (db *Database) GetBlogArticles(showAll bool, offset int, limit int) ([]Arti
|
|||||||
|
|
||||||
err = rows.Close()
|
err = rows.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return articles, nil
|
return articles, total, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Database) GetBlogArticle(showAll bool, id int64) (*Article, error) {
|
func (db *Database) GetBlogArticle(showAll bool, id int64) (*Article, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user