cpolis/cmd/backend/articles_contributors.go

115 lines
3.2 KiB
Go
Raw Permalink Normal View History

package backend
import (
"fmt"
"log"
)
func (db *DB) WriteArticleContributors(articleID int64, contributorIDs []int64) error {
query := "INSERT INTO articles_contributors (article_id, contributor_id) VALUES (?, ?)"
for i := 0; i < TxMaxRetries; i++ {
err := func() error {
tx, err := db.Begin()
if err != nil {
return fmt.Errorf("error starting transaction: %v", err)
}
for _, contributorID := range contributorIDs {
if _, err := tx.Exec(query, articleID, contributorID); err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil {
log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr)
}
return fmt.Errorf("error inserting into articles_contributors: %v", err)
}
}
if err = tx.Commit(); err != nil {
return fmt.Errorf("error committing transaction: %v", err)
}
return nil
}()
if err == nil {
return nil
}
log.Println(err)
wait(i)
}
return fmt.Errorf("error: %v unsuccessful retries for DB operation, aborting", TxMaxRetries)
}
func (db *DB) GetArticleContributors(c *Config, articleID int64) ([]*User, error) {
query := `
SELECT u.id
FROM articles a
2024-12-27 07:20:24 +01:00
INNER JOIN articles_contributors ac ON a.id = ac.article_id
INNER JOIN users u ON ac.contributor_id = u.id
WHERE a.id = ?
`
rows, err := db.Query(query, articleID)
if err != nil {
return nil, fmt.Errorf("error querying articles_contributors: %v", err)
}
contributors := make([]*User, 0)
for rows.Next() {
var contributorID int64
if err = rows.Scan(&contributorID); err != nil {
return nil, fmt.Errorf("error scanning rows: %v", err)
}
contributor, err := db.GetUser(c, contributorID)
if err != nil {
return nil, fmt.Errorf("error getting user info for article contributor: %v", err)
}
contributors = append(contributors, contributor)
}
return contributors, nil
}
func (db *DB) UpdateArticleContributors(articleID int64, contributorIDs []int64) error {
deleteQuery := "DELETE FROM articles_contributors WHERE article_id = ?"
insertQuery := "INSERT INTO articles_contributors (article_id, contributor_id) VALUES (?, ?)"
for i := 0; i < TxMaxRetries; i++ {
err := func() error {
tx, err := db.Begin()
if err != nil {
return fmt.Errorf("error starting transaction: %v", err)
}
if _, err := tx.Exec(deleteQuery, articleID); err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil {
log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr)
}
return fmt.Errorf("error deleting entries from articles_contributors before inserting new ones: %v", err)
}
for _, contributorID := range contributorIDs {
if _, err := tx.Exec(insertQuery, articleID, contributorID); err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil {
log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr)
}
return fmt.Errorf("error inserting new entries into articles_contributors: %v", err)
}
}
if err = tx.Commit(); err != nil {
return fmt.Errorf("error committing transaction: %v", err)
}
return nil
}()
if err == nil {
return nil
}
log.Println(err)
wait(i)
}
return fmt.Errorf("error: %v unsuccessful retries for DB operation, aborting", TxMaxRetries)
}