From a925cc069ef058de4a3f2bd725c020084362485c Mon Sep 17 00:00:00 2001 From: mkelvers Date: Thu, 11 Jun 2026 13:04:51 +0200 Subject: [PATCH] refactor: shorten init below funlen threshold --- ...0260608_backfill_anime_duration_seconds.go | 128 ++++++++++-------- 1 file changed, 69 insertions(+), 59 deletions(-) diff --git a/internal/database/fixes/20260608_backfill_anime_duration_seconds.go b/internal/database/fixes/20260608_backfill_anime_duration_seconds.go index 0180768..8cc6086 100644 --- a/internal/database/fixes/20260608_backfill_anime_duration_seconds.go +++ b/internal/database/fixes/20260608_backfill_anime_duration_seconds.go @@ -10,72 +10,82 @@ import ( "mal/internal/observability" ) +type animeDurationRow struct { + id int64 + titleOriginal string +} + func init() { Register(Fix{ ID: "20260608_backfill_anime_duration_seconds", - Apply: func(ctx context.Context, sqlDB *sql.DB) error { - rows, err := sqlDB.QueryContext(ctx, ` + Apply: applyAnimeDurationSecondsBackfill, + }) +} + +func applyAnimeDurationSecondsBackfill(ctx context.Context, sqlDB *sql.DB) error { + toUpdate, err := listAnimeMissingDurationSeconds(ctx, sqlDB) + if err != nil { + return err + } + + client := jikan.NewClient(config.Config{}, db.New(sqlDB), observability.NewMetrics()) + for _, row := range toUpdate { + anime, err := client.GetAnimeByID(ctx, int(row.id)) + if err != nil { + return fmt.Errorf("fetch anime %d for duration backfill: %w", row.id, err) + } + + durationSeconds := anime.DurationSeconds() + if durationSeconds <= 0 { + continue + } + + if _, err := sqlDB.ExecContext( + ctx, + `UPDATE anime SET duration_seconds = ? WHERE id = ? AND duration_seconds IS NULL`, + durationSeconds, + row.id, + ); err != nil { + return fmt.Errorf("update anime %d duration_seconds: %w", row.id, err) + } + } + + return nil +} + +func listAnimeMissingDurationSeconds(ctx context.Context, sqlDB *sql.DB) ([]animeDurationRow, error) { + rows, err := sqlDB.QueryContext(ctx, ` SELECT id, title_original, title_english, title_japanese, image_url, airing FROM anime WHERE duration_seconds IS NULL; `) - if err != nil { - return fmt.Errorf("query anime rows missing duration_seconds: %w", err) - } - defer func() { _ = rows.Close() }() + if err != nil { + return nil, fmt.Errorf("query anime rows missing duration_seconds: %w", err) + } + defer func() { _ = rows.Close() }() - client := jikan.NewClient(config.Config{}, db.New(sqlDB), observability.NewMetrics()) + var toUpdate []animeDurationRow + for rows.Next() { + var row animeDurationRow + var titleEnglish sql.NullString + var titleJapanese sql.NullString + var imageURL string + var airing sql.NullBool + if err := rows.Scan( + &row.id, + &row.titleOriginal, + &titleEnglish, + &titleJapanese, + &imageURL, + &airing, + ); err != nil { + return nil, fmt.Errorf("scan anime row missing duration_seconds: %w", err) + } + toUpdate = append(toUpdate, row) + } + if err := rows.Err(); err != nil { + return nil, fmt.Errorf("iterate anime rows missing duration_seconds: %w", err) + } - type animeRow struct { - id int64 - titleOriginal string - } - - var toUpdate []animeRow - for rows.Next() { - var row animeRow - var titleEnglish sql.NullString - var titleJapanese sql.NullString - var imageURL string - var airing sql.NullBool - if err := rows.Scan( - &row.id, - &row.titleOriginal, - &titleEnglish, - &titleJapanese, - &imageURL, - &airing, - ); err != nil { - return fmt.Errorf("scan anime row missing duration_seconds: %w", err) - } - toUpdate = append(toUpdate, row) - } - if err := rows.Err(); err != nil { - return fmt.Errorf("iterate anime rows missing duration_seconds: %w", err) - } - - for _, row := range toUpdate { - anime, err := client.GetAnimeByID(ctx, int(row.id)) - if err != nil { - return fmt.Errorf("fetch anime %d for duration backfill: %w", row.id, err) - } - - durationSeconds := anime.DurationSeconds() - if durationSeconds <= 0 { - continue - } - - if _, err := sqlDB.ExecContext( - ctx, - `UPDATE anime SET duration_seconds = ? WHERE id = ? AND duration_seconds IS NULL`, - durationSeconds, - row.id, - ); err != nil { - return fmt.Errorf("update anime %d duration_seconds: %w", row.id, err) - } - } - - return nil - }, - }) + return toUpdate, nil }