Browse Source

Improve entry existance check to make better use of index

Frédéric Guillot 2 years ago
parent
commit
aadbd5adf3
2 changed files with 34 additions and 12 deletions
  1. 22 10
      storage/entry.go
  2. 12 2
      storage/feed.go

+ 22 - 10
storage/entry.go

@@ -219,15 +219,17 @@ func (s *Storage) updateEntry(tx *sql.Tx, entry *model.Entry) error {
 }
 
 // entryExists checks if an entry already exists based on its hash when refreshing a feed.
-func (s *Storage) entryExists(tx *sql.Tx, entry *model.Entry) bool {
+func (s *Storage) entryExists(tx *sql.Tx, entry *model.Entry) (bool, error) {
 	var result bool
-	tx.QueryRow(
-		`SELECT true FROM entries WHERE user_id=$1 AND feed_id=$2 AND hash=$3`,
-		entry.UserID,
-		entry.FeedID,
-		entry.Hash,
-	).Scan(&result)
-	return result
+
+	// Note: This query uses entries_feed_id_hash_key index (filtering on user_id is not necessary).
+	err := tx.QueryRow(`SELECT true FROM entries WHERE feed_id=$1 AND hash=$2`, entry.FeedID, entry.Hash).Scan(&result)
+
+	if err != nil && err != sql.ErrNoRows {
+		return result, fmt.Errorf(`store: unable to check if entry exists: %v`, err)
+	}
+
+	return result, nil
 }
 
 // GetReadTime fetches the read time of an entry based on its hash, and the feed id and user id from the feed.
@@ -274,7 +276,15 @@ func (s *Storage) RefreshFeedEntries(userID, feedID int64, entries model.Entries
 			return fmt.Errorf(`store: unable to start transaction: %v`, err)
 		}
 
-		if s.entryExists(tx, entry) {
+		entryExists, err := s.entryExists(tx, entry)
+		if err != nil {
+			if rollbackErr := tx.Rollback(); rollbackErr != nil {
+				return fmt.Errorf(`store: unable to rollback transaction: %v (rolled back due to: %v)`, rollbackErr, err)
+			}
+			return err
+		}
+
+		if entryExists {
 			if updateExistingEntries {
 				err = s.updateEntry(tx, entry)
 			}
@@ -283,7 +293,9 @@ func (s *Storage) RefreshFeedEntries(userID, feedID int64, entries model.Entries
 		}
 
 		if err != nil {
-			tx.Rollback()
+			if rollbackErr := tx.Rollback(); rollbackErr != nil {
+				return fmt.Errorf(`store: unable to rollback transaction: %v (rolled back due to: %v)`, rollbackErr, err)
+			}
 			return err
 		}
 

+ 12 - 2
storage/feed.go

@@ -286,9 +286,19 @@ func (s *Storage) CreateFeed(feed *model.Feed) error {
 			return fmt.Errorf(`store: unable to start transaction: %v`, err)
 		}
 
-		if !s.entryExists(tx, feed.Entries[i]) {
+		entryExists, err := s.entryExists(tx, feed.Entries[i])
+		if err != nil {
+			if rollbackErr := tx.Rollback(); rollbackErr != nil {
+				return fmt.Errorf(`store: unable to rollback transaction: %v (rolled back due to: %v)`, rollbackErr, err)
+			}
+			return err
+		}
+
+		if !entryExists {
 			if err := s.createEntry(tx, feed.Entries[i]); err != nil {
-				tx.Rollback()
+				if rollbackErr := tx.Rollback(); rollbackErr != nil {
+					return fmt.Errorf(`store: unable to rollback transaction: %v (rolled back due to: %v)`, rollbackErr, err)
+				}
 				return err
 			}
 		}