diff --git a/cmd/data/articles.go b/cmd/data/articles.go
index 6fdc370..0b0eb0d 100644
--- a/cmd/data/articles.go
+++ b/cmd/data/articles.go
@@ -9,7 +9,6 @@ type Article struct {
Created time.Time
Desc string
Content string
- Tags []string
Published bool
ID int64
AuthorID int64
diff --git a/cmd/data/db.go b/cmd/data/db.go
index 7d5be05..5c548de 100644
--- a/cmd/data/db.go
+++ b/cmd/data/db.go
@@ -35,6 +35,18 @@ func OpenDB(dbName string) (*DB, error) {
return &db, nil
}
+func (db *DB) UpdateAttribute(table string, id int64, attribute string, val interface{}) error {
+ query := `
+ UPDATE ?
+ SET ? = ?
+ WHERE id = ?
+ `
+ if _, err := db.Exec(query, table, attribute, val, id); err != nil {
+ return fmt.Errorf("error updating article in DB: %v", err)
+ }
+ return nil
+}
+
func (db *DB) AddUser(user *User, pass string) error {
hashedPass, err := bcrypt.GenerateFromPassword([]byte(pass), bcrypt.DefaultCost)
if err != nil {
@@ -173,7 +185,7 @@ func (db *DB) GetUser(id int64) (*User, error) {
}
func (db *DB) AddTag(tagName string) error {
- query := "INSERT INTO tags name VALUES ?"
+ query := "INSERT INTO tags (name) VALUES (?)"
if _, err := db.Exec(query, tagName); err != nil {
return fmt.Errorf("error inserting tag into DB: %v", err)
}
@@ -195,21 +207,31 @@ func (db *DB) GetTagList() ([]Tag, error) {
}
tagList = append(tagList, tag)
}
+ if err = rows.Err(); err != nil {
+ return nil, fmt.Errorf("error iterating through rows: %v", err)
+ }
return tagList, nil
}
-func (db *DB) AddArticle(a *Article) error {
+func (db *DB) AddArticle(a *Article) (int64, 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)
+
+ result, err := db.Exec(query, a.Title, a.Desc, a.Content, a.Published, a.AuthorID)
+ if err != nil {
+ return 0, fmt.Errorf("error inserting article into DB: %v", err)
}
- return nil
+ id, err := result.LastInsertId()
+ if err != nil {
+ return 0, fmt.Errorf("error retrieving last ID: %v", err)
+ }
+
+ return id, nil
}
func (db *DB) GetArticle(id int64) (*Article, error) {
@@ -254,14 +276,27 @@ func (db *DB) GetUnpublishedArticles() ([]Article, error) {
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)
+func (db *DB) WriteArticleTags(articleID int64, tagIDs []int64) error {
+ tx, err := db.Begin()
+ if err != nil {
+ return fmt.Errorf("error starting transaction: %v", err)
+ }
+
+ for _, tagID := range tagIDs {
+ query := `
+ INSERT INTO articles_tags (article_id, tag_id)
+ VALUES (?, ?)
+ `
+ if _, err := tx.Exec(query, articleID, tagID); err != nil {
+ if rollbackErr := tx.Rollback(); rollbackErr != nil {
+ log.Fatalf("error: transaction error: %v, rollback error: %v", err, rollbackErr)
+ }
+ return fmt.Errorf("error inserting into articles_tags: %v", err)
+ }
+ }
+
+ if err = tx.Commit(); err != nil {
+ return fmt.Errorf("error committing transaction: %v", err)
}
return nil
}
diff --git a/cmd/data/tags.go b/cmd/data/tags.go
index 8cb0fff..71361eb 100644
--- a/cmd/data/tags.go
+++ b/cmd/data/tags.go
@@ -1,6 +1,6 @@
package data
type Tag struct {
- ID int64
Name string
+ ID int64
}
diff --git a/cmd/main.go b/cmd/main.go
index b115de6..ac746a7 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -48,7 +48,8 @@ func main() {
store := data.NewCookieStore(key)
mux := http.NewServeMux()
- mux.Handle("/web/static/", http.StripPrefix("/web/static/", http.FileServer(http.Dir("web/static/"))))
+ mux.Handle("/web/static/", http.StripPrefix("/web/static/",
+ http.FileServer(http.Dir("web/static/"))))
mux.HandleFunc("/", ui.HomePage(db, store))
mux.HandleFunc("GET /create-tag/", ui.CreateTag)
diff --git a/cmd/ui/articles.go b/cmd/ui/articles.go
index cb53e04..66551f9 100644
--- a/cmd/ui/articles.go
+++ b/cmd/ui/articles.go
@@ -65,9 +65,6 @@ func FinishArticle(db *data.DB, s *data.CookieStore) http.HandlerFunc {
return
}
- r.ParseForm()
- article.Tags = append(article.Tags, r.Form["tags"]...)
-
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles("web/templates/login.html")
@@ -76,7 +73,29 @@ func FinishArticle(db *data.DB, s *data.CookieStore) http.HandlerFunc {
}
article.AuthorID = session.Values["id"].(int64)
- db.AddArticle(article)
+ article.ID, err = db.AddArticle(article)
+ if err != nil {
+ log.Println(err)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ r.ParseForm()
+ tags := make([]int64, 0)
+ for _, tag := range r.Form["tags"] {
+ tagID, err := strconv.ParseInt(tag, 10, 64)
+ if err != nil {
+ log.Println(err)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ tags = append(tags, tagID)
+ }
+ if err = db.WriteArticleTags(article.ID, tags); err != nil {
+ log.Println(err)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
tmpl, err := template.ParseFiles("web/templates/hub.html")
tmpl = template.Must(tmpl, err)
@@ -135,7 +154,7 @@ func PublishArticle(db *data.DB, c *data.Channel, s *data.CookieStore) http.Hand
return
}
- if err = db.UpdateArticle(id, "published", true); err != nil {
+ if err = db.UpdateAttribute("articles", id, "published", true); err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
@@ -160,7 +179,7 @@ func PublishArticle(db *data.DB, c *data.Channel, s *data.CookieStore) http.Hand
PubDate: article.Created.Format(time.RFC1123Z),
Description: article.Desc,
Content: &rss.Content{Value: article.Content},
- Categories: article.Tags,
+ // Categories: article.Tags,
})
c.Save("tmp/rss.gob")
diff --git a/go.mod b/go.mod
index 184b8a6..e3b1fb3 100644
--- a/go.mod
+++ b/go.mod
@@ -5,8 +5,6 @@ go 1.22.0
require (
git.streifling.com/jason/rss v0.0.0-20240305164907-524bf9676188
github.com/go-sql-driver/mysql v1.7.1
- github.com/google/uuid v1.6.0
- github.com/gorilla/feeds v1.1.2
github.com/gorilla/sessions v1.2.2
github.com/microcosm-cc/bluemonday v1.0.26
github.com/yuin/goldmark v1.7.0
diff --git a/go.sum b/go.sum
index 13ec948..e79d004 100644
--- a/go.sum
+++ b/go.sum
@@ -1,9 +1,3 @@
-git.streifling.com/jason/rss v0.0.0-20240305152729-9d8cc6464565 h1:/eO9NTksh+9yLz3HiYNR7BJo/iMTxxW5/d9h8I6vR6E=
-git.streifling.com/jason/rss v0.0.0-20240305152729-9d8cc6464565/go.mod h1:gpZF0nZbQSstMpyHD9DTAvlQEG7v4pjO5c7aIMWM4Jg=
-git.streifling.com/jason/rss v0.0.0-20240305160544-c8551159fe32 h1:G25NZzsD73rOkGYgV2vPUDviB0JXk5qi+dXOwB6J56U=
-git.streifling.com/jason/rss v0.0.0-20240305160544-c8551159fe32/go.mod h1:gpZF0nZbQSstMpyHD9DTAvlQEG7v4pjO5c7aIMWM4Jg=
-git.streifling.com/jason/rss v0.0.0-20240305160829-6cd08bb65d2a h1:TWQ9gwe7eWjaLUrZ0CJSc+sUUOw3VoGHlR3F8mH6vqs=
-git.streifling.com/jason/rss v0.0.0-20240305160829-6cd08bb65d2a/go.mod h1:gpZF0nZbQSstMpyHD9DTAvlQEG7v4pjO5c7aIMWM4Jg=
git.streifling.com/jason/rss v0.0.0-20240305164907-524bf9676188 h1:C8M/j3f+cl5Y7YfGpU/ynb/SC/4tTYMDsyGFt3rswM8=
git.streifling.com/jason/rss v0.0.0-20240305164907-524bf9676188/go.mod h1:gpZF0nZbQSstMpyHD9DTAvlQEG7v4pjO5c7aIMWM4Jg=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
@@ -12,24 +6,14 @@ github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrt
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
-github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
-github.com/gorilla/feeds v1.1.2 h1:pxzZ5PD3RJdhFH2FsJJ4x6PqMqbgFk1+Vez4XWBW8Iw=
-github.com/gorilla/feeds v1.1.2/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
-github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
-github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
-github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
-github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
-github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA=
github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
diff --git a/web/templates/editor.html b/web/templates/editor.html
index 303e8d6..6401141 100644
--- a/web/templates/editor.html
+++ b/web/templates/editor.html
@@ -5,8 +5,8 @@
{{range .}}
-
-
+
+
{{end}}