diff --git a/internal/database/action.go b/internal/database/action.go index a27c7a3..821affa 100644 --- a/internal/database/action.go +++ b/internal/database/action.go @@ -616,12 +616,8 @@ func (r *ActionRepo) Get(ctx context.Context, req *domain.GetActionRequest) (*do } row := r.db.handler.QueryRowContext(ctx, query, args...) - if err != nil { - return nil, errors.Wrap(err, "error executing query") - } - if err := row.Err(); err != nil { - return nil, errors.Wrap(err, "rows error") + return nil, errors.Wrap(err, "error executing query") } var a domain.Action diff --git a/internal/database/api.go b/internal/database/api.go index 256eaaa..e9048fc 100644 --- a/internal/database/api.go +++ b/internal/database/api.go @@ -98,7 +98,6 @@ func (r *APIRepo) GetAllAPIKeys(ctx context.Context) ([]domain.APIKey, error) { if err := rows.Scan(&name, &a.Key, pq.Array(&a.Scopes), &a.CreatedAt); err != nil { return nil, errors.Wrap(err, "error scanning row") - } a.Name = name.String @@ -122,9 +121,6 @@ func (r *APIRepo) GetKey(ctx context.Context, key string) (*domain.APIKey, error row := r.db.handler.QueryRowContext(ctx, query, args...) if err := row.Err(); err != nil { - if errors.Is(err, sql.ErrNoRows) { - return nil, domain.ErrRecordNotFound - } return nil, errors.Wrap(err, "error executing query") } @@ -133,6 +129,10 @@ func (r *APIRepo) GetKey(ctx context.Context, key string) (*domain.APIKey, error var name sql.NullString if err := row.Scan(&name, &apiKey.Key, pq.Array(&apiKey.Scopes), &apiKey.CreatedAt); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, domain.ErrRecordNotFound + } + return nil, errors.Wrap(err, "error scanning row") } diff --git a/internal/database/download_client.go b/internal/database/download_client.go index e0724b4..4832b7a 100644 --- a/internal/database/download_client.go +++ b/internal/database/download_client.go @@ -120,7 +120,7 @@ func (r *DownloadClientRepo) FindByID(ctx context.Context, id int32) (*domain.Do if err := row.Scan(&client.ID, &client.Name, &client.Type, &client.Enabled, &client.Host, &client.Port, &client.TLS, &client.TLSSkipVerify, &client.Username, &client.Password, &settingsJsonStr); err != nil { if errors.Is(err, sql.ErrNoRows) { - return nil, errors.New("no client configured") + return nil, domain.ErrRecordNotFound } return nil, errors.Wrap(err, "error scanning row") diff --git a/internal/database/download_client_test.go b/internal/database/download_client_test.go index f9fb1d2..c5a87b4 100644 --- a/internal/database/download_client_test.go +++ b/internal/database/download_client_test.go @@ -157,7 +157,7 @@ func TestDownloadClientRepo_FindByID(t *testing.T) { t.Run(fmt.Sprintf("FindByID_Fails_With_Nonexistent_ID [%s]", dbType), func(t *testing.T) { _, err := repo.FindByID(context.Background(), 9999) assert.Error(t, err) - assert.Equal(t, "no client configured", err.Error()) + assert.ErrorIs(t, err, domain.ErrRecordNotFound) }) t.Run(fmt.Sprintf("FindByID_Fails_With_Negative_ID [%s]", dbType), func(t *testing.T) { @@ -179,7 +179,7 @@ func TestDownloadClientRepo_FindByID(t *testing.T) { _ = repo.Delete(context.Background(), mock.ID) _, err := repo.FindByID(context.Background(), mock.ID) assert.Error(t, err) - assert.Equal(t, "no client configured", err.Error()) + assert.ErrorIs(t, err, domain.ErrRecordNotFound) // Cleanup _ = repo.Delete(context.Background(), mock.ID) diff --git a/internal/database/feed.go b/internal/database/feed.go index 3a938d7..24f5d22 100644 --- a/internal/database/feed.go +++ b/internal/database/feed.go @@ -68,6 +68,10 @@ func (r *FeedRepo) FindByID(ctx context.Context, id int) (*domain.Feed, error) { var apiKey, cookie, settings sql.NullString if err := row.Scan(&f.ID, &f.Indexer.ID, &f.Indexer.Identifier, &f.Indexer.IdentifierExternal, &f.Indexer.Name, &f.Name, &f.Type, &f.Enabled, &f.URL, &f.Interval, &f.Timeout, &f.MaxAge, &apiKey, &cookie, &settings, &f.CreatedAt, &f.UpdatedAt); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, domain.ErrRecordNotFound + } + return nil, errors.Wrap(err, "error scanning row") } @@ -126,6 +130,10 @@ func (r *FeedRepo) FindByIndexerIdentifier(ctx context.Context, indexer string) var apiKey, cookie, settings sql.NullString if err := row.Scan(&f.ID, &f.Indexer.ID, &f.Indexer.Identifier, &f.Indexer.IdentifierExternal, &f.Indexer.Name, &f.Name, &f.Type, &f.Enabled, &f.URL, &f.Interval, &f.Timeout, &f.MaxAge, &apiKey, &cookie, &settings, &f.CreatedAt, &f.UpdatedAt); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, domain.ErrRecordNotFound + } + return nil, errors.Wrap(err, "error scanning row") } @@ -237,6 +245,10 @@ func (r *FeedRepo) GetLastRunDataByID(ctx context.Context, id int) (string, erro var data sql.NullString if err := row.Scan(&data); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return "", domain.ErrRecordNotFound + } + return "", errors.Wrap(err, "error scanning row") } diff --git a/internal/database/feed_cache.go b/internal/database/feed_cache.go index dbc9fbd..8698b63 100644 --- a/internal/database/feed_cache.go +++ b/internal/database/feed_cache.go @@ -117,7 +117,7 @@ func (r *FeedCacheRepo) GetCountByFeed(ctx context.Context, feedId int) (int, er } row := r.db.handler.QueryRowContext(ctx, query, args...) - if err != nil { + if err := row.Err(); err != nil { return 0, errors.Wrap(err, "error executing query") } diff --git a/internal/database/filter.go b/internal/database/filter.go index e54aa1b..6181e32 100644 --- a/internal/database/filter.go +++ b/internal/database/filter.go @@ -32,26 +32,15 @@ func NewFilterRepo(log logger.Logger, db *DB) domain.FilterRepo { } func (r *FilterRepo) Find(ctx context.Context, params domain.FilterQueryParams) ([]domain.Filter, error) { - tx, err := r.db.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelReadCommitted}) - if err != nil { - return nil, errors.Wrap(err, "error begin transaction") - } - defer tx.Rollback() - - filters, err := r.find(ctx, tx, params) + filters, err := r.find(ctx, params) if err != nil { return nil, err } - if err := tx.Commit(); err != nil { - return nil, errors.Wrap(err, "error commit transaction find releases") - } - return filters, nil } -func (r *FilterRepo) find(ctx context.Context, tx *Tx, params domain.FilterQueryParams) ([]domain.Filter, error) { - +func (r *FilterRepo) find(ctx context.Context, params domain.FilterQueryParams) ([]domain.Filter, error) { actionCountQuery := r.db.squirrel. Select("COUNT(*)"). From("action a"). @@ -104,7 +93,7 @@ func (r *FilterRepo) find(ctx context.Context, tx *Tx, params domain.FilterQuery return nil, errors.Wrap(err, "error building query") } - rows, err := tx.QueryContext(ctx, query, args...) + rows, err := r.db.handler.QueryContext(ctx, query, args...) if err != nil { return nil, errors.Wrap(err, "error executing query") } @@ -1347,6 +1336,10 @@ WHERE (release_action_status.status = 'PUSH_APPROVED' OR release_action_status.s var f domain.FilterDownloads if err := row.Scan(&f.HourCount, &f.DayCount, &f.WeekCount, &f.MonthCount, &f.TotalCount); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, domain.ErrRecordNotFound + } + return nil, errors.Wrap(err, "error scanning stats data sqlite") } @@ -1373,6 +1366,10 @@ WHERE (release_action_status.status = 'PUSH_APPROVED' OR release_action_status.s var f domain.FilterDownloads if err := row.Scan(&f.HourCount, &f.DayCount, &f.WeekCount, &f.MonthCount, &f.TotalCount); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, domain.ErrRecordNotFound + } + return nil, errors.Wrap(err, "error scanning stats data postgres") } diff --git a/internal/database/indexer.go b/internal/database/indexer.go index 78f09e2..80b8e1e 100644 --- a/internal/database/indexer.go +++ b/internal/database/indexer.go @@ -148,6 +148,10 @@ func (r *IndexerRepo) FindByID(ctx context.Context, id int) (*domain.Indexer, er var identifierExternal, implementation, baseURL, settings sql.Null[string] if err := row.Scan(&i.ID, &i.Enabled, &i.Name, &i.Identifier, &identifierExternal, &implementation, &baseURL, &settings); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, domain.ErrRecordNotFound + } + return nil, errors.Wrap(err, "error scanning row") } @@ -193,6 +197,10 @@ func (r *IndexerRepo) GetBy(ctx context.Context, req domain.GetIndexerRequest) ( var identifierExternal, implementation, baseURL, settings sql.Null[string] if err := row.Scan(&i.ID, &i.Enabled, &i.Name, &i.Identifier, &identifierExternal, &implementation, &baseURL, &settings); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, domain.ErrRecordNotFound + } + return nil, errors.Wrap(err, "error scanning row") } diff --git a/internal/database/irc.go b/internal/database/irc.go index 07f395f..4e49b8b 100644 --- a/internal/database/irc.go +++ b/internal/database/irc.go @@ -48,6 +48,10 @@ func (r *IrcRepo) GetNetworkByID(ctx context.Context, id int64) (*domain.IrcNetw row := r.db.handler.QueryRowContext(ctx, query, args...) if err := row.Scan(&n.ID, &n.Enabled, &n.Name, &n.Server, &n.Port, &tls, &pass, &nick, &n.Auth.Mechanism, &account, &password, &inviteCmd, &bouncerAddr, &n.UseBouncer, &n.BotMode); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, domain.ErrRecordNotFound + } + return nil, errors.Wrap(err, "error scanning row") } @@ -253,6 +257,9 @@ func (r *IrcRepo) CheckExistingNetwork(ctx context.Context, network *domain.IrcN r.log.Trace().Str("database", "irc.checkExistingNetwork").Msgf("query: '%s', args: '%v'", query, args) row := r.db.handler.QueryRowContext(ctx, query, args...) + if err := row.Err(); err != nil { + return nil, errors.Wrap(err, "error executing query") + } var net domain.IrcNetwork diff --git a/internal/database/notification.go b/internal/database/notification.go index 82d4676..3891355 100644 --- a/internal/database/notification.go +++ b/internal/database/notification.go @@ -29,7 +29,6 @@ func NewNotificationRepo(log logger.Logger, db *DB) domain.NotificationRepo { } func (r *NotificationRepo) Find(ctx context.Context, params domain.NotificationQueryParams) ([]domain.Notification, int, error) { - queryBuilder := r.db.squirrel. Select("id", "name", "type", "enabled", "events", "webhook", "token", "api_key", "channel", "priority", "topic", "host", "created_at", "updated_at", "COUNT(*) OVER() AS total_count"). From("notification"). @@ -75,7 +74,6 @@ func (r *NotificationRepo) Find(ctx context.Context, params domain.NotificationQ } func (r *NotificationRepo) List(ctx context.Context) ([]domain.Notification, error) { - rows, err := r.db.handler.QueryContext(ctx, "SELECT id, name, type, enabled, events, token, api_key, webhook, title, icon, host, username, password, channel, targets, devices, priority, topic, created_at, updated_at FROM notification ORDER BY name ASC") if err != nil { return nil, errors.Wrap(err, "error executing query") @@ -117,7 +115,6 @@ func (r *NotificationRepo) List(ctx context.Context) ([]domain.Notification, err } func (r *NotificationRepo) FindByID(ctx context.Context, id int) (*domain.Notification, error) { - queryBuilder := r.db.squirrel. Select( "id", @@ -158,6 +155,10 @@ func (r *NotificationRepo) FindByID(ctx context.Context, id int) (*domain.Notifi var token, apiKey, webhook, title, icon, host, username, password, channel, targets, devices, topic sql.NullString if err := row.Scan(&n.ID, &n.Name, &n.Type, &n.Enabled, pq.Array(&n.Events), &token, &apiKey, &webhook, &title, &icon, &host, &username, &password, &channel, &targets, &devices, &n.Priority, &topic, &n.CreatedAt, &n.UpdatedAt); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, domain.ErrRecordNotFound + } + return nil, errors.Wrap(err, "error scanning row") } diff --git a/internal/database/release.go b/internal/database/release.go index f34c713..11559b9 100644 --- a/internal/database/release.go +++ b/internal/database/release.go @@ -423,12 +423,8 @@ func (repo *ReleaseRepo) Get(ctx context.Context, req *domain.GetReleaseRequest) repo.log.Trace().Str("database", "release.find").Msgf("query: '%s', args: '%v'", query, args) row := repo.db.handler.QueryRowContext(ctx, query, args...) - if err != nil { - return nil, errors.Wrap(err, "error executing query") - } - if err := row.Err(); err != nil { - return nil, errors.Wrap(err, "error rows find release") + return nil, errors.Wrap(err, "error executing query") } var rls domain.Release @@ -438,8 +434,9 @@ func (repo *ReleaseRepo) Get(ctx context.Context, req *domain.GetReleaseRequest) if err := row.Scan(&rls.ID, &rls.FilterStatus, pq.Array(&rls.Rejections), &indexerName, &filterName, &filterId, &rls.Protocol, &rls.Implementation, &infoUrl, &downloadUrl, &rls.Title, &rls.TorrentName, &category, &rls.Size, &groupId, &torrentId, &uploader, &rls.Timestamp); err != nil { if errors.Is(err, sql.ErrNoRows) { - return nil, nil + return nil, domain.ErrRecordNotFound } + return nil, errors.Wrap(err, "error scanning row") } @@ -469,13 +466,8 @@ func (repo *ReleaseRepo) GetActionStatus(ctx context.Context, req *domain.GetRel } row := repo.db.handler.QueryRowContext(ctx, query, args...) - if err != nil { - return nil, errors.Wrap(err, "error executing query") - } - if err := row.Err(); err != nil { - repo.log.Error().Stack().Err(err) - return nil, err + return nil, errors.Wrap(err, "error executing query") } var rls domain.ReleaseActionStatus @@ -485,7 +477,7 @@ func (repo *ReleaseRepo) GetActionStatus(ctx context.Context, req *domain.GetRel if err := row.Scan(&rls.ID, &rls.Status, &rls.Action, &actionId, &rls.Type, &client, &filter, &filterId, &rls.ReleaseID, pq.Array(&rls.Rejections), &rls.Timestamp); err != nil { if errors.Is(err, sql.ErrNoRows) { - return nil, nil + return nil, domain.ErrRecordNotFound } return nil, errors.Wrap(err, "error scanning row") @@ -545,7 +537,6 @@ func (repo *ReleaseRepo) attachActionStatus(ctx context.Context, tx *Tx, release } func (repo *ReleaseRepo) Stats(ctx context.Context) (*domain.ReleaseStats, error) { - query := `SELECT * FROM ( SELECT