Improve entry existance check to make better use of index

This commit is contained in:
Frédéric Guillot 2023-06-24 12:56:53 -07:00
parent b552c293ca
commit aadbd5adf3
2 changed files with 34 additions and 12 deletions

View File

@ -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
}

View File

@ -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
}
}