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. // 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 var result bool
tx.QueryRow(
`SELECT true FROM entries WHERE user_id=$1 AND feed_id=$2 AND hash=$3`, // Note: This query uses entries_feed_id_hash_key index (filtering on user_id is not necessary).
entry.UserID, err := tx.QueryRow(`SELECT true FROM entries WHERE feed_id=$1 AND hash=$2`, entry.FeedID, entry.Hash).Scan(&result)
entry.FeedID,
entry.Hash, if err != nil && err != sql.ErrNoRows {
).Scan(&result) return result, fmt.Errorf(`store: unable to check if entry exists: %v`, err)
return result }
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. // 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) 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 { if updateExistingEntries {
err = s.updateEntry(tx, entry) err = s.updateEntry(tx, entry)
} }
@ -283,7 +293,9 @@ func (s *Storage) RefreshFeedEntries(userID, feedID int64, entries model.Entries
} }
if err != nil { 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 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) 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 { 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 return err
} }
} }