Rename movie tables to groups in database schema (#5082)

* Rename movie tables to groups
* Correct index name
* Rename synopsis to description in schema
This commit is contained in:
WithoutPants 2024-07-30 14:14:16 +10:00 committed by GitHub
parent 48c6373afa
commit d96850c008
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 112 additions and 88 deletions

View file

@ -86,8 +86,8 @@ func (db *Anonymiser) deleteBlobs() error {
func() error { return db.truncateColumn("studios", "image_blob") },
func() error { return db.truncateColumn("performers", "image_blob") },
func() error { return db.truncateColumn("scenes", "cover_blob") },
func() error { return db.truncateColumn("movies", "front_image_blob") },
func() error { return db.truncateColumn("movies", "back_image_blob") },
func() error { return db.truncateColumn("groups", "front_image_blob") },
func() error { return db.truncateColumn("groups", "back_image_blob") },
func() error { return db.truncateTable("blobs") },
})
@ -838,7 +838,7 @@ func (db *Anonymiser) anonymiseGroups(ctx context.Context) error {
table.Col(idColumn),
table.Col("name"),
table.Col("aliases"),
table.Col("synopsis"),
table.Col("description"),
table.Col("director"),
).Where(table.Col(idColumn).Gt(lastID)).Limit(1000)
@ -847,18 +847,18 @@ func (db *Anonymiser) anonymiseGroups(ctx context.Context) error {
const single = false
return queryFunc(ctx, query, single, func(rows *sqlx.Rows) error {
var (
id int
name sql.NullString
aliases sql.NullString
synopsis sql.NullString
director sql.NullString
id int
name sql.NullString
aliases sql.NullString
description sql.NullString
director sql.NullString
)
if err := rows.Scan(
&id,
&name,
&aliases,
&synopsis,
&description,
&director,
); err != nil {
return err
@ -867,7 +867,7 @@ func (db *Anonymiser) anonymiseGroups(ctx context.Context) error {
set := goqu.Record{}
db.obfuscateNullString(set, "name", name)
db.obfuscateNullString(set, "aliases", aliases)
db.obfuscateNullString(set, "synopsis", synopsis)
db.obfuscateNullString(set, "description", description)
db.obfuscateNullString(set, "director", director)
if len(set) > 0 {
@ -893,7 +893,7 @@ func (db *Anonymiser) anonymiseGroups(ctx context.Context) error {
}
}
if err := db.anonymiseURLs(ctx, goqu.T(groupURLsTable), "movie_id"); err != nil {
if err := db.anonymiseURLs(ctx, goqu.T(groupURLsTable), "group_id"); err != nil {
return err
}

View file

@ -30,7 +30,7 @@ const (
dbConnTimeout = 30
)
var appSchemaVersion uint = 64
var appSchemaVersion uint = 65
//go:embed migrations/*.sql
var migrationsBox embed.FS

View file

@ -17,15 +17,15 @@ import (
)
const (
groupTable = "movies"
groupIDColumn = "movie_id"
groupTable = "groups"
groupIDColumn = "group_id"
groupFrontImageBlobColumn = "front_image_blob"
groupBackImageBlobColumn = "back_image_blob"
groupsTagsTable = "movies_tags"
groupsTagsTable = "groups_tags"
groupURLsTable = "movie_urls"
groupURLsTable = "group_urls"
groupURLColumn = "url"
)
@ -36,12 +36,12 @@ type groupRow struct {
Duration null.Int `db:"duration"`
Date NullDate `db:"date"`
// expressed as 1-100
Rating null.Int `db:"rating"`
StudioID null.Int `db:"studio_id,omitempty"`
Director zero.String `db:"director"`
Synopsis zero.String `db:"synopsis"`
CreatedAt Timestamp `db:"created_at"`
UpdatedAt Timestamp `db:"updated_at"`
Rating null.Int `db:"rating"`
StudioID null.Int `db:"studio_id,omitempty"`
Director zero.String `db:"director"`
Description zero.String `db:"description"`
CreatedAt Timestamp `db:"created_at"`
UpdatedAt Timestamp `db:"updated_at"`
// not used in resolutions or updates
FrontImageBlob zero.String `db:"front_image_blob"`
@ -57,7 +57,7 @@ func (r *groupRow) fromGroup(o models.Group) {
r.Rating = intFromPtr(o.Rating)
r.StudioID = intFromPtr(o.StudioID)
r.Director = zero.StringFrom(o.Director)
r.Synopsis = zero.StringFrom(o.Synopsis)
r.Description = zero.StringFrom(o.Synopsis)
r.CreatedAt = Timestamp{Timestamp: o.CreatedAt}
r.UpdatedAt = Timestamp{Timestamp: o.UpdatedAt}
}
@ -72,7 +72,7 @@ func (r *groupRow) resolve() *models.Group {
Rating: nullIntPtr(r.Rating),
StudioID: nullIntPtr(r.StudioID),
Director: r.Director.String,
Synopsis: r.Synopsis.String,
Synopsis: r.Description.String,
CreatedAt: r.CreatedAt.Timestamp,
UpdatedAt: r.UpdatedAt.Timestamp,
}
@ -92,7 +92,7 @@ func (r *groupRowRecord) fromPartial(o models.GroupPartial) {
r.setNullInt("rating", o.Rating)
r.setNullInt("studio_id", o.StudioID)
r.setNullString("director", o.Director)
r.setNullString("synopsis", o.Synopsis)
r.setNullString("description", o.Synopsis)
r.setTimestamp("created_at", o.CreatedAt)
r.setTimestamp("updated_at", o.UpdatedAt)
}
@ -330,7 +330,7 @@ func (qb *GroupStore) getMany(ctx context.Context, q *goqu.SelectDataset) ([]*mo
}
func (qb *GroupStore) FindByName(ctx context.Context, name string, nocase bool) (*models.Group, error) {
// query := "SELECT * FROM movies WHERE name = ?"
// query := "SELECT * FROM groups WHERE name = ?"
// if nocase {
// query += " COLLATE NOCASE"
// }
@ -350,7 +350,7 @@ func (qb *GroupStore) FindByName(ctx context.Context, name string, nocase bool)
}
func (qb *GroupStore) FindByNames(ctx context.Context, names []string, nocase bool) ([]*models.Group, error) {
// query := "SELECT * FROM movies WHERE name"
// query := "SELECT * FROM groups WHERE name"
// if nocase {
// query += " COLLATE NOCASE"
// }
@ -400,7 +400,7 @@ func (qb *GroupStore) makeQuery(ctx context.Context, groupFilter *models.GroupFi
distinctIDs(&query, groupTable)
if q := findFilter.Q; q != nil && *q != "" {
searchColumns := []string{"movies.name", "movies.aliases"}
searchColumns := []string{"groups.name", "groups.aliases"}
query.parseQueryString(searchColumns, *q)
}
@ -487,11 +487,11 @@ func (qb *GroupStore) getGroupSort(findFilter *models.FindFilterType) (string, e
case "scenes_count": // generic getSort won't work for this
sortQuery += getCountSort(groupTable, groupsScenesTable, groupIDColumn, direction)
default:
sortQuery += getSort(sort, direction, "movies")
sortQuery += getSort(sort, direction, "groups")
}
// Whatever the sorting, always use name/id as a final sort
sortQuery += ", COALESCE(movies.name, movies.id) COLLATE NATURAL_CI ASC"
sortQuery += ", COALESCE(groups.name, groups.id) COLLATE NATURAL_CI ASC"
return sortQuery, nil
}
@ -551,10 +551,10 @@ func (qb *GroupStore) HasBackImage(ctx context.Context, groupID int) (bool, erro
}
func (qb *GroupStore) FindByPerformerID(ctx context.Context, performerID int) ([]*models.Group, error) {
query := `SELECT DISTINCT movies.*
FROM movies
INNER JOIN movies_scenes ON movies.id = movies_scenes.movie_id
INNER JOIN performers_scenes ON performers_scenes.scene_id = movies_scenes.scene_id
query := `SELECT DISTINCT groups.*
FROM groups
INNER JOIN groups_scenes ON groups.id = groups_scenes.group_id
INNER JOIN performers_scenes ON performers_scenes.scene_id = groups_scenes.scene_id
WHERE performers_scenes.performer_id = ?
`
args := []interface{}{performerID}
@ -562,9 +562,9 @@ WHERE performers_scenes.performer_id = ?
}
func (qb *GroupStore) CountByPerformerID(ctx context.Context, performerID int) (int, error) {
query := `SELECT COUNT(DISTINCT movies_scenes.movie_id) AS count
FROM movies_scenes
INNER JOIN performers_scenes ON performers_scenes.scene_id = movies_scenes.scene_id
query := `SELECT COUNT(DISTINCT groups_scenes.group_id) AS count
FROM groups_scenes
INNER JOIN performers_scenes ON performers_scenes.scene_id = groups_scenes.scene_id
WHERE performers_scenes.performer_id = ?
`
args := []interface{}{performerID}
@ -572,9 +572,9 @@ WHERE performers_scenes.performer_id = ?
}
func (qb *GroupStore) FindByStudioID(ctx context.Context, studioID int) ([]*models.Group, error) {
query := `SELECT movies.*
FROM movies
WHERE movies.studio_id = ?
query := `SELECT groups.*
FROM groups
WHERE groups.studio_id = ?
`
args := []interface{}{studioID}
return qb.queryGroups(ctx, query, args)
@ -582,8 +582,8 @@ WHERE movies.studio_id = ?
func (qb *GroupStore) CountByStudioID(ctx context.Context, studioID int) (int, error) {
query := `SELECT COUNT(1) AS count
FROM movies
WHERE movies.studio_id = ?
FROM groups
WHERE groups.studio_id = ?
`
args := []interface{}{studioID}
return groupRepository.runCountQuery(ctx, query, args)

View file

@ -54,32 +54,32 @@ func (qb *groupFilterHandler) handle(ctx context.Context, f *filterBuilder) {
func (qb *groupFilterHandler) criterionHandler() criterionHandler {
groupFilter := qb.groupFilter
return compoundHandler{
stringCriterionHandler(groupFilter.Name, "movies.name"),
stringCriterionHandler(groupFilter.Director, "movies.director"),
stringCriterionHandler(groupFilter.Synopsis, "movies.synopsis"),
intCriterionHandler(groupFilter.Rating100, "movies.rating", nil),
floatIntCriterionHandler(groupFilter.Duration, "movies.duration", nil),
stringCriterionHandler(groupFilter.Name, "groups.name"),
stringCriterionHandler(groupFilter.Director, "groups.director"),
stringCriterionHandler(groupFilter.Synopsis, "groups.description"),
intCriterionHandler(groupFilter.Rating100, "groups.rating", nil),
floatIntCriterionHandler(groupFilter.Duration, "groups.duration", nil),
qb.missingCriterionHandler(groupFilter.IsMissing),
qb.urlsCriterionHandler(groupFilter.URL),
studioCriterionHandler(groupTable, groupFilter.Studios),
qb.performersCriterionHandler(groupFilter.Performers),
qb.tagsCriterionHandler(groupFilter.Tags),
qb.tagCountCriterionHandler(groupFilter.TagCount),
&dateCriterionHandler{groupFilter.Date, "movies.date", nil},
&timestampCriterionHandler{groupFilter.CreatedAt, "movies.created_at", nil},
&timestampCriterionHandler{groupFilter.UpdatedAt, "movies.updated_at", nil},
&dateCriterionHandler{groupFilter.Date, "groups.date", nil},
&timestampCriterionHandler{groupFilter.CreatedAt, "groups.created_at", nil},
&timestampCriterionHandler{groupFilter.UpdatedAt, "groups.updated_at", nil},
&relatedFilterHandler{
relatedIDCol: "movies_scenes.scene_id",
relatedIDCol: "groups_scenes.scene_id",
relatedRepo: sceneRepository.repository,
relatedHandler: &sceneFilterHandler{groupFilter.ScenesFilter},
joinFn: func(f *filterBuilder) {
groupRepository.scenes.innerJoin(f, "", "movies.id")
groupRepository.scenes.innerJoin(f, "", "groups.id")
},
},
&relatedFilterHandler{
relatedIDCol: "movies.studio_id",
relatedIDCol: "groups.studio_id",
relatedRepo: studioRepository.repository,
relatedHandler: &studioFilterHandler{groupFilter.StudiosFilter},
},
@ -91,14 +91,14 @@ func (qb *groupFilterHandler) missingCriterionHandler(isMissing *string) criteri
if isMissing != nil && *isMissing != "" {
switch *isMissing {
case "front_image":
f.addWhere("movies.front_image_blob IS NULL")
f.addWhere("groups.front_image_blob IS NULL")
case "back_image":
f.addWhere("movies.back_image_blob IS NULL")
f.addWhere("groups.back_image_blob IS NULL")
case "scenes":
f.addLeftJoin("movies_scenes", "", "movies_scenes.movie_id = movies.id")
f.addWhere("movies_scenes.scene_id IS NULL")
f.addLeftJoin("groups_scenes", "", "groups_scenes.group_id = groups.id")
f.addWhere("groups_scenes.scene_id IS NULL")
default:
f.addWhere("(movies." + *isMissing + " IS NULL OR TRIM(movies." + *isMissing + ") = '')")
f.addWhere("(groups." + *isMissing + " IS NULL OR TRIM(groups." + *isMissing + ") = '')")
}
}
}
@ -111,7 +111,7 @@ func (qb *groupFilterHandler) urlsCriterionHandler(url *models.StringCriterionIn
joinTable: groupURLsTable,
stringColumn: groupURLColumn,
addJoinTable: func(f *filterBuilder) {
groupsURLsTableMgr.join(f, "", "movies.id")
groupsURLsTableMgr.join(f, "", "groups.id")
},
}
@ -127,8 +127,8 @@ func (qb *groupFilterHandler) performersCriterionHandler(performers *models.Mult
notClause = "NOT"
}
f.addLeftJoin("movies_scenes", "", "movies.id = movies_scenes.movie_id")
f.addLeftJoin("performers_scenes", "", "movies_scenes.scene_id = performers_scenes.scene_id")
f.addLeftJoin("groups_scenes", "", "groups.id = groups_scenes.group_id")
f.addLeftJoin("performers_scenes", "", "groups_scenes.scene_id = performers_scenes.scene_id")
f.addWhere(fmt.Sprintf("performers_scenes.performer_id IS %s NULL", notClause))
return
@ -144,22 +144,22 @@ func (qb *groupFilterHandler) performersCriterionHandler(performers *models.Mult
}
// Hack, can't apply args to join, nor inner join on a left join, so use CTE instead
f.addWith(`movies_performers AS (
SELECT movies_scenes.movie_id, performers_scenes.performer_id
FROM movies_scenes
INNER JOIN performers_scenes ON movies_scenes.scene_id = performers_scenes.scene_id
f.addWith(`groups_performers AS (
SELECT groups_scenes.group_id, performers_scenes.performer_id
FROM groups_scenes
INNER JOIN performers_scenes ON groups_scenes.scene_id = performers_scenes.scene_id
WHERE performers_scenes.performer_id IN`+getInBinding(len(performers.Value))+`
)`, args...)
f.addLeftJoin("movies_performers", "", "movies.id = movies_performers.movie_id")
f.addLeftJoin("groups_performers", "", "groups.id = groups_performers.group_id")
switch performers.Modifier {
case models.CriterionModifierIncludes:
f.addWhere("movies_performers.performer_id IS NOT NULL")
f.addWhere("groups_performers.performer_id IS NOT NULL")
case models.CriterionModifierIncludesAll:
f.addWhere("movies_performers.performer_id IS NOT NULL")
f.addHaving("COUNT(DISTINCT movies_performers.performer_id) = ?", len(performers.Value))
f.addWhere("groups_performers.performer_id IS NOT NULL")
f.addHaving("COUNT(DISTINCT groups_performers.performer_id) = ?", len(performers.Value))
case models.CriterionModifierExcludes:
f.addWhere("movies_performers.performer_id IS NULL")
f.addWhere("groups_performers.performer_id IS NULL")
}
}
}
@ -172,7 +172,7 @@ func (qb *groupFilterHandler) tagsCriterionHandler(tags *models.HierarchicalMult
foreignFK: "tag_id",
relationsTable: "tags_relations",
joinAs: "movie_tag",
joinAs: "group_tag",
joinTable: groupsTagsTable,
primaryFK: groupIDColumn,
}

View file

@ -0,0 +1,24 @@
ALTER TABLE `movies` RENAME TO `groups`;
ALTER TABLE `groups` RENAME COLUMN `synopsis` TO `description`;
DROP INDEX `index_movies_on_name`;
CREATE INDEX `index_groups_on_name` ON `groups`(`name`);
DROP INDEX `index_movies_on_studio_id`;
CREATE INDEX `index_groups_on_studio_id` on `groups` (`studio_id`);
ALTER TABLE `movie_urls` RENAME TO `group_urls`;
ALTER TABLE `group_urls` RENAME COLUMN `movie_id` TO `group_id`;
DROP INDEX `movie_urls_url`;
CREATE INDEX `group_urls_url` on `group_urls` (`url`);
ALTER TABLE `movies_tags` RENAME TO `groups_tags`;
ALTER TABLE `groups_tags` RENAME COLUMN `movie_id` TO `group_id`;
DROP INDEX `index_movies_tags_on_tag_id`;
CREATE INDEX `index_groups_tags_on_tag_id` on `groups_tags` (`tag_id`);
DROP INDEX `index_movies_tags_on_movie_id`;
CREATE INDEX `index_groups_tags_on_movie_id` on `groups_tags` (`group_id`);
ALTER TABLE `movies_scenes` RENAME TO `groups_scenes`;
ALTER TABLE `groups_scenes` RENAME COLUMN `movie_id` TO `group_id`;

View file

@ -28,7 +28,7 @@ const (
performersScenesTable = "performers_scenes"
scenesTagsTable = "scenes_tags"
scenesGalleriesTable = "scenes_galleries"
groupsScenesTable = "movies_scenes"
groupsScenesTable = "groups_scenes"
scenesURLsTable = "scene_urls"
sceneURLColumn = "url"
scenesViewDatesTable = "scenes_view_dates"
@ -1142,7 +1142,7 @@ func (qb *SceneStore) setSceneSort(query *queryBuilder, findFilter *models.FindF
direction := findFilter.GetDirection()
switch sort {
case "movie_scene_number", "group_scene_number":
query.join(groupsScenesTable, "", "scenes.id = movies_scenes.scene_id")
query.join(groupsScenesTable, "", "scenes.id = groups_scenes.scene_id")
query.sortAndPagination += getSort("scene_index", direction, groupsScenesTable)
case "tag_count":
query.sortAndPagination += getCountSort(sceneTable, scenesTagsTable, sceneIDColumn, direction)

View file

@ -194,7 +194,7 @@ func (qb *sceneFilterHandler) criterionHandler() criterionHandler {
},
&relatedFilterHandler{
relatedIDCol: "movies_scenes.movie_id",
relatedIDCol: "groups_scenes.group_id",
relatedRepo: groupRepository.repository,
relatedHandler: &groupFilterHandler{sceneFilter.MoviesFilter},
joinFn: func(f *filterBuilder) {
@ -320,8 +320,8 @@ func (qb *sceneFilterHandler) isMissingCriterionHandler(isMissing *string) crite
case "studio":
f.addWhere("scenes.studio_id IS NULL")
case "movie":
sceneRepository.groups.join(f, "movies_join", "scenes.id")
f.addWhere("movies_join.scene_id IS NULL")
sceneRepository.groups.join(f, "groups_join", "scenes.id")
f.addWhere("groups_join.scene_id IS NULL")
case "performers":
sceneRepository.performers.join(f, "performers_join", "scenes.id")
f.addWhere("performers_join.scene_id IS NULL")
@ -486,9 +486,9 @@ func (qb *sceneFilterHandler) performerAgeCriterionHandler(performerAge *models.
func (qb *sceneFilterHandler) groupsCriterionHandler(movies *models.MultiCriterionInput) criterionHandlerFunc {
addJoinsFunc := func(f *filterBuilder) {
sceneRepository.groups.join(f, "", "scenes.id")
f.addLeftJoin("movies", "", "movies_scenes.movie_id = movies.id")
f.addLeftJoin("groups", "", "groups_scenes.group_id = groups.id")
}
h := qb.getMultiCriterionHandlerBuilder(groupTable, groupsScenesTable, "movie_id", addJoinsFunc)
h := qb.getMultiCriterionHandlerBuilder(groupTable, groupsScenesTable, "group_id", addJoinsFunc)
return h.handler(movies)
}

View file

@ -594,7 +594,7 @@ type scenesGroupsTable struct {
type groupsScenesRow struct {
SceneID null.Int `db:"scene_id"`
GroupID null.Int `db:"movie_id"`
GroupID null.Int `db:"group_id"`
SceneIndex null.Int `db:"scene_index"`
}
@ -606,7 +606,7 @@ func (r groupsScenesRow) resolve(sceneID int) models.GroupsScenes {
}
func (t *scenesGroupsTable) get(ctx context.Context, id int) ([]models.GroupsScenes, error) {
q := dialect.Select("movie_id", "scene_index").From(t.table.table).Where(t.idColumn.Eq(id))
q := dialect.Select("group_id", "scene_index").From(t.table.table).Where(t.idColumn.Eq(id))
const single = false
var ret []models.GroupsScenes
@ -627,7 +627,7 @@ func (t *scenesGroupsTable) get(ctx context.Context, id int) ([]models.GroupsSce
}
func (t *scenesGroupsTable) insertJoin(ctx context.Context, id int, v models.GroupsScenes) (sql.Result, error) {
q := dialect.Insert(t.table.table).Cols(t.idColumn.GetCol(), "movie_id", "scene_index").Vals(
q := dialect.Insert(t.table.table).Cols(t.idColumn.GetCol(), "group_id", "scene_index").Vals(
goqu.Vals{id, v.GroupID, intFromPtr(v.SceneIndex)},
)
ret, err := exec(ctx, q)
@ -686,7 +686,7 @@ func (t *scenesGroupsTable) destroyJoins(ctx context.Context, id int, v []models
for _, vv := range v {
q := dialect.Delete(t.table.table).Where(
t.idColumn.Eq(id),
t.table.table.Col("movie_id").Eq(vv.GroupID),
t.table.table.Col("group_id").Eq(vv.GroupID),
)
if _, err := exec(ctx, q); err != nil {

View file

@ -424,15 +424,15 @@ func (qb *TagStore) FindByGalleryID(ctx context.Context, galleryID int) ([]*mode
return qb.queryTags(ctx, query, args)
}
func (qb *TagStore) FindByGroupID(ctx context.Context, movieID int) ([]*models.Tag, error) {
func (qb *TagStore) FindByGroupID(ctx context.Context, groupID int) ([]*models.Tag, error) {
query := `
SELECT tags.* FROM tags
LEFT JOIN movies_tags as movies_join on movies_join.tag_id = tags.id
WHERE movies_join.movie_id = ?
LEFT JOIN groups_tags as groups_join on groups_join.tag_id = tags.id
WHERE groups_join.group_id = ?
GROUP BY tags.id
`
query += qb.getDefaultTagSort()
args := []interface{}{movieID}
args := []interface{}{groupID}
return qb.queryTags(ctx, query, args)
}

View file

@ -193,8 +193,8 @@ func (qb *tagFilterHandler) studioCountCriterionHandler(studioCount *models.IntC
func (qb *tagFilterHandler) groupCountCriterionHandler(groupCount *models.IntCriterionInput) criterionHandlerFunc {
return func(ctx context.Context, f *filterBuilder) {
if groupCount != nil {
f.addLeftJoin("movies_tags", "", "movies_tags.tag_id = tags.id")
clause, args := getIntCriterionWhereClause("count(distinct movies_tags.movie_id)", *groupCount)
f.addLeftJoin("groups_tags", "", "groups_tags.tag_id = tags.id")
clause, args := getIntCriterionWhereClause("count(distinct groups_tags.group_id)", *groupCount)
f.addHaving(clause, args...)
}