Jelajahi Sumber

fix(storage): use <> ALL when counting remaining categories

The guard in RemoveAndReplaceCategoriesByName counted categories with
"title != ANY($2)", which is true whenever the title differs from at
least one element of the array. With two or more titles in the list,
every category matched — including the ones being deleted — so the
"at least 1 category must remain" check could pass even when the
deletion would remove all of the user's categories, leaving feeds
with a NULL category. Using "title <> ALL($2)" counts only the
categories that would actually survive the deletion.
Fred 1 bulan lalu
induk
melakukan
c119273b89
1 mengubah file dengan 4 tambahan dan 3 penghapusan
  1. 4 3
      internal/storage/category.go

+ 4 - 3
internal/storage/category.go

@@ -241,8 +241,9 @@ func (s *Storage) RemoveCategory(userID, categoryID int64) error {
 	return nil
 }
 
-// RemoveAndReplaceCategoriesByName deletes the given categories, replacing those categories with the user's first
-// category on affected feeds.
+// RemoveAndReplaceCategoriesByName deletes categories with the given titles and
+// reassigns affected feeds to the user's first remaining category. It returns
+// an error if the deletion would leave the user without any categories.
 func (s *Storage) RemoveAndReplaceCategoriesByName(userid int64, titles []string) error {
 	tx, err := s.db.Begin()
 	if err != nil {
@@ -251,7 +252,7 @@ func (s *Storage) RemoveAndReplaceCategoriesByName(userid int64, titles []string
 
 	titleParam := pq.Array(titles)
 	var count int
-	query := "SELECT count(*) FROM categories WHERE user_id = $1 and title != ANY($2)"
+	query := "SELECT count(*) FROM categories WHERE user_id = $1 AND title <> ALL($2)"
 	err = tx.QueryRow(query, userid, titleParam).Scan(&count)
 	if err != nil {
 		tx.Rollback()