diff --git a/transcoder/migrations/000004_add_id_column.down.sql b/transcoder/migrations/000004_add_id_column.down.sql new file mode 100644 index 00000000..ccf9e527 --- /dev/null +++ b/transcoder/migrations/000004_add_id_column.down.sql @@ -0,0 +1,49 @@ +begin; + +-- chapters +alter table gocoder.chapters add column sha varchar(40); +update gocoder.chapters c set sha = i.sha from gocoder.info i where c.id = i.id; +alter table gocoder.chapters alter column sha set not null; + +alter table gocoder.chapters drop constraint chapter_pk; +alter table gocoder.chapters drop constraint chapters_info_fk; +alter table gocoder.chapters drop column id; +alter table gocoder.chapters add constraint chapter_pk primary key (sha, start_time); +alter table gocoder.chapters add foreign key (sha) references gocoder.info(sha) on delete cascade; + +-- subtitles +alter table gocoder.subtitles add column sha varchar(40); +update gocoder.subtitles s set sha = i.sha from gocoder.info i where s.id = i.id; +alter table gocoder.subtitles alter column sha set not null; + +alter table gocoder.subtitles drop constraint subtitle_pk; +alter table gocoder.subtitles drop constraint subtitles_info_fk; +alter table gocoder.subtitles drop column id; +alter table gocoder.subtitles add constraint subtitle_pk primary key (sha, idx); +alter table gocoder.subtitles add foreign key (sha) references gocoder.info(sha) on delete cascade; + +-- audios +alter table gocoder.audios add column sha varchar(40); +update gocoder.audios a set sha = i.sha from gocoder.info i where a.id = i.id; +alter table gocoder.audios alter column sha set not null; + +alter table gocoder.audios drop constraint audios_pk; +alter table gocoder.audios drop constraint audios_info_fk; +alter table gocoder.audios drop column id; +alter table gocoder.audios add constraint audios_pk primary key (sha, idx); +alter table gocoder.audios add foreign key (sha) references gocoder.info(sha) on delete cascade; + +-- videos +alter table gocoder.videos add column sha varchar(40); +update gocoder.videos v set sha = i.sha from gocoder.info i where v.id = i.id; +alter table gocoder.videos alter column sha set not null; + +alter table gocoder.videos drop constraint videos_pk; +alter table gocoder.videos drop constraint videos_info_fk; +alter table gocoder.videos drop column id; +alter table gocoder.videos add constraint videos_pk primary key (sha, idx); +alter table gocoder.videos add foreign key (sha) references gocoder.info(sha) on delete cascade; + +alter table gocoder.info drop column id; + +commit; diff --git a/transcoder/migrations/000004_add_id_column.up.sql b/transcoder/migrations/000004_add_id_column.up.sql new file mode 100644 index 00000000..2eb05fc6 --- /dev/null +++ b/transcoder/migrations/000004_add_id_column.up.sql @@ -0,0 +1,55 @@ +begin; + +alter table gocoder.info add column id serial unique not null; +alter table gocoder.info drop constraint info_pkey; +alter table gocoder.info add constraint info_pkey primary key(id); + +-- videos +alter table gocoder.videos add column id integer; +update gocoder.videos v set id = i.id from gocoder.info i where v.sha = i.sha; +alter table gocoder.videos alter column id set not null; + +alter table gocoder.videos drop constraint videos_pk; +alter table gocoder.videos drop constraint videos_sha_fkey; +alter table gocoder.videos drop column sha; +alter table gocoder.videos add constraint videos_info_fk + foreign key (id) references gocoder.info(id) on delete cascade; +alter table gocoder.videos add constraint videos_pk primary key (id, idx); + +-- audios +alter table gocoder.audios add column id integer; +update gocoder.audios a set id = i.id from gocoder.info i where a.sha = i.sha; +alter table gocoder.audios alter column id set not null; + +alter table gocoder.audios drop constraint audios_pk; +alter table gocoder.audios drop constraint audios_sha_fkey; +alter table gocoder.audios drop column sha; +alter table gocoder.audios add constraint audios_info_fk + foreign key (id) references gocoder.info(id) on delete cascade; +alter table gocoder.audios add constraint audios_pk primary key (id, idx); + +-- subtitles +alter table gocoder.subtitles add column id integer; +update gocoder.subtitles s set id = i.id from gocoder.info i where s.sha = i.sha; +alter table gocoder.subtitles alter column id set not null; + +alter table gocoder.subtitles drop constraint subtitle_pk; +alter table gocoder.subtitles drop constraint subtitles_sha_fkey; +alter table gocoder.subtitles drop column sha; +alter table gocoder.subtitles add constraint subtitles_info_fk + foreign key (id) references gocoder.info(id) on delete cascade; +alter table gocoder.subtitles add constraint subtitle_pk primary key (id, idx); + +-- chapters +alter table gocoder.chapters add column id integer; +update gocoder.chapters c set id = i.id from gocoder.info i where c.sha = i.sha; +alter table gocoder.chapters alter column id set not null; + +alter table gocoder.chapters drop constraint chapter_pk; +alter table gocoder.chapters drop constraint chapters_sha_fkey; +alter table gocoder.chapters drop column sha; +alter table gocoder.chapters add constraint chapters_info_fk + foreign key (id) references gocoder.info(id) on delete cascade; +alter table gocoder.chapters add constraint chapter_pk primary key (id, start_time); + +commit; diff --git a/transcoder/src/info.go b/transcoder/src/info.go index e6761b97..5e166602 100644 --- a/transcoder/src/info.go +++ b/transcoder/src/info.go @@ -27,6 +27,8 @@ type Versions struct { } type MediaInfo struct { + // Auto-increment id used as foreign key for related tables. + Id int32 `json:"id" db:"id"` // The sha1 of the video file. Sha string `json:"sha" db:"sha"` /// The internal path of the video file. @@ -60,7 +62,7 @@ type MediaInfo struct { } type Video struct { - Sha string `json:"-" db:"sha"` + Id int32 `json:"-" db:"id"` /// The index of this track on the media. Index uint32 `json:"index" db:"idx"` @@ -86,7 +88,7 @@ type Video struct { } type Audio struct { - Sha string `json:"-" db:"sha"` + Id int32 `json:"-" db:"id"` /// The index of this track on the media. Index uint32 `json:"index" db:"idx"` @@ -110,7 +112,7 @@ type Audio struct { } type Subtitle struct { - Sha string `json:"-" db:"sha"` + Id int32 `json:"-" db:"id"` /// The index of this track on the media. Index *uint32 `json:"index" db:"idx"` @@ -137,7 +139,7 @@ type Subtitle struct { } type Chapter struct { - Sha string `json:"-" db:"sha"` + Id int32 `json:"-" db:"id"` /// The start time of the chapter (in second from the start of the episode). StartTime float32 `json:"startTime" db:"start_time"` diff --git a/transcoder/src/keyframes.go b/transcoder/src/keyframes.go index 5f76ed08..94d4038b 100644 --- a/transcoder/src/keyframes.go +++ b/transcoder/src/keyframes.go @@ -160,12 +160,12 @@ func (s *MetadataService) GetKeyframes(info *MediaInfo, isVideo bool, idx uint32 tx, _ := s.Database.Begin(ctx) tx.Exec( ctx, - fmt.Sprintf(`update %s set keyframes = $3 where sha = $1 and idx = $2`, table), - info.Sha, + fmt.Sprintf(`update %s set keyframes = $3 where id = $1 and idx = $2`, table), + info.Id, idx, kf.Keyframes, ) - tx.Exec(ctx, `update gocoder.info set ver_keyframes = $2 where sha = $1`, info.Sha, KeyframeVersion) + tx.Exec(ctx, `update gocoder.info set ver_keyframes = $2 where id = $1`, info.Id, KeyframeVersion) err = tx.Commit(ctx) if err != nil { log.Printf("Couldn't store keyframes on database: %v", err) diff --git a/transcoder/src/metadata.go b/transcoder/src/metadata.go index 4a79c912..4b972e9e 100644 --- a/transcoder/src/metadata.go +++ b/transcoder/src/metadata.go @@ -171,9 +171,9 @@ func (s *MetadataService) GetMetadata(ctx context.Context, path string, sha stri if err != nil { return nil, err } - tx.Exec(bgCtx, `update gocoder.videos set keyframes = null where sha = $1`, sha) - tx.Exec(bgCtx, `update gocoder.audios set keyframes = null where sha = $1`, sha) - tx.Exec(bgCtx, `update gocoder.info set ver_keyframes = 0 where sha = $1`, sha) + tx.Exec(bgCtx, `update gocoder.videos set keyframes = null where id = $1`, ret.Id) + tx.Exec(bgCtx, `update gocoder.audios set keyframes = null where id = $1`, ret.Id) + tx.Exec(bgCtx, `update gocoder.info set ver_keyframes = 0 where id = $1`, ret.Id) err = tx.Commit(bgCtx) if err != nil { fmt.Printf("error deleting old keyframes from database: %v", err) @@ -187,7 +187,7 @@ func (s *MetadataService) getMetadata(ctx context.Context, path string, sha stri rows, _ := s.Database.Query( ctx, `select - i.sha, i.path, i.extension, i.mime_codec, i.size, i.duration, i.container, i.fonts, + i.id, i.sha, i.path, i.extension, i.mime_codec, i.size, i.duration, i.container, i.fonts, jsonb_build_object( 'info', i.ver_info, 'extract', i.ver_extract, @@ -209,8 +209,8 @@ func (s *MetadataService) getMetadata(ctx context.Context, path string, sha stri rows, _ = s.Database.Query( ctx, - `select * from gocoder.videos as v where v.sha=$1`, - sha, + `select * from gocoder.videos as v where v.id=$1`, + ret.Id, ) ret.Videos, err = pgx.CollectRows(rows, pgx.RowToStructByName[Video]) if err != nil { @@ -219,8 +219,8 @@ func (s *MetadataService) getMetadata(ctx context.Context, path string, sha stri rows, _ = s.Database.Query( ctx, - `select * from gocoder.audios as a where a.sha=$1`, - sha, + `select * from gocoder.audios as a where a.id=$1`, + ret.Id, ) ret.Audios, err = pgx.CollectRows(rows, pgx.RowToStructByName[Audio]) if err != nil { @@ -229,8 +229,8 @@ func (s *MetadataService) getMetadata(ctx context.Context, path string, sha stri rows, _ = s.Database.Query( ctx, - `select * from gocoder.subtitles as s where s.sha=$1`, - sha, + `select * from gocoder.subtitles as s where s.id=$1`, + ret.Id, ) ret.Subtitles, err = pgx.CollectRows(rows, pgx.RowToStructByName[Subtitle]) if err != nil { @@ -254,8 +254,8 @@ func (s *MetadataService) getMetadata(ctx context.Context, path string, sha stri rows, _ = s.Database.Query( ctx, - `select * from gocoder.chapters as c where c.sha=$1`, - sha, + `select * from gocoder.chapters as c where c.id=$1`, + ret.Id, ) ret.Chapters, err = pgx.CollectRows(rows, pgx.RowToStructByName[Chapter]) if err != nil { @@ -283,24 +283,28 @@ func (s *MetadataService) storeFreshMetadata(ctx context.Context, path string, s // it needs to be a delete instead of a on conflict do update because we want to trigger delete casquade for // videos/audios & co. tx.Exec(ctx, `delete from gocoder.info where path = $1`, path) - tx.Exec(ctx, + err = tx.QueryRow(ctx, ` insert into gocoder.info(sha, path, extension, mime_codec, size, duration, container, fonts, ver_info, ver_extract, ver_thumbs, ver_keyframes) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + returning id `, // on conflict do not update versions of extract/thumbs/keyframes ret.Sha, ret.Path, ret.Extension, ret.MimeCodec, ret.Size, ret.Duration, ret.Container, ret.Fonts, ret.Versions.Info, ret.Versions.Extract, ret.Versions.Thumbs, ret.Versions.Keyframes, - ) + ).Scan(&ret.Id) + if err != nil { + return set(ret, fmt.Errorf("failed to insert info: %w", err)) + } for _, v := range ret.Videos { tx.Exec( ctx, ` - insert into gocoder.videos(sha, idx, title, language, codec, mime_codec, width, height, is_default, bitrate) + insert into gocoder.videos(id, idx, title, language, codec, mime_codec, width, height, is_default, bitrate) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) - on conflict (sha, idx) do update set - sha = excluded.sha, + on conflict (id, idx) do update set + id = excluded.id, idx = excluded.idx, title = excluded.title, language = excluded.language, @@ -311,17 +315,17 @@ func (s *MetadataService) storeFreshMetadata(ctx context.Context, path string, s is_default = excluded.is_default, bitrate = excluded.bitrate `, - ret.Sha, v.Index, v.Title, v.Language, v.Codec, v.MimeCodec, v.Width, v.Height, v.IsDefault, v.Bitrate, + ret.Id, v.Index, v.Title, v.Language, v.Codec, v.MimeCodec, v.Width, v.Height, v.IsDefault, v.Bitrate, ) } for _, a := range ret.Audios { tx.Exec( ctx, ` - insert into gocoder.audios(sha, idx, title, language, codec, mime_codec, channels, is_default, bitrate) + insert into gocoder.audios(id, idx, title, language, codec, mime_codec, channels, is_default, bitrate) values ($1, $2, $3, $4, $5, $6, $7, $8, $9) - on conflict (sha, idx) do update set - sha = excluded.sha, + on conflict (id, idx) do update set + id = excluded.id, idx = excluded.idx, title = excluded.title, language = excluded.language, @@ -331,17 +335,17 @@ func (s *MetadataService) storeFreshMetadata(ctx context.Context, path string, s is_default = excluded.is_default, bitrate = excluded.bitrate `, - ret.Sha, a.Index, a.Title, a.Language, a.Codec, a.MimeCodec, a.Channels, a.IsDefault, a.Bitrate, + ret.Id, a.Index, a.Title, a.Language, a.Codec, a.MimeCodec, a.Channels, a.IsDefault, a.Bitrate, ) } for _, s := range ret.Subtitles { tx.Exec( ctx, ` - insert into gocoder.subtitles(sha, idx, title, language, codec, extension, is_default, is_forced, is_hearing_impaired) + insert into gocoder.subtitles(id, idx, title, language, codec, extension, is_default, is_forced, is_hearing_impaired) values ($1, $2, $3, $4, $5, $6, $7, $8, $9) - on conflict (sha, idx) do update set - sha = excluded.sha, + on conflict (id, idx) do update set + id = excluded.id, idx = excluded.idx, title = excluded.title, language = excluded.language, @@ -351,23 +355,23 @@ func (s *MetadataService) storeFreshMetadata(ctx context.Context, path string, s is_forced = excluded.is_forced, is_hearing_impaired = excluded.is_hearing_impaired `, - ret.Sha, s.Index, s.Title, s.Language, s.Codec, s.Extension, s.IsDefault, s.IsForced, s.IsHearingImpaired, + ret.Id, s.Index, s.Title, s.Language, s.Codec, s.Extension, s.IsDefault, s.IsForced, s.IsHearingImpaired, ) } for _, c := range ret.Chapters { tx.Exec( ctx, ` - insert into gocoder.chapters(sha, start_time, end_time, name, type) + insert into gocoder.chapters(id, start_time, end_time, name, type) values ($1, $2, $3, $4, $5) - on conflict (sha, start_time) do update set - sha = excluded.sha, + on conflict (id, start_time) do update set + id = excluded.id, start_time = excluded.start_time, end_time = excluded.end_time, name = excluded.name, type = excluded.type `, - ret.Sha, c.StartTime, c.EndTime, c.Name, c.Type, + ret.Id, c.StartTime, c.EndTime, c.Name, c.Type, ) } err = tx.Commit(ctx)