Converted articles and tags to DB base

This commit is contained in:
2024-03-06 20:53:17 +01:00
parent 052d36b01b
commit 582f25bec7
6 changed files with 154 additions and 245 deletions

View File

@ -1,206 +1,16 @@
package data
import (
"encoding/gob"
"fmt"
"os"
"sync"
"time"
"github.com/google/uuid"
)
type Article struct {
Title string
Author string
Created time.Time
Desc string
Content string
Tags []string
UUID uuid.UUID
AuthorID int64
}
// TODO: setCh
type ArticleList struct {
addCh chan *Article
delCh chan uuid.UUID
getCh chan []Article
retCh chan *Article
articles []*Article
wg sync.WaitGroup
}
// TODO: setCh
type TagList struct {
addCh chan string
getCh chan []string
tags []string
wg sync.WaitGroup
}
func initArticleList() *ArticleList {
return &ArticleList{
addCh: make(chan *Article),
delCh: make(chan uuid.UUID),
getCh: make(chan []Article),
retCh: make(chan *Article),
}
}
func initTagList() *TagList {
return &TagList{
addCh: make(chan string),
getCh: make(chan []string),
}
}
func (al *ArticleList) start() {
al.wg.Done()
for {
select {
case article := <-al.addCh:
al.articles = append(al.articles, article)
case uuid := <-al.delCh:
for i, article := range al.articles {
if article.UUID == uuid {
al.articles = append(al.articles[:i], al.articles[i+1:]...)
al.retCh <- article
}
}
case al.getCh <- func() []Article {
var list []Article
for _, article := range al.articles {
list = append(list, *article)
}
return list
}():
}
}
}
func (tl *TagList) start() {
tl.wg.Done()
for {
select {
case tag := <-tl.addCh:
tl.tags = append(tl.tags, tag)
case tl.getCh <- tl.tags:
}
}
}
func NewArticleList() *ArticleList {
list := initArticleList()
list.articles = make([]*Article, 0)
list.wg.Add(1)
go list.start()
list.wg.Wait()
return list
}
func (al *ArticleList) Add(a *Article) {
al.addCh <- a
}
func (al *ArticleList) Release(uuid uuid.UUID) (*Article, bool) {
al.delCh <- uuid
article := <-al.retCh
if article == nil {
return nil, false
}
return article, true
}
func (al *ArticleList) Get() []Article {
return <-al.getCh
}
func (al *ArticleList) Save(filename string) error {
file, err := os.Create(filename)
if err != nil {
return fmt.Errorf("error creating key file: %v", err)
}
defer file.Close()
articles := al.Get()
if err = gob.NewEncoder(file).Encode(articles); err != nil {
return fmt.Errorf("error ecoding key: %v", err)
}
return nil
}
func LoadArticleList(filename string) (*ArticleList, error) {
file, err := os.Open(filename)
if err != nil {
return nil, fmt.Errorf("error opening key file: %v", err)
}
articleList := initArticleList()
if err = gob.NewDecoder(file).Decode(&articleList.articles); err != nil {
return nil, fmt.Errorf("error decoding key: %v", err)
}
articleList.wg.Add(1)
go articleList.start()
articleList.wg.Wait()
return articleList, nil
}
func NewTagList() *TagList {
list := initTagList()
list.tags = make([]string, 0)
list.wg.Add(1)
go list.start()
list.wg.Wait()
return list
}
func (tl *TagList) Add(tag string) {
tl.addCh <- tag
}
func (tl *TagList) Get() []string {
return <-tl.getCh
}
func (tl *TagList) Save(filename string) error {
file, err := os.Create(filename)
if err != nil {
return fmt.Errorf("error creating key file: %v", err)
}
defer file.Close()
tags := tl.Get()
if err = gob.NewEncoder(file).Encode(tags); err != nil {
return fmt.Errorf("error ecoding key: %v", err)
}
return nil
}
func LoadTagList(filename string) (*TagList, error) {
file, err := os.Open(filename)
if err != nil {
return nil, fmt.Errorf("error opening key file: %v", err)
}
defer file.Close()
tagList := initTagList()
if err = gob.NewDecoder(file).Decode(&tagList.tags); err != nil {
return nil, fmt.Errorf("error decoding key: %v", err)
}
tagList.wg.Add(1)
go tagList.start()
tagList.wg.Wait()
return tagList, nil
Title string
Created time.Time
Desc string
Content string
Tags []string
Published bool
ID int64
AuthorID int64
}

View File

@ -171,3 +171,97 @@ func (db *DB) GetUser(id int64) (*User, error) {
return user, nil
}
func (db *DB) AddTag(tagName string) error {
query := "INSERT INTO tags name VALUES ?"
if _, err := db.Exec(query, tagName); err != nil {
return fmt.Errorf("error inserting tag into DB: %v", err)
}
return nil
}
func (db *DB) GetTagList() ([]Tag, error) {
query := "SELECT id, name FROM tags"
rows, err := db.Query(query)
if err != nil {
return nil, fmt.Errorf("error querying tags: %v", err)
}
var tagList []Tag
for rows.Next() {
var tag Tag
if err = rows.Scan(&tag.ID, &tag.Name); err != nil {
return nil, fmt.Errorf("error scanning tag row: %v", err)
}
tagList = append(tagList, tag)
}
return tagList, nil
}
func (db *DB) AddArticle(a *Article) error {
query := `
INSERT INTO articles
(title, description, content, published, author_id)
VALUES
(?, ?, ?, ?)
`
if _, err := db.Exec(query, a.Title, a.Desc, a.Content, a.Published, a.AuthorID); err != nil {
return fmt.Errorf("error inserting article into DB: %v", err)
}
return nil
}
func (db *DB) GetArticle(id int64) (*Article, error) {
query := `
SELECT title, created, description, content, published, author_id
FROM articles
WHERE id = ?
`
row := db.QueryRow(query, id)
article := new(Article)
if err := row.Scan(&article.Title, &article.Created, &article.Desc,
&article.Content, &article.Published, &article.AuthorID); err != nil {
return nil, fmt.Errorf("error scanning article row: %v", err)
}
return article, nil
}
func (db *DB) GetUnpublishedArticles() ([]Article, error) {
query := `
SELECT id, title, created, description, content, published, author_id
FROM articles
WHERE published = ?
`
rows, err := db.Query(query, false)
if err != nil {
return nil, fmt.Errorf("error querying articles: %v", err)
}
var articleList []Article
for rows.Next() {
var article Article
if err = rows.Scan(&article.ID, &article.Title, &article.Created,
&article.Desc, &article.Content, &article.Published,
&article.AuthorID); err != nil {
return nil, fmt.Errorf("error scanning article row: %v", err)
}
articleList = append(articleList, article)
}
return articleList, nil
}
func (db *DB) UpdateArticle(id int64, attribute string, val interface{}) error {
query := `
UPDATE articles
SET ? = ?
WHERE id = ?
`
if _, err := db.Exec(query, attribute, val, id); err != nil {
return fmt.Errorf("error updating article in DB: %v", err)
}
return nil
}

6
cmd/data/tags.go Normal file
View File

@ -0,0 +1,6 @@
package data
type Tag struct {
ID int64
Name string
}