refactor(migrations): propagate context.Context through all DB calls

Thread the context.Context that goose.UpContext already passes into every
migration through to all DB calls: tx.Exec/Query/QueryRow become
tx.ExecContext/QueryContext/QueryRowContext with ctx. The shared helpers in
migration.go (notice, forceFullRescan, isDBInitialized) gain a ctx parameter
and all call sites are updated. No-op migration functions use blank params
(_ context.Context, _ *sql.Tx).

This is a behavior-preserving change: the SQL, arguments, and ordering of every
migration are unchanged; only cancellation/deadline propagation is added.

Add a forbidigo lint rule scoped to db/migrations/ that forbids the
non-context tx.Exec/Query/QueryRow forms, preventing regression.

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan
2026-06-18 09:50:26 -04:00
parent 6abc2ed517
commit 32ac53dc9f
84 changed files with 327 additions and 315 deletions
+12
View File
@@ -13,6 +13,7 @@ linters:
- dogsled
- durationcheck
- errorlint
- forbidigo
- gocritic
- gocyclo
- goprintffuncname
@@ -36,6 +37,14 @@ linters:
- G401
- G505
- G115
forbidigo:
forbid:
- pattern: 'tx\.Exec$'
msg: "use tx.ExecContext(ctx, ...) in migrations to propagate context"
- pattern: 'tx\.Query$'
msg: "use tx.QueryContext(ctx, ...) in migrations to propagate context"
- pattern: 'tx\.QueryRow$'
msg: "use tx.QueryRowContext(ctx, ...) in migrations to propagate context"
govet:
enable:
- nilness
@@ -45,6 +54,9 @@ linters:
- gosec
path: _test\.go
text: "G703"
- path-except: 'db/migrations/'
linters:
- forbidigo
generated: lax
presets:
- comments
@@ -12,9 +12,9 @@ func init() {
goose.AddMigrationContext(Up20200130083147, Down20200130083147)
}
func Up20200130083147(_ context.Context, tx *sql.Tx) error {
func Up20200130083147(ctx context.Context, tx *sql.Tx) error {
log.Info("Creating DB Schema")
_, err := tx.Exec(`
_, err := tx.ExecContext(ctx, `
create table if not exists album
(
id varchar(255) not null
@@ -179,6 +179,6 @@ create table if not exists user
return err
}
func Down20200130083147(_ context.Context, tx *sql.Tx) error {
func Down20200130083147(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20200131183653, Down20200131183653)
}
func Up20200131183653(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200131183653(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table search_dg_tmp
(
id varchar(255) not null
@@ -37,8 +37,8 @@ update annotation set item_type = 'media_file' where item_type = 'mediaFile';
return err
}
func Down20200131183653(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Down20200131183653(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table search_dg_tmp
(
id varchar(255) not null
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20200208222418, Down20200208222418)
}
func Up20200208222418(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200208222418(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
update annotation set play_count = 0 where play_count is null;
update annotation set rating = 0 where rating is null;
create table annotation_dg_tmp
@@ -51,6 +51,6 @@ create index annotation_starred
return err
}
func Down20200208222418(_ context.Context, tx *sql.Tx) error {
func Down20200208222418(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,9 +11,9 @@ func init() {
goose.AddMigrationContext(Up20200220143731, Down20200220143731)
}
func Up20200220143731(_ context.Context, tx *sql.Tx) error {
notice(tx, "This migration will force the next scan to be a full rescan!")
_, err := tx.Exec(`
func Up20200220143731(ctx context.Context, tx *sql.Tx) error {
notice(ctx, tx, "This migration will force the next scan to be a full rescan!")
_, err := tx.ExecContext(ctx, `
create table media_file_dg_tmp
(
id varchar(255) not null
@@ -125,6 +125,6 @@ update media_file set updated_at = '0001-01-01';
return err
}
func Down20200220143731(_ context.Context, tx *sql.Tx) error {
func Down20200220143731(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,11 +11,11 @@ func init() {
goose.AddMigrationContext(Up20200310171621, Down20200310171621)
}
func Up20200310171621(_ context.Context, tx *sql.Tx) error {
notice(tx, "A full rescan will be performed to enable search by Album Artist!")
return forceFullRescan(tx)
func Up20200310171621(ctx context.Context, tx *sql.Tx) error {
notice(ctx, tx, "A full rescan will be performed to enable search by Album Artist!")
return forceFullRescan(ctx, tx)
}
func Down20200310171621(_ context.Context, tx *sql.Tx) error {
func Down20200310171621(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20200310181627, Down20200310181627)
}
func Up20200310181627(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200310181627(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table transcoding
(
id varchar(255) not null primary key,
@@ -45,8 +45,8 @@ create table player
return err
}
func Down20200310181627(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Down20200310181627(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
drop table transcoding;
drop table player;
`)
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20200319211049, Down20200319211049)
}
func Up20200319211049(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200319211049(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table media_file
add full_text varchar(255) default '';
create index if not exists media_file_full_text
@@ -33,10 +33,10 @@ drop table if exists search;
if err != nil {
return err
}
notice(tx, "A full rescan will be performed!")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan will be performed!")
return forceFullRescan(ctx, tx)
}
func Down20200319211049(_ context.Context, tx *sql.Tx) error {
func Down20200319211049(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20200325185135, Down20200325185135)
}
func Up20200325185135(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200325185135(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table album
add album_artist_id varchar(255) default '';
create index album_artist_album_id
@@ -26,10 +26,10 @@ create index media_file_artist_album_id
if err != nil {
return err
}
notice(tx, "A full rescan will be performed!")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan will be performed!")
return forceFullRescan(ctx, tx)
}
func Down20200325185135(_ context.Context, tx *sql.Tx) error {
func Down20200325185135(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,11 +11,11 @@ func init() {
goose.AddMigrationContext(Up20200326090707, Down20200326090707)
}
func Up20200326090707(_ context.Context, tx *sql.Tx) error {
notice(tx, "A full rescan will be performed!")
return forceFullRescan(tx)
func Up20200326090707(ctx context.Context, tx *sql.Tx) error {
notice(ctx, tx, "A full rescan will be performed!")
return forceFullRescan(ctx, tx)
}
func Down20200326090707(_ context.Context, tx *sql.Tx) error {
func Down20200326090707(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20200327193744, Down20200327193744)
}
func Up20200327193744(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200327193744(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table album_dg_tmp
(
id varchar(255) not null
@@ -72,10 +72,10 @@ create index album_max_year
if err != nil {
return err
}
notice(tx, "A full rescan will be performed!")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan will be performed!")
return forceFullRescan(ctx, tx)
}
func Down20200327193744(_ context.Context, tx *sql.Tx) error {
func Down20200327193744(_ context.Context, _ *sql.Tx) error {
return nil
}
+3 -3
View File
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20200404214704, Down20200404214704)
}
func Up20200404214704(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200404214704(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create index if not exists media_file_year
on media_file (year);
@@ -25,6 +25,6 @@ create index if not exists media_file_track_number
return err
}
func Down20200404214704(_ context.Context, tx *sql.Tx) error {
func Down20200404214704(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,11 +11,11 @@ func init() {
goose.AddMigrationContext(Up20200409002249, Down20200409002249)
}
func Up20200409002249(_ context.Context, tx *sql.Tx) error {
notice(tx, "A full rescan will be performed to enable search by individual Artist in an Album!")
return forceFullRescan(tx)
func Up20200409002249(ctx context.Context, tx *sql.Tx) error {
notice(ctx, tx, "A full rescan will be performed to enable search by individual Artist in an Album!")
return forceFullRescan(ctx, tx)
}
func Down20200409002249(_ context.Context, tx *sql.Tx) error {
func Down20200409002249(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20200411164603, Down20200411164603)
}
func Up20200411164603(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200411164603(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table playlist
add created_at datetime;
alter table playlist
@@ -23,6 +23,6 @@ update playlist
return err
}
func Down20200411164603(_ context.Context, tx *sql.Tx) error {
func Down20200411164603(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,11 +11,11 @@ func init() {
goose.AddMigrationContext(Up20200418110522, Down20200418110522)
}
func Up20200418110522(_ context.Context, tx *sql.Tx) error {
notice(tx, "A full rescan will be performed to fix search Albums by year")
return forceFullRescan(tx)
func Up20200418110522(ctx context.Context, tx *sql.Tx) error {
notice(ctx, tx, "A full rescan will be performed to fix search Albums by year")
return forceFullRescan(ctx, tx)
}
func Down20200418110522(_ context.Context, tx *sql.Tx) error {
func Down20200418110522(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,11 +11,11 @@ func init() {
goose.AddMigrationContext(Up20200419222708, Down20200419222708)
}
func Up20200419222708(_ context.Context, tx *sql.Tx) error {
notice(tx, "A full rescan will be performed to change the search behaviour")
return forceFullRescan(tx)
func Up20200419222708(ctx context.Context, tx *sql.Tx) error {
notice(ctx, tx, "A full rescan will be performed to change the search behaviour")
return forceFullRescan(ctx, tx)
}
func Down20200419222708(_ context.Context, tx *sql.Tx) error {
func Down20200419222708(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20200423204116, Down20200423204116)
}
func Up20200423204116(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200423204116(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table artist
add order_artist_name varchar(255) collate nocase;
alter table artist
@@ -57,10 +57,10 @@ create index if not exists media_file_order_artist_name
if err != nil {
return err
}
notice(tx, "A full rescan will be performed to change the search behaviour")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan will be performed to change the search behaviour")
return forceFullRescan(ctx, tx)
}
func Down20200423204116(_ context.Context, tx *sql.Tx) error {
func Down20200423204116(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,18 +11,18 @@ func init() {
goose.AddMigrationContext(Up20200508093059, Down20200508093059)
}
func Up20200508093059(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200508093059(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table artist
add song_count integer default 0 not null;
`)
if err != nil {
return err
}
notice(tx, "A full rescan will be performed to calculate artists' song counts")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan will be performed to calculate artists' song counts")
return forceFullRescan(ctx, tx)
}
func Down20200508093059(_ context.Context, tx *sql.Tx) error {
func Down20200508093059(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,18 +11,18 @@ func init() {
goose.AddMigrationContext(Up20200512104202, Down20200512104202)
}
func Up20200512104202(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200512104202(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table media_file
add disc_subtitle varchar(255);
`)
if err != nil {
return err
}
notice(tx, "A full rescan will be performed to import disc subtitles")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan will be performed to import disc subtitles")
return forceFullRescan(ctx, tx)
}
func Down20200512104202(_ context.Context, tx *sql.Tx) error {
func Down20200512104202(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -13,8 +13,8 @@ func init() {
goose.AddMigrationContext(Up20200516140647, Down20200516140647)
}
func Up20200516140647(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20200516140647(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table if not exists playlist_tracks
(
id integer default 0 not null,
@@ -28,7 +28,7 @@ create unique index if not exists playlist_tracks_pos
if err != nil {
return err
}
rows, err := tx.Query("select id, tracks from playlist")
rows, err := tx.QueryContext(ctx, "select id, tracks from playlist")
if err != nil {
return err
}
@@ -49,7 +49,7 @@ create unique index if not exists playlist_tracks_pos
return err
}
_, err = tx.Exec(`
_, err = tx.ExecContext(ctx, `
create table playlist_dg_tmp
(
id varchar(255) not null
@@ -96,6 +96,6 @@ func Up20200516140647UpdatePlaylistTracks(tx *sql.Tx, id string, tracks string)
return nil
}
func Down20200516140647(_ context.Context, tx *sql.Tx) error {
func Down20200516140647(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,46 +11,46 @@ func init() {
goose.AddMigrationContext(Up20200608153717, Down20200608153717)
}
func Up20200608153717(_ context.Context, tx *sql.Tx) error {
func Up20200608153717(ctx context.Context, tx *sql.Tx) error {
// First delete dangling players
_, err := tx.Exec(`
_, err := tx.ExecContext(ctx, `
delete from player where user_name not in (select user_name from user)`)
if err != nil {
return err
}
// Also delete dangling players
_, err = tx.Exec(`
_, err = tx.ExecContext(ctx, `
delete from playlist where owner not in (select user_name from user)`)
if err != nil {
return err
}
// Also delete dangling playlist tracks
_, err = tx.Exec(`
_, err = tx.ExecContext(ctx, `
delete from playlist_tracks where playlist_id not in (select id from playlist)`)
if err != nil {
return err
}
// Add foreign key to player table
err = updatePlayer_20200608153717(tx)
err = updatePlayer_20200608153717(ctx, tx)
if err != nil {
return err
}
// Add foreign key to playlist table
err = updatePlaylist_20200608153717(tx)
err = updatePlaylist_20200608153717(ctx, tx)
if err != nil {
return err
}
// Add foreign keys to playlist_tracks table
return updatePlaylistTracks_20200608153717(tx)
return updatePlaylistTracks_20200608153717(ctx, tx)
}
func updatePlayer_20200608153717(tx *sql.Tx) error {
_, err := tx.Exec(`
func updatePlayer_20200608153717(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table player_dg_tmp
(
id varchar(255) not null
@@ -77,8 +77,8 @@ alter table player_dg_tmp rename to player;
return err
}
func updatePlaylist_20200608153717(tx *sql.Tx) error {
_, err := tx.Exec(`
func updatePlaylist_20200608153717(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table playlist_dg_tmp
(
id varchar(255) not null
@@ -108,8 +108,8 @@ create index playlist_name
return err
}
func updatePlaylistTracks_20200608153717(tx *sql.Tx) error {
_, err := tx.Exec(`
func updatePlaylistTracks_20200608153717(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table playlist_tracks_dg_tmp
(
id integer default 0 not null,
@@ -133,6 +133,6 @@ create unique index playlist_tracks_pos
return err
}
func Down20200608153717(_ context.Context, tx *sql.Tx) error {
func Down20200608153717(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -13,8 +13,8 @@ func init() {
goose.AddMigrationContext(upAddDefaultTranscodings, downAddDefaultTranscodings)
}
func upAddDefaultTranscodings(_ context.Context, tx *sql.Tx) error {
row := tx.QueryRow("SELECT COUNT(*) FROM transcoding")
func upAddDefaultTranscodings(ctx context.Context, tx *sql.Tx) error {
row := tx.QueryRowContext(ctx, "SELECT COUNT(*) FROM transcoding")
var count int
err := row.Scan(&count)
if err != nil {
@@ -38,6 +38,6 @@ func upAddDefaultTranscodings(_ context.Context, tx *sql.Tx) error {
return nil
}
func downAddDefaultTranscodings(_ context.Context, tx *sql.Tx) error {
func downAddDefaultTranscodings(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddPlaylistPath, downAddPlaylistPath)
}
func upAddPlaylistPath(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddPlaylistPath(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table playlist
add path string default '' not null;
@@ -23,6 +23,6 @@ alter table playlist
return err
}
func downAddPlaylistPath(_ context.Context, tx *sql.Tx) error {
func downAddPlaylistPath(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upCreatePlayQueuesTable, downCreatePlayQueuesTable)
}
func upCreatePlayQueuesTable(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upCreatePlayQueuesTable(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table playqueue
(
id varchar(255) not null primary key,
@@ -32,6 +32,6 @@ create table playqueue
return err
}
func downCreatePlayQueuesTable(_ context.Context, tx *sql.Tx) error {
func downCreatePlayQueuesTable(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upCreateBookmarkTable, downCreateBookmarkTable)
}
func upCreateBookmarkTable(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upCreateBookmarkTable(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table bookmark
(
user_id varchar(255) not null
@@ -49,6 +49,6 @@ alter table playqueue_dg_tmp rename to playqueue;
return err
}
func downCreateBookmarkTable(_ context.Context, tx *sql.Tx) error {
func downCreateBookmarkTable(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upDropEmailUniqueConstraint, downDropEmailUniqueConstraint)
}
func upDropEmailUniqueConstraint(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upDropEmailUniqueConstraint(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table user_dg_tmp
(
id varchar(255) not null
@@ -38,6 +38,6 @@ alter table user_dg_tmp rename to user;
return err
}
func downDropEmailUniqueConstraint(_ context.Context, tx *sql.Tx) error {
func downDropEmailUniqueConstraint(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,14 +11,14 @@ func init() {
goose.AddMigrationContext(Up20201003111749, Down20201003111749)
}
func Up20201003111749(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20201003111749(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create index if not exists annotation_starred_at
on annotation (starred_at);
`)
return err
}
func Down20201003111749(_ context.Context, tx *sql.Tx) error {
func Down20201003111749(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20201010162350, Down20201010162350)
}
func Up20201010162350(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20201010162350(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table album
add size integer default 0 not null;
create index if not exists album_size
@@ -28,7 +28,7 @@ where id not null;`)
return err
}
func Down20201010162350(_ context.Context, tx *sql.Tx) error {
func Down20201010162350(ctx context.Context, tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20201012210022, Down20201012210022)
}
func Up20201012210022(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20201012210022(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table artist
add size integer default 0 not null;
create index if not exists artist_size
@@ -40,6 +40,6 @@ update playlist set size = ifnull((
return err
}
func Down20201012210022(_ context.Context, tx *sql.Tx) error {
func Down20201012210022(_ context.Context, _ *sql.Tx) error {
return nil
}
+5 -5
View File
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20201021085410, Down20201021085410)
}
func Up20201021085410(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20201021085410(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table media_file
add mbz_track_id varchar(255);
alter table media_file
@@ -49,11 +49,11 @@ alter table artist
if err != nil {
return err
}
notice(tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(ctx, tx)
}
func Down20201021085410(_ context.Context, tx *sql.Tx) error {
func Down20201021085410(ctx context.Context, tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20201021093209, Down20201021093209)
}
func Up20201021093209(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20201021093209(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create index if not exists media_file_artist
on media_file (artist);
create index if not exists media_file_album_artist
@@ -23,6 +23,6 @@ create index if not exists media_file_mbz_track_id
return err
}
func Down20201021093209(_ context.Context, tx *sql.Tx) error {
func Down20201021093209(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,14 +11,14 @@ func init() {
goose.AddMigrationContext(Up20201021135455, Down20201021135455)
}
func Up20201021135455(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20201021135455(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create index if not exists media_file_artist_id
on media_file (artist_id);
`)
return err
}
func Down20201021135455(_ context.Context, tx *sql.Tx) error {
func Down20201021135455(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddArtistImageUrl, downAddArtistImageUrl)
}
func upAddArtistImageUrl(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddArtistImageUrl(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table artist
add biography varchar(255) default '' not null;
alter table artist
@@ -31,6 +31,6 @@ alter table artist
return err
}
func downAddArtistImageUrl(_ context.Context, tx *sql.Tx) error {
func downAddArtistImageUrl(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(Up20201110205344, Down20201110205344)
}
func Up20201110205344(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20201110205344(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table media_file
add comment varchar;
alter table media_file
@@ -24,10 +24,10 @@ alter table album
if err != nil {
return err
}
notice(tx, "A full rescan will be performed to import comments and lyrics")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan will be performed to import comments and lyrics")
return forceFullRescan(ctx, tx)
}
func Down20201110205344(_ context.Context, tx *sql.Tx) error {
func Down20201110205344(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,14 +11,14 @@ func init() {
goose.AddMigrationContext(Up20201128100726, Down20201128100726)
}
func Up20201128100726(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20201128100726(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table player
add report_real_path bool default FALSE not null;
`)
return err
}
func Down20201128100726(_ context.Context, tx *sql.Tx) error {
func Down20201128100726(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -13,8 +13,8 @@ func init() {
goose.AddMigrationContext(Up20201213124814, Down20201213124814)
}
func Up20201213124814(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func Up20201213124814(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table album
add all_artist_ids varchar;
@@ -25,11 +25,11 @@ create index if not exists album_all_artist_ids
return err
}
return updateAlbums20201213124814(tx)
return updateAlbums20201213124814(ctx, tx)
}
func updateAlbums20201213124814(tx *sql.Tx) error {
rows, err := tx.Query(`
func updateAlbums20201213124814(ctx context.Context, tx *sql.Tx) error {
rows, err := tx.QueryContext(ctx, `
select a.id, a.name, a.artist_id, a.album_artist_id, group_concat(mf.artist_id, ' ')
from album a left join media_file mf on a.id = mf.album_id group by a.id
`)
@@ -59,6 +59,6 @@ select a.id, a.name, a.artist_id, a.album_artist_id, group_concat(mf.artist_id,
return rows.Err()
}
func Down20201213124814(_ context.Context, tx *sql.Tx) error {
func Down20201213124814(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddTimestampIndexesGo, downAddTimestampIndexesGo)
}
func upAddTimestampIndexesGo(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddTimestampIndexesGo(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create index if not exists album_updated_at
on album (updated_at);
create index if not exists album_created_at
@@ -29,6 +29,6 @@ create index if not exists media_file_updated_at
return err
}
func downAddTimestampIndexesGo(_ context.Context, tx *sql.Tx) error {
func downAddTimestampIndexesGo(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -14,10 +14,10 @@ func init() {
goose.AddMigrationContext(upFixAlbumComments, downFixAlbumComments)
}
func upFixAlbumComments(_ context.Context, tx *sql.Tx) error {
func upFixAlbumComments(ctx context.Context, tx *sql.Tx) error {
//nolint:gosec
rows, err := tx.Query(`
SELECT album.id, group_concat(media_file.comment, '` + consts.Zwsp + `') FROM album, media_file WHERE media_file.album_id = album.id GROUP BY album.id;
rows, err := tx.QueryContext(ctx, `
SELECT album.id, group_concat(media_file.comment, '`+consts.Zwsp+`') FROM album, media_file WHERE media_file.album_id = album.id GROUP BY album.id;
`)
if err != nil {
return err
@@ -49,7 +49,7 @@ func upFixAlbumComments(_ context.Context, tx *sql.Tx) error {
return rows.Err()
}
func downFixAlbumComments(_ context.Context, tx *sql.Tx) error {
func downFixAlbumComments(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddBpmMetadata, downAddBpmMetadata)
}
func upAddBpmMetadata(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddBpmMetadata(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table media_file
add bpm integer;
@@ -22,10 +22,10 @@ create index if not exists media_file_bpm
if err != nil {
return err
}
notice(tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(ctx, tx)
}
func downAddBpmMetadata(_ context.Context, tx *sql.Tx) error {
func downAddBpmMetadata(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upCreateSharesTable, downCreateSharesTable)
}
func upCreateSharesTable(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upCreateSharesTable(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table share
(
id varchar(255) not null primary key,
@@ -30,6 +30,6 @@ create table share
return err
}
func downCreateSharesTable(_ context.Context, tx *sql.Tx) error {
func downCreateSharesTable(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upUpdateShareFieldNames, downUpdateShareFieldNames)
}
func upUpdateShareFieldNames(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upUpdateShareFieldNames(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table share rename column expires to expires_at;
alter table share rename column created to created_at;
alter table share rename column last_visited to last_visited_at;
@@ -21,6 +21,6 @@ alter table share rename column last_visited to last_visited_at;
return err
}
func downUpdateShareFieldNames(_ context.Context, tx *sql.Tx) error {
func downUpdateShareFieldNames(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -16,7 +16,7 @@ func init() {
}
func upEncodeAllPasswords(ctx context.Context, tx *sql.Tx) error {
rows, err := tx.Query(`SELECT id, user_name, password from user;`)
rows, err := tx.QueryContext(ctx, `SELECT id, user_name, password from user;`)
if err != nil {
return err
}
@@ -51,6 +51,6 @@ func upEncodeAllPasswords(ctx context.Context, tx *sql.Tx) error {
return rows.Err()
}
func downEncodeAllPasswords(_ context.Context, tx *sql.Tx) error {
func downEncodeAllPasswords(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upDropPlayerNameUniqueConstraint, downDropPlayerNameUniqueConstraint)
}
func upDropPlayerNameUniqueConstraint(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upDropPlayerNameUniqueConstraint(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table player_dg_tmp
(
id varchar(255) not null
@@ -43,6 +43,6 @@ create index if not exists player_name
return err
}
func downDropPlayerNameUniqueConstraint(_ context.Context, tx *sql.Tx) error {
func downDropPlayerNameUniqueConstraint(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,16 +11,16 @@ func init() {
goose.AddMigrationContext(upAddUserPrefsPlayerScrobblerEnabled, downAddUserPrefsPlayerScrobblerEnabled)
}
func upAddUserPrefsPlayerScrobblerEnabled(_ context.Context, tx *sql.Tx) error {
err := upAddUserPrefs(tx)
func upAddUserPrefsPlayerScrobblerEnabled(ctx context.Context, tx *sql.Tx) error {
err := upAddUserPrefs(ctx, tx)
if err != nil {
return err
}
return upPlayerScrobblerEnabled(tx)
return upPlayerScrobblerEnabled(ctx, tx)
}
func upAddUserPrefs(tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddUserPrefs(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table user_props
(
user_id varchar not null,
@@ -33,13 +33,13 @@ create table user_props
return err
}
func upPlayerScrobblerEnabled(tx *sql.Tx) error {
_, err := tx.Exec(`
func upPlayerScrobblerEnabled(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table player add scrobble_enabled bool default true;
`)
return err
}
func downAddUserPrefsPlayerScrobblerEnabled(_ context.Context, tx *sql.Tx) error {
func downAddUserPrefsPlayerScrobblerEnabled(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddReferentialIntegrityToUserProps, downAddReferentialIntegrityToUserProps)
}
func upAddReferentialIntegrityToUserProps(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddReferentialIntegrityToUserProps(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table user_props_dg_tmp
(
user_id varchar not null
@@ -34,6 +34,6 @@ alter table user_props_dg_tmp rename to user_props;
return err
}
func downAddReferentialIntegrityToUserProps(_ context.Context, tx *sql.Tx) error {
func downAddReferentialIntegrityToUserProps(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddScrobbleBuffer, downAddScrobbleBuffer)
}
func upAddScrobbleBuffer(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddScrobbleBuffer(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table if not exists scrobble_buffer
(
user_id varchar not null
@@ -34,6 +34,6 @@ create table if not exists scrobble_buffer
return err
}
func downAddScrobbleBuffer(_ context.Context, tx *sql.Tx) error {
func downAddScrobbleBuffer(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,9 +11,9 @@ func init() {
goose.AddMigrationContext(upAddGenreTables, downAddGenreTables)
}
func upAddGenreTables(_ context.Context, tx *sql.Tx) error {
notice(tx, "A full rescan will be performed to import multiple genres!")
_, err := tx.Exec(`
func upAddGenreTables(ctx context.Context, tx *sql.Tx) error {
notice(ctx, tx, "A full rescan will be performed to import multiple genres!")
_, err := tx.ExecContext(ctx, `
create table if not exists genre
(
id varchar not null primary key,
@@ -61,9 +61,9 @@ create table if not exists artist_genres
if err != nil {
return err
}
return forceFullRescan(tx)
return forceFullRescan(ctx, tx)
}
func downAddGenreTables(_ context.Context, tx *sql.Tx) error {
func downAddGenreTables(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddMediafileChannels, downAddMediafileChannels)
}
func upAddMediafileChannels(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddMediafileChannels(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table media_file
add channels integer;
@@ -22,10 +22,10 @@ create index if not exists media_file_channels
if err != nil {
return err
}
notice(tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(ctx, tx)
}
func downAddMediafileChannels(_ context.Context, tx *sql.Tx) error {
func downAddMediafileChannels(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddSmartPlaylist, downAddSmartPlaylist)
}
func upAddSmartPlaylist(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddSmartPlaylist(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table playlist
add column rules varchar null;
alter table playlist
@@ -33,6 +33,6 @@ create unique index playlist_fields_idx
return err
}
func downAddSmartPlaylist(_ context.Context, tx *sql.Tx) error {
func downAddSmartPlaylist(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -14,8 +14,8 @@ func init() {
goose.AddMigrationContext(upAddOrderTitleToMediaFile, downAddOrderTitleToMediaFile)
}
func upAddOrderTitleToMediaFile(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddOrderTitleToMediaFile(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table main.media_file
add order_title varchar null collate NOCASE;
create index if not exists media_file_order_title
@@ -25,12 +25,12 @@ create index if not exists media_file_order_title
return err
}
return upAddOrderTitleToMediaFile_populateOrderTitle(tx)
return upAddOrderTitleToMediaFile_populateOrderTitle(ctx, tx)
}
//goland:noinspection GoSnakeCaseUsage
func upAddOrderTitleToMediaFile_populateOrderTitle(tx *sql.Tx) error {
rows, err := tx.Query(`select id, title from media_file`)
func upAddOrderTitleToMediaFile_populateOrderTitle(ctx context.Context, tx *sql.Tx) error {
rows, err := tx.QueryContext(ctx, `select id, title from media_file`)
if err != nil {
return err
}
@@ -57,6 +57,6 @@ func upAddOrderTitleToMediaFile_populateOrderTitle(tx *sql.Tx) error {
return rows.Err()
}
func downAddOrderTitleToMediaFile(_ context.Context, tx *sql.Tx) error {
func downAddOrderTitleToMediaFile(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -13,8 +13,8 @@ func init() {
goose.AddMigrationContext(upUnescapeLyricsAndComments, downUnescapeLyricsAndComments)
}
func upUnescapeLyricsAndComments(_ context.Context, tx *sql.Tx) error {
rows, err := tx.Query(`select id, comment, lyrics, title from media_file`)
func upUnescapeLyricsAndComments(ctx context.Context, tx *sql.Tx) error {
rows, err := tx.QueryContext(ctx, `select id, comment, lyrics, title from media_file`)
if err != nil {
return err
}
@@ -43,6 +43,6 @@ func upUnescapeLyricsAndComments(_ context.Context, tx *sql.Tx) error {
return rows.Err()
}
func downUnescapeLyricsAndComments(_ context.Context, tx *sql.Tx) error {
func downUnescapeLyricsAndComments(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddUseridToPlaylist, downAddUseridToPlaylist)
}
func upAddUseridToPlaylist(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddUseridToPlaylist(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table playlist_dg_tmp
(
id varchar(255) not null
@@ -56,6 +56,6 @@ create index playlist_updated_at
return err
}
func downAddUseridToPlaylist(_ context.Context, tx *sql.Tx) error {
func downAddUseridToPlaylist(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,14 +11,14 @@ func init() {
goose.AddMigrationContext(upAddAlphabeticalByArtistIndex, downAddAlphabeticalByArtistIndex)
}
func upAddAlphabeticalByArtistIndex(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddAlphabeticalByArtistIndex(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create index album_alphabetical_by_artist
ON album(compilation, order_album_artist_name, order_album_name)
`)
return err
}
func downAddAlphabeticalByArtistIndex(_ context.Context, tx *sql.Tx) error {
func downAddAlphabeticalByArtistIndex(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,13 +11,13 @@ func init() {
goose.AddMigrationContext(upRemoveInvalidArtistIds, downRemoveInvalidArtistIds)
}
func upRemoveInvalidArtistIds(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upRemoveInvalidArtistIds(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
update media_file set artist_id = '' where not exists(select 1 from artist where id = artist_id)
`)
return err
}
func downRemoveInvalidArtistIds(_ context.Context, tx *sql.Tx) error {
func downRemoveInvalidArtistIds(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,19 +11,19 @@ func init() {
goose.AddMigrationContext(upAddMusicbrainzReleaseTrackId, downAddMusicbrainzReleaseTrackId)
}
func upAddMusicbrainzReleaseTrackId(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddMusicbrainzReleaseTrackId(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table media_file
add mbz_release_track_id varchar(255);
`)
if err != nil {
return err
}
notice(tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(ctx, tx)
}
func downAddMusicbrainzReleaseTrackId(_ context.Context, tx *sql.Tx) error {
func downAddMusicbrainzReleaseTrackId(ctx context.Context, tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return nil
}
@@ -11,17 +11,17 @@ func init() {
goose.AddMigrationContext(upAddAlbumImagePaths, downAddAlbumImagePaths)
}
func upAddAlbumImagePaths(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddAlbumImagePaths(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table main.album add image_files varchar;
`)
if err != nil {
return err
}
notice(tx, "A full rescan needs to be performed to import all album images")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan needs to be performed to import all album images")
return forceFullRescan(ctx, tx)
}
func downAddAlbumImagePaths(_ context.Context, tx *sql.Tx) error {
func downAddAlbumImagePaths(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,18 +11,18 @@ func init() {
goose.AddMigrationContext(upRemoveCoverArtId, downRemoveCoverArtId)
}
func upRemoveCoverArtId(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upRemoveCoverArtId(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table album drop column cover_art_id;
alter table album rename column cover_art_path to embed_art_path
`)
if err != nil {
return err
}
notice(tx, "A full rescan needs to be performed to import all album images")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan needs to be performed to import all album images")
return forceFullRescan(ctx, tx)
}
func downRemoveCoverArtId(_ context.Context, tx *sql.Tx) error {
func downRemoveCoverArtId(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -16,15 +16,15 @@ func init() {
goose.AddMigrationContext(upAddAlbumPaths, downAddAlbumPaths)
}
func upAddAlbumPaths(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`alter table album add paths varchar;`)
func upAddAlbumPaths(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `alter table album add paths varchar;`)
if err != nil {
return err
}
//nolint:gosec
rows, err := tx.Query(`
select album_id, group_concat(path, '` + consts.Zwsp + `') from media_file group by album_id
rows, err := tx.QueryContext(ctx, `
select album_id, group_concat(path, '`+consts.Zwsp+`') from media_file group by album_id
`)
if err != nil {
return err
@@ -63,6 +63,6 @@ func upAddAlbumPathsDirs(filePaths string) string {
return strings.Join(dirs, string(filepath.ListSeparator))
}
func downAddAlbumPaths(_ context.Context, tx *sql.Tx) error {
func downAddAlbumPaths(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,11 +11,11 @@ func init() {
goose.AddMigrationContext(upTouchPlaylists, downTouchPlaylists)
}
func upTouchPlaylists(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`update playlist set updated_at = datetime('now');`)
func upTouchPlaylists(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `update playlist set updated_at = datetime('now');`)
return err
}
func downTouchPlaylists(_ context.Context, tx *sql.Tx) error {
func downTouchPlaylists(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upCreateInternetRadio, downCreateInternetRadio)
}
func upCreateInternetRadio(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upCreateInternetRadio(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
create table if not exists radio
(
id varchar(255) not null primary key,
@@ -26,6 +26,6 @@ create table if not exists radio
return err
}
func downCreateInternetRadio(_ context.Context, tx *sql.Tx) error {
func downCreateInternetRadio(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddReplaygainMetadata, downAddReplaygainMetadata)
}
func upAddReplaygainMetadata(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddReplaygainMetadata(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table media_file add
rg_album_gain real;
alter table media_file add
@@ -26,10 +26,10 @@ alter table media_file add
return err
}
notice(tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(ctx, tx)
}
func downAddReplaygainMetadata(_ context.Context, tx *sql.Tx) error {
func downAddReplaygainMetadata(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddAlbumInfo, downAddAlbumInfo)
}
func upAddAlbumInfo(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddAlbumInfo(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table album
add description varchar(255) default '' not null;
alter table album
@@ -29,6 +29,6 @@ alter table album
return err
}
func downAddAlbumInfo(_ context.Context, tx *sql.Tx) error {
func downAddAlbumInfo(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddMissingShareInfo, downAddMissingShareInfo)
}
func upAddMissingShareInfo(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddMissingShareInfo(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
drop table if exists share;
create table share
(
@@ -37,6 +37,6 @@ create table share
return err
}
func downAddMissingShareInfo(_ context.Context, tx *sql.Tx) error {
func downAddMissingShareInfo(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -16,10 +16,10 @@ func init() {
goose.AddMigrationContext(upChangePathListSeparator, downChangePathListSeparator)
}
func upChangePathListSeparator(_ context.Context, tx *sql.Tx) error {
func upChangePathListSeparator(ctx context.Context, tx *sql.Tx) error {
//nolint:gosec
rows, err := tx.Query(`
select album_id, group_concat(path, '` + consts.Zwsp + `') from media_file group by album_id
rows, err := tx.QueryContext(ctx, `
select album_id, group_concat(path, '`+consts.Zwsp+`') from media_file group by album_id
`)
if err != nil {
return err
@@ -58,6 +58,6 @@ func upChangePathListSeparatorDirs(filePaths string) string {
return strings.Join(dirs, consts.Zwsp)
}
func downChangePathListSeparator(_ context.Context, tx *sql.Tx) error {
func downChangePathListSeparator(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -16,8 +16,8 @@ func init() {
goose.AddMigrationContext(upChangeImageFilesListSeparator, downChangeImageFilesListSeparator)
}
func upChangeImageFilesListSeparator(_ context.Context, tx *sql.Tx) error {
rows, err := tx.Query(`select id, image_files from album`)
func upChangeImageFilesListSeparator(ctx context.Context, tx *sql.Tx) error {
rows, err := tx.QueryContext(ctx, `select id, image_files from album`)
if err != nil {
return err
}
@@ -54,7 +54,7 @@ func upChangeImageFilesListSeparatorDirs(filePaths string) string {
return strings.Join(allPaths, consts.Zwsp)
}
func downChangeImageFilesListSeparator(_ context.Context, tx *sql.Tx) error {
func downChangeImageFilesListSeparator(ctx context.Context, tx *sql.Tx) error {
// This code is executed when the migration is rolled back.
return nil
}
@@ -11,14 +11,14 @@ func init() {
goose.AddMigrationContext(upAddDownloadToShare, downAddDownloadToShare)
}
func upAddDownloadToShare(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddDownloadToShare(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table share
add downloadable bool not null default false;
`)
return err
}
func downAddDownloadToShare(_ context.Context, tx *sql.Tx) error {
func downAddDownloadToShare(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,8 +11,8 @@ func init() {
goose.AddMigrationContext(upAddRelRecYear, downAddRelRecYear)
}
func upAddRelRecYear(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upAddRelRecYear(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table media_file
add date varchar(255) default '' not null;
alter table media_file
@@ -41,10 +41,10 @@ alter table album
return err
}
notice(tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(tx)
notice(ctx, tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(ctx, tx)
}
func downAddRelRecYear(_ context.Context, tx *sql.Tx) error {
func downAddRelRecYear(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,16 +11,16 @@ func init() {
goose.AddMigrationContext(upRenameMusicbrainzRecordingId, downRenameMusicbrainzRecordingId)
}
func upRenameMusicbrainzRecordingId(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func upRenameMusicbrainzRecordingId(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table media_file
rename column mbz_track_id to mbz_recording_id;
`)
return err
}
func downRenameMusicbrainzRecordingId(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
func downRenameMusicbrainzRecordingId(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `
alter table media_file
rename column mbz_recording_id to mbz_track_id;
`)
@@ -29,7 +29,7 @@ func upAlterLyricColumn(ctx context.Context, tx *sql.Tx) error {
return err
}
rows, err := tx.Query(`select id, lyrics_old FROM media_file WHERE lyrics_old <> '';`)
rows, err := tx.QueryContext(ctx, `select id, lyrics_old FROM media_file WHERE lyrics_old <> '';`)
if err != nil {
return err
}
@@ -72,7 +72,7 @@ func upAlterLyricColumn(ctx context.Context, tx *sql.Tx) error {
return err
}
notice(tx, "A full rescan should be performed to pick up additional lyrics (existing lyrics have been preserved)")
notice(ctx, tx, "A full rescan should be performed to pick up additional lyrics (existing lyrics have been preserved)")
return nil
}
@@ -558,6 +558,6 @@ create index media_file_mbz_track_id
return err
}
func Down20240122223340(context.Context, *sql.Tx) error {
func Down20240122223340(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -19,7 +19,7 @@ alter table media_file
create index if not exists media_file_sample_rate
on media_file (sample_rate);
`)
notice(tx, "A full rescan should be performed to pick up additional tags")
notice(ctx, tx, "A full rescan should be performed to pick up additional tags")
return err
}
@@ -61,6 +61,6 @@ create index annotation_starred_at
return err
}
func downRemoveAnnotationId(ctx context.Context, tx *sql.Tx) error {
func downRemoveAnnotationId(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -97,8 +97,8 @@ insert into property (id, value) values ('PIDTrack', 'track_legacy') on conflict
insert into property (id, value) values ('PIDAlbum', 'album_legacy') on conflict do nothing;
`),
func() error {
notice(tx, "A full scan will be triggered to populate the new tables. This may take a while.")
return forceFullRescan(tx)
notice(ctx, tx, "A full scan will be triggered to populate the new tables. This may take a while.")
return forceFullRescan(ctx, tx)
},
)
}
@@ -314,6 +314,6 @@ alter table artist
}
}
func downSupportNewScanner(context.Context, *sql.Tx) error {
func downSupportNewScanner(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -75,6 +75,6 @@ create table playqueue_dg_tmp(
return err
}
func downPlayQueueCurrentToIndex(ctx context.Context, tx *sql.Tx) error {
func downPlayQueueCurrentToIndex(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -16,6 +16,6 @@ func upAddFolderHash(ctx context.Context, tx *sql.Tx) error {
return err
}
func downAddFolderHash(ctx context.Context, tx *sql.Tx) error {
func downAddFolderHash(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -43,6 +43,6 @@ update library set
return err
}
func downAddLibraryStats(ctx context.Context, tx *sql.Tx) error {
func downAddLibraryStats(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -39,7 +39,7 @@ ALTER TABLE media_file RENAME COLUMN rg_track_peak_new TO rg_track_peak;
return err
}
notice(tx, "Fetching replaygain fields properly will require a full scan")
notice(ctx, tx, "Fetching replaygain fields properly will require a full scan")
return nil
}
@@ -22,7 +22,7 @@ func stripPunct(col string) string {
}
func upAddFts5Search(ctx context.Context, tx *sql.Tx) error {
notice(tx, "Adding FTS5 full-text search indexes. This may take a moment on large libraries.")
notice(ctx, tx, "Adding FTS5 full-text search indexes. This may take a moment on large libraries.")
// Step 1: Add search_participants and search_normalized columns to media_file, album, and artist
_, err := tx.ExecContext(ctx, `ALTER TABLE media_file ADD COLUMN search_participants TEXT NOT NULL DEFAULT ''`)
@@ -12,20 +12,20 @@ func init() {
goose.AddMigrationContext(upAddCodecAndUpdateTranscodings, downAddCodecAndUpdateTranscodings)
}
func upAddCodecAndUpdateTranscodings(_ context.Context, tx *sql.Tx) error {
func upAddCodecAndUpdateTranscodings(ctx context.Context, tx *sql.Tx) error {
// Add codec column to media_file.
_, err := tx.Exec(`ALTER TABLE media_file ADD COLUMN codec VARCHAR(255) DEFAULT '' NOT NULL`)
_, err := tx.ExecContext(ctx, `ALTER TABLE media_file ADD COLUMN codec VARCHAR(255) DEFAULT '' NOT NULL`)
if err != nil {
return err
}
_, err = tx.Exec(`CREATE INDEX IF NOT EXISTS media_file_codec ON media_file(codec)`)
_, err = tx.ExecContext(ctx, `CREATE INDEX IF NOT EXISTS media_file_codec ON media_file(codec)`)
if err != nil {
return err
}
// Update old AAC default (adts) to new default (ipod with fragmented MP4).
// Only affects users who still have the unmodified old default command.
_, err = tx.Exec(
_, err = tx.ExecContext(ctx,
`UPDATE transcoding SET command = ? WHERE target_format = 'aac' AND command = ?`,
"ffmpeg -i %s -ss %t -map 0:a:0 -b:a %bk -v 0 -c:a aac -f ipod -movflags frag_keyframe+empty_moov -",
"ffmpeg -i %s -ss %t -map 0:a:0 -b:a %bk -v 0 -c:a aac -f adts -",
@@ -36,12 +36,12 @@ func upAddCodecAndUpdateTranscodings(_ context.Context, tx *sql.Tx) error {
// Add FLAC transcoding for existing installations that were seeded before FLAC was added.
var count int
err = tx.QueryRow("SELECT COUNT(*) FROM transcoding WHERE target_format = 'flac'").Scan(&count)
err = tx.QueryRowContext(ctx, "SELECT COUNT(*) FROM transcoding WHERE target_format = 'flac'").Scan(&count)
if err != nil {
return err
}
if count == 0 {
_, err = tx.Exec(
_, err = tx.ExecContext(ctx,
"INSERT INTO transcoding (id, name, target_format, default_bit_rate, command) VALUES (?, ?, ?, ?, ?)",
id.NewRandom(), "flac audio", "flac", 0,
"ffmpeg -i %s -ss %t -map 0:a:0 -v 0 -c:a flac -f flac -",
@@ -52,22 +52,22 @@ func upAddCodecAndUpdateTranscodings(_ context.Context, tx *sql.Tx) error {
}
// Add probe_data column for caching ffprobe results.
_, err = tx.Exec(`ALTER TABLE media_file ADD COLUMN probe_data TEXT DEFAULT NULL`)
_, err = tx.ExecContext(ctx, `ALTER TABLE media_file ADD COLUMN probe_data TEXT DEFAULT NULL`)
if err != nil {
return err
}
return nil
}
func downAddCodecAndUpdateTranscodings(_ context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`ALTER TABLE media_file DROP COLUMN probe_data`)
func downAddCodecAndUpdateTranscodings(ctx context.Context, tx *sql.Tx) error {
_, err := tx.ExecContext(ctx, `ALTER TABLE media_file DROP COLUMN probe_data`)
if err != nil {
return err
}
_, err = tx.Exec(`DROP INDEX IF EXISTS media_file_codec`)
_, err = tx.ExecContext(ctx, `DROP INDEX IF EXISTS media_file_codec`)
if err != nil {
return err
}
_, err = tx.Exec(`ALTER TABLE media_file DROP COLUMN codec`)
_, err = tx.ExecContext(ctx, `ALTER TABLE media_file DROP COLUMN codec`)
return err
}
@@ -11,18 +11,18 @@ func init() {
goose.AddMigrationContext(upFixProbeDataNull, downFixProbeDataNull)
}
func upFixProbeDataNull(_ context.Context, tx *sql.Tx) error {
func upFixProbeDataNull(ctx context.Context, tx *sql.Tx) error {
// Recreate probe_data column as NOT NULL with empty string default.
// The previous migration created it with DEFAULT NULL, which causes
// scan errors when reading into Go string fields.
_, err := tx.Exec(`ALTER TABLE media_file DROP COLUMN probe_data`)
_, err := tx.ExecContext(ctx, `ALTER TABLE media_file DROP COLUMN probe_data`)
if err != nil {
return err
}
_, err = tx.Exec(`ALTER TABLE media_file ADD COLUMN probe_data TEXT DEFAULT '' NOT NULL`)
_, err = tx.ExecContext(ctx, `ALTER TABLE media_file ADD COLUMN probe_data TEXT DEFAULT '' NOT NULL`)
return err
}
func downFixProbeDataNull(_ context.Context, tx *sql.Tx) error {
func downFixProbeDataNull(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -13,7 +13,7 @@ func init() {
goose.AddMigrationContext(upEnsureDefaultTranscodings, downEnsureDefaultTranscodings)
}
func upEnsureDefaultTranscodings(_ context.Context, tx *sql.Tx) error {
func upEnsureDefaultTranscodings(ctx context.Context, tx *sql.Tx) error {
// Older installations may be missing default transcodings that were added
// after the initial seeding (e.g., aac was added later than mp3/opus).
// Insert any missing defaults without touching user-customized entries.
@@ -22,12 +22,12 @@ func upEnsureDefaultTranscodings(_ context.Context, tx *sql.Tx) error {
// but the same name.
for _, t := range consts.DefaultTranscodings {
var count int
err := tx.QueryRow("SELECT COUNT(*) FROM transcoding WHERE target_format = ? OR name = ?", t.TargetFormat, t.Name).Scan(&count)
err := tx.QueryRowContext(ctx, "SELECT COUNT(*) FROM transcoding WHERE target_format = ? OR name = ?", t.TargetFormat, t.Name).Scan(&count)
if err != nil {
return err
}
if count == 0 {
_, err = tx.Exec(
_, err = tx.ExecContext(ctx,
"INSERT INTO transcoding (id, name, target_format, default_bit_rate, command) VALUES (?, ?, ?, ?, ?)",
id.NewRandom(), t.Name, t.TargetFormat, t.DefaultBitRate, t.Command,
)
@@ -39,6 +39,6 @@ func upEnsureDefaultTranscodings(_ context.Context, tx *sql.Tx) error {
return nil
}
func downEnsureDefaultTranscodings(_ context.Context, tx *sql.Tx) error {
func downEnsureDefaultTranscodings(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -11,20 +11,20 @@ func init() {
goose.AddMigrationContext(upFixAacTranscodeCommand, downFixAacTranscodeCommand)
}
func upFixAacTranscodeCommand(_ context.Context, tx *sql.Tx) error {
func upFixAacTranscodeCommand(ctx context.Context, tx *sql.Tx) error {
// The old AAC command used `-f ipod -movflags frag_keyframe+empty_moov` which produces
// corrupt/silent audio when ffmpeg pipes to stdout (confirmed in ffmpeg 8.0+).
// Switch to `-f adts` (raw AAC framing) which works reliably via pipe.
// Only update rows that still have the old default command.
const oldCommand = "ffmpeg -i %s -ss %t -map 0:a:0 -b:a %bk -v 0 -c:a aac -f ipod -movflags frag_keyframe+empty_moov -"
const newCommand = "ffmpeg -i %s -ss %t -map 0:a:0 -b:a %bk -v 0 -c:a aac -f adts -"
_, err := tx.Exec(
_, err := tx.ExecContext(ctx,
"UPDATE transcoding SET command = ? WHERE target_format = 'aac' AND command = ?",
newCommand, oldCommand,
)
return err
}
func downFixAacTranscodeCommand(_ context.Context, tx *sql.Tx) error {
func downFixAacTranscodeCommand(_ context.Context, _ *sql.Tx) error {
return nil
}
@@ -36,18 +36,18 @@ var ssSeekPairs = [][2]string{
},
}
func upMoveSsBeforeInput(_ context.Context, tx *sql.Tx) error {
func upMoveSsBeforeInput(ctx context.Context, tx *sql.Tx) error {
for _, p := range ssSeekPairs {
if _, err := tx.Exec(`UPDATE transcoding SET command = ? WHERE command = ?`, p[1], p[0]); err != nil {
if _, err := tx.ExecContext(ctx, `UPDATE transcoding SET command = ? WHERE command = ?`, p[1], p[0]); err != nil {
return err
}
}
return nil
}
func downMoveSsBeforeInput(_ context.Context, tx *sql.Tx) error {
func downMoveSsBeforeInput(ctx context.Context, tx *sql.Tx) error {
for _, p := range ssSeekPairs {
if _, err := tx.Exec(`UPDATE transcoding SET command = ? WHERE command = ?`, p[0], p[1]); err != nil {
if _, err := tx.ExecContext(ctx, `UPDATE transcoding SET command = ? WHERE command = ?`, p[0], p[1]); err != nil {
return err
}
}
+7 -7
View File
@@ -12,23 +12,23 @@ import (
)
// Use this in migrations that need to communicate something important (breaking changes, forced reindexes, etc...)
func notice(tx *sql.Tx, msg string) {
if isDBInitialized(tx) {
func notice(ctx context.Context, tx *sql.Tx, msg string) {
if isDBInitialized(ctx, tx) {
line := strings.Repeat("*", len(msg)+8)
fmt.Printf("\n%s\nNOTICE: %s\n%s\n\n", line, msg, line)
}
}
// Call this in migrations that requires a full rescan
func forceFullRescan(tx *sql.Tx) error {
func forceFullRescan(ctx context.Context, tx *sql.Tx) error {
// If a full scan is required, most probably the query optimizer is outdated, so we run `analyze`.
if conf.Server.DevOptimizeDB {
_, err := tx.Exec(`ANALYZE;`)
_, err := tx.ExecContext(ctx, `ANALYZE;`)
if err != nil {
return err
}
}
_, err := tx.Exec(fmt.Sprintf(`
_, err := tx.ExecContext(ctx, fmt.Sprintf(`
INSERT OR REPLACE into property (id, value) values ('%s', '1');
`, consts.FullScanAfterMigrationFlagKey))
return err
@@ -44,9 +44,9 @@ var (
initialized bool
)
func isDBInitialized(tx *sql.Tx) bool {
func isDBInitialized(ctx context.Context, tx *sql.Tx) bool {
once.Do(func() {
rows, err := tx.Query("select count(*) from property where id=?", consts.InitialSetupFlagKey)
rows, err := tx.QueryContext(ctx, "select count(*) from property where id=?", consts.InitialSetupFlagKey)
checkErr(err)
initialized = checkCount(rows) > 0
})