| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -13,7 +13,6 @@ type Article struct {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					Title         string
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					BannerLink    string
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					Summary       string
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ContentLink   string
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ID            int64
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					AuthorID      int64
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					IssueID       int64
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -30,8 +29,8 @@ func (db *DB) AddArticle(a *Article) (int64, error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					selectQuery := "SELECT id FROM issues WHERE published = false"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					insertQuery := `
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    INSERT INTO articles
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        (title, banner_link, summary, content_link, published, rejected, author_id, issue_id, edited_id, is_in_issue, auto_generated)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        (title, banner_link, summary, published, rejected, author_id, issue_id, edited_id, is_in_issue, auto_generated)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    `
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for i := 0; i < TxMaxRetries; i++ {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -48,7 +47,7 @@ func (db *DB) AddArticle(a *Article) (int64, error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								return 0, fmt.Errorf("error getting issue ID when adding article to DB: %v", err)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							result, err := tx.Exec(insertQuery, a.Title, a.BannerLink, a.Summary, a.ContentLink, a.Published, a.Rejected, a.AuthorID, id, a.EditedID, a.IsInIssue, a.AutoGenerated)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							result, err := tx.Exec(insertQuery, a.Title, a.BannerLink, a.Summary, a.Published, a.Rejected, a.AuthorID, id, a.EditedID, a.IsInIssue, a.AutoGenerated)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if err != nil {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if rollbackErr := tx.Rollback(); rollbackErr != nil {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr)
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -82,7 +81,7 @@ func (db *DB) AddArticle(a *Article) (int64, error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func (db *DB) GetArticle(id int64) (*Article, error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					query := `
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SELECT title, created, banner_link, summary, content_link, published, author_id, issue_id, edited_id, is_in_issue, auto_generated
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SELECT title, created, banner_link, summary, published, author_id, issue_id, edited_id, is_in_issue, auto_generated
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    FROM articles
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    WHERE id = ?
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    `
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -92,7 +91,7 @@ func (db *DB) GetArticle(id int64) (*Article, error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					var created []byte
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					var err error
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if err := row.Scan(&article.Title, &created, &article.BannerLink, &article.Summary, &article.ContentLink, &article.Published, &article.AuthorID, &article.IssueID, &article.EditedID, &article.IsInIssue, &article.AutoGenerated); err != nil {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if err := row.Scan(&article.Title, &created, &article.BannerLink, &article.Summary, &article.Published, &article.AuthorID, &article.IssueID, &article.EditedID, &article.IsInIssue, &article.AutoGenerated); err != nil {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return nil, fmt.Errorf("error scanning article row: %v", err)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -107,7 +106,7 @@ func (db *DB) GetArticle(id int64) (*Article, error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func (db *DB) GetCertainArticles(attribute string, value bool) ([]*Article, error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					query := fmt.Sprintf(`
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SELECT id, title, created, banner_link, summary, content_link, author_id, issue_id, published, rejected, is_in_issue, auto_generated
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SELECT id, title, created, banner_link, summary, author_id, issue_id, published, rejected, is_in_issue, auto_generated
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    FROM articles
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    WHERE %s = ?
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    `, attribute)
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -121,7 +120,7 @@ func (db *DB) GetCertainArticles(attribute string, value bool) ([]*Article, erro
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						article := new(Article)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						var created []byte
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if err = rows.Scan(&article.ID, &article.Title, &created, &article.BannerLink, &article.Summary, &article.ContentLink, &article.AuthorID, &article.IssueID, &article.Published, &article.Rejected, &article.IsInIssue, &article.AutoGenerated); err != nil {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if err = rows.Scan(&article.ID, &article.Title, &created, &article.BannerLink, &article.Summary, &article.AuthorID, &article.IssueID, &article.Published, &article.Rejected, &article.IsInIssue, &article.AutoGenerated); err != nil {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return nil, fmt.Errorf("error scanning article row: %v", err)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -141,7 +140,7 @@ func (db *DB) GetCurrentIssueArticles() ([]*Article, error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					txOptions := &sql.TxOptions{Isolation: sql.LevelSerializable}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					issueQuery := "SELECT id FROM issues WHERE published = false"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					articlesQuery := `
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SELECT id, title, created, banner_link, summary, content_link, author_id, auto_generated
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SELECT id, title, created, banner_link, summary, author_id, auto_generated
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    FROM articles
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    WHERE issue_id = ? AND published = true AND is_in_issue = true
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    `
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -174,7 +173,7 @@ func (db *DB) GetCurrentIssueArticles() ([]*Article, error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								article := new(Article)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								var created []byte
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if err = rows.Scan(&article.ID, &article.Title, &created, &article.BannerLink, &article.Summary, &article.ContentLink, &article.AuthorID, &article.AutoGenerated); err != nil {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if err = rows.Scan(&article.ID, &article.Title, &created, &article.BannerLink, &article.Summary, &article.AuthorID, &article.AutoGenerated); err != nil {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									if rollbackErr := tx.Rollback(); rollbackErr != nil {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									}
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |