115 lines
3.2 KiB
Go
115 lines
3.2 KiB
Go
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
|
|
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)
|
|
}
|