mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Movie group renames (#5039)
* Rename Movie and MoviePartial to Group/GroupPartial * Rename Movie interfaces * Update movie url builders to use group * Rename movieRoutes to groupRoutes * Update dataloader * Update names in sqlite package * Rename in resolvers * Add GroupByURL to scraper config * Scraper backward compatibility hacks
This commit is contained in:
@@ -57,7 +57,7 @@ func (db *Anonymiser) Anonymise(ctx context.Context) error {
|
||||
func() error { return db.anonymisePerformers(ctx) },
|
||||
func() error { return db.anonymiseStudios(ctx) },
|
||||
func() error { return db.anonymiseTags(ctx) },
|
||||
func() error { return db.anonymiseMovies(ctx) },
|
||||
func() error { return db.anonymiseGroups(ctx) },
|
||||
func() error { return db.Optimise(ctx) },
|
||||
})
|
||||
}(); err != nil {
|
||||
@@ -825,9 +825,9 @@ func (db *Anonymiser) anonymiseTags(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Anonymiser) anonymiseMovies(ctx context.Context) error {
|
||||
logger.Infof("Anonymising movies")
|
||||
table := movieTableMgr.table
|
||||
func (db *Anonymiser) anonymiseGroups(ctx context.Context) error {
|
||||
logger.Infof("Anonymising groups")
|
||||
table := groupTableMgr.table
|
||||
lastID := 0
|
||||
total := 0
|
||||
const logEvery = 10000
|
||||
@@ -883,7 +883,7 @@ func (db *Anonymiser) anonymiseMovies(ctx context.Context) error {
|
||||
total++
|
||||
|
||||
if total%logEvery == 0 {
|
||||
logger.Infof("Anonymised %d movies", total)
|
||||
logger.Infof("Anonymised %d groups", total)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -893,7 +893,7 @@ func (db *Anonymiser) anonymiseMovies(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := db.anonymiseURLs(ctx, goqu.T(movieURLsTable), "movie_id"); err != nil {
|
||||
if err := db.anonymiseURLs(ctx, goqu.T(groupURLsTable), "movie_id"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
type updateImageFunc func(ctx context.Context, id int, image []byte) error
|
||||
type getImageFunc func(ctx context.Context, movieID int) ([]byte, error)
|
||||
type getImageFunc func(ctx context.Context, id int) ([]byte, error)
|
||||
|
||||
func testUpdateImage(t *testing.T, ctx context.Context, id int, updateFn updateImageFunc, getFn getImageFunc) error {
|
||||
image := []byte("image")
|
||||
|
||||
@@ -74,7 +74,7 @@ type storeRepository struct {
|
||||
SavedFilter *SavedFilterStore
|
||||
Studio *StudioStore
|
||||
Tag *TagStore
|
||||
Movie *MovieStore
|
||||
Group *GroupStore
|
||||
}
|
||||
|
||||
type Database struct {
|
||||
@@ -110,7 +110,7 @@ func NewDatabase() *Database {
|
||||
Performer: performerStore,
|
||||
Studio: studioStore,
|
||||
Tag: tagStore,
|
||||
Movie: NewMovieStore(blobStore),
|
||||
Group: NewGroupStore(blobStore),
|
||||
SavedFilter: NewSavedFilterStore(),
|
||||
}
|
||||
|
||||
|
||||
@@ -17,19 +17,19 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
movieTable = "movies"
|
||||
movieIDColumn = "movie_id"
|
||||
groupTable = "movies"
|
||||
groupIDColumn = "movie_id"
|
||||
|
||||
movieFrontImageBlobColumn = "front_image_blob"
|
||||
movieBackImageBlobColumn = "back_image_blob"
|
||||
groupFrontImageBlobColumn = "front_image_blob"
|
||||
groupBackImageBlobColumn = "back_image_blob"
|
||||
|
||||
moviesTagsTable = "movies_tags"
|
||||
groupsTagsTable = "movies_tags"
|
||||
|
||||
movieURLsTable = "movie_urls"
|
||||
movieURLColumn = "url"
|
||||
groupURLsTable = "movie_urls"
|
||||
groupURLColumn = "url"
|
||||
)
|
||||
|
||||
type movieRow struct {
|
||||
type groupRow struct {
|
||||
ID int `db:"id" goqu:"skipinsert"`
|
||||
Name zero.String `db:"name"`
|
||||
Aliases zero.String `db:"aliases"`
|
||||
@@ -48,7 +48,7 @@ type movieRow struct {
|
||||
BackImageBlob zero.String `db:"back_image_blob"`
|
||||
}
|
||||
|
||||
func (r *movieRow) fromMovie(o models.Movie) {
|
||||
func (r *groupRow) fromGroup(o models.Group) {
|
||||
r.ID = o.ID
|
||||
r.Name = zero.StringFrom(o.Name)
|
||||
r.Aliases = zero.StringFrom(o.Aliases)
|
||||
@@ -62,8 +62,8 @@ func (r *movieRow) fromMovie(o models.Movie) {
|
||||
r.UpdatedAt = Timestamp{Timestamp: o.UpdatedAt}
|
||||
}
|
||||
|
||||
func (r *movieRow) resolve() *models.Movie {
|
||||
ret := &models.Movie{
|
||||
func (r *groupRow) resolve() *models.Group {
|
||||
ret := &models.Group{
|
||||
ID: r.ID,
|
||||
Name: r.Name.String,
|
||||
Aliases: r.Aliases.String,
|
||||
@@ -80,11 +80,11 @@ func (r *movieRow) resolve() *models.Movie {
|
||||
return ret
|
||||
}
|
||||
|
||||
type movieRowRecord struct {
|
||||
type groupRowRecord struct {
|
||||
updateRecord
|
||||
}
|
||||
|
||||
func (r *movieRowRecord) fromPartial(o models.MoviePartial) {
|
||||
func (r *groupRowRecord) fromPartial(o models.GroupPartial) {
|
||||
r.setNullString("name", o.Name)
|
||||
r.setNullString("aliases", o.Aliases)
|
||||
r.setNullInt("duration", o.Duration)
|
||||
@@ -97,26 +97,26 @@ func (r *movieRowRecord) fromPartial(o models.MoviePartial) {
|
||||
r.setTimestamp("updated_at", o.UpdatedAt)
|
||||
}
|
||||
|
||||
type movieRepositoryType struct {
|
||||
type groupRepositoryType struct {
|
||||
repository
|
||||
scenes repository
|
||||
tags joinRepository
|
||||
}
|
||||
|
||||
var (
|
||||
movieRepository = movieRepositoryType{
|
||||
groupRepository = groupRepositoryType{
|
||||
repository: repository{
|
||||
tableName: movieTable,
|
||||
tableName: groupTable,
|
||||
idColumn: idColumn,
|
||||
},
|
||||
scenes: repository{
|
||||
tableName: moviesScenesTable,
|
||||
idColumn: movieIDColumn,
|
||||
tableName: groupsScenesTable,
|
||||
idColumn: groupIDColumn,
|
||||
},
|
||||
tags: joinRepository{
|
||||
repository: repository{
|
||||
tableName: moviesTagsTable,
|
||||
idColumn: movieIDColumn,
|
||||
tableName: groupsTagsTable,
|
||||
idColumn: groupIDColumn,
|
||||
},
|
||||
fkColumn: tagIDColumn,
|
||||
foreignTable: tagTable,
|
||||
@@ -125,40 +125,40 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
type MovieStore struct {
|
||||
type GroupStore struct {
|
||||
blobJoinQueryBuilder
|
||||
tagRelationshipStore
|
||||
|
||||
tableMgr *table
|
||||
}
|
||||
|
||||
func NewMovieStore(blobStore *BlobStore) *MovieStore {
|
||||
return &MovieStore{
|
||||
func NewGroupStore(blobStore *BlobStore) *GroupStore {
|
||||
return &GroupStore{
|
||||
blobJoinQueryBuilder: blobJoinQueryBuilder{
|
||||
blobStore: blobStore,
|
||||
joinTable: movieTable,
|
||||
joinTable: groupTable,
|
||||
},
|
||||
tagRelationshipStore: tagRelationshipStore{
|
||||
idRelationshipStore: idRelationshipStore{
|
||||
joinTable: moviesTagsTableMgr,
|
||||
joinTable: groupsTagsTableMgr,
|
||||
},
|
||||
},
|
||||
|
||||
tableMgr: movieTableMgr,
|
||||
tableMgr: groupTableMgr,
|
||||
}
|
||||
}
|
||||
|
||||
func (qb *MovieStore) table() exp.IdentifierExpression {
|
||||
func (qb *GroupStore) table() exp.IdentifierExpression {
|
||||
return qb.tableMgr.table
|
||||
}
|
||||
|
||||
func (qb *MovieStore) selectDataset() *goqu.SelectDataset {
|
||||
func (qb *GroupStore) selectDataset() *goqu.SelectDataset {
|
||||
return dialect.From(qb.table()).Select(qb.table().All())
|
||||
}
|
||||
|
||||
func (qb *MovieStore) Create(ctx context.Context, newObject *models.Movie) error {
|
||||
var r movieRow
|
||||
r.fromMovie(*newObject)
|
||||
func (qb *GroupStore) Create(ctx context.Context, newObject *models.Group) error {
|
||||
var r groupRow
|
||||
r.fromGroup(*newObject)
|
||||
|
||||
id, err := qb.tableMgr.insertID(ctx, r)
|
||||
if err != nil {
|
||||
@@ -167,7 +167,7 @@ func (qb *MovieStore) Create(ctx context.Context, newObject *models.Movie) error
|
||||
|
||||
if newObject.URLs.Loaded() {
|
||||
const startPos = 0
|
||||
if err := moviesURLsTableMgr.insertJoins(ctx, id, startPos, newObject.URLs.List()); err != nil {
|
||||
if err := groupsURLsTableMgr.insertJoins(ctx, id, startPos, newObject.URLs.List()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -186,8 +186,8 @@ func (qb *MovieStore) Create(ctx context.Context, newObject *models.Movie) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (qb *MovieStore) UpdatePartial(ctx context.Context, id int, partial models.MoviePartial) (*models.Movie, error) {
|
||||
r := movieRowRecord{
|
||||
func (qb *GroupStore) UpdatePartial(ctx context.Context, id int, partial models.GroupPartial) (*models.Group, error) {
|
||||
r := groupRowRecord{
|
||||
updateRecord{
|
||||
Record: make(exp.Record),
|
||||
},
|
||||
@@ -202,7 +202,7 @@ func (qb *MovieStore) UpdatePartial(ctx context.Context, id int, partial models.
|
||||
}
|
||||
|
||||
if partial.URLs != nil {
|
||||
if err := moviesURLsTableMgr.modifyJoins(ctx, id, partial.URLs.Values, partial.URLs.Mode); err != nil {
|
||||
if err := groupsURLsTableMgr.modifyJoins(ctx, id, partial.URLs.Values, partial.URLs.Mode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -214,16 +214,16 @@ func (qb *MovieStore) UpdatePartial(ctx context.Context, id int, partial models.
|
||||
return qb.find(ctx, id)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) Update(ctx context.Context, updatedObject *models.Movie) error {
|
||||
var r movieRow
|
||||
r.fromMovie(*updatedObject)
|
||||
func (qb *GroupStore) Update(ctx context.Context, updatedObject *models.Group) error {
|
||||
var r groupRow
|
||||
r.fromGroup(*updatedObject)
|
||||
|
||||
if err := qb.tableMgr.updateByID(ctx, updatedObject.ID, r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if updatedObject.URLs.Loaded() {
|
||||
if err := moviesURLsTableMgr.replaceJoins(ctx, updatedObject.ID, updatedObject.URLs.List()); err != nil {
|
||||
if err := groupsURLsTableMgr.replaceJoins(ctx, updatedObject.ID, updatedObject.URLs.List()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -235,17 +235,17 @@ func (qb *MovieStore) Update(ctx context.Context, updatedObject *models.Movie) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (qb *MovieStore) Destroy(ctx context.Context, id int) error {
|
||||
func (qb *GroupStore) Destroy(ctx context.Context, id int) error {
|
||||
// must handle image checksums manually
|
||||
if err := qb.destroyImages(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return movieRepository.destroyExisting(ctx, []int{id})
|
||||
return groupRepository.destroyExisting(ctx, []int{id})
|
||||
}
|
||||
|
||||
// returns nil, nil if not found
|
||||
func (qb *MovieStore) Find(ctx context.Context, id int) (*models.Movie, error) {
|
||||
func (qb *GroupStore) Find(ctx context.Context, id int) (*models.Group, error) {
|
||||
ret, err := qb.find(ctx, id)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, nil
|
||||
@@ -253,8 +253,8 @@ func (qb *MovieStore) Find(ctx context.Context, id int) (*models.Movie, error) {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (qb *MovieStore) FindMany(ctx context.Context, ids []int) ([]*models.Movie, error) {
|
||||
ret := make([]*models.Movie, len(ids))
|
||||
func (qb *GroupStore) FindMany(ctx context.Context, ids []int) ([]*models.Group, error) {
|
||||
ret := make([]*models.Group, len(ids))
|
||||
|
||||
table := qb.table()
|
||||
if err := batchExec(ids, defaultBatchSize, func(batch []int) error {
|
||||
@@ -276,7 +276,7 @@ func (qb *MovieStore) FindMany(ctx context.Context, ids []int) ([]*models.Movie,
|
||||
|
||||
for i := range ret {
|
||||
if ret[i] == nil {
|
||||
return nil, fmt.Errorf("movie with id %d not found", ids[i])
|
||||
return nil, fmt.Errorf("group with id %d not found", ids[i])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,7 +284,7 @@ func (qb *MovieStore) FindMany(ctx context.Context, ids []int) ([]*models.Movie,
|
||||
}
|
||||
|
||||
// returns nil, sql.ErrNoRows if not found
|
||||
func (qb *MovieStore) find(ctx context.Context, id int) (*models.Movie, error) {
|
||||
func (qb *GroupStore) find(ctx context.Context, id int) (*models.Group, error) {
|
||||
q := qb.selectDataset().Where(qb.tableMgr.byID(id))
|
||||
|
||||
ret, err := qb.get(ctx, q)
|
||||
@@ -296,7 +296,7 @@ func (qb *MovieStore) find(ctx context.Context, id int) (*models.Movie, error) {
|
||||
}
|
||||
|
||||
// returns nil, sql.ErrNoRows if not found
|
||||
func (qb *MovieStore) get(ctx context.Context, q *goqu.SelectDataset) (*models.Movie, error) {
|
||||
func (qb *GroupStore) get(ctx context.Context, q *goqu.SelectDataset) (*models.Group, error) {
|
||||
ret, err := qb.getMany(ctx, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -309,11 +309,11 @@ func (qb *MovieStore) get(ctx context.Context, q *goqu.SelectDataset) (*models.M
|
||||
return ret[0], nil
|
||||
}
|
||||
|
||||
func (qb *MovieStore) getMany(ctx context.Context, q *goqu.SelectDataset) ([]*models.Movie, error) {
|
||||
func (qb *GroupStore) getMany(ctx context.Context, q *goqu.SelectDataset) ([]*models.Group, error) {
|
||||
const single = false
|
||||
var ret []*models.Movie
|
||||
var ret []*models.Group
|
||||
if err := queryFunc(ctx, q, single, func(r *sqlx.Rows) error {
|
||||
var f movieRow
|
||||
var f groupRow
|
||||
if err := r.StructScan(&f); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -329,7 +329,7 @@ func (qb *MovieStore) getMany(ctx context.Context, q *goqu.SelectDataset) ([]*mo
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (qb *MovieStore) FindByName(ctx context.Context, name string, nocase bool) (*models.Movie, error) {
|
||||
func (qb *GroupStore) FindByName(ctx context.Context, name string, nocase bool) (*models.Group, error) {
|
||||
// query := "SELECT * FROM movies WHERE name = ?"
|
||||
// if nocase {
|
||||
// query += " COLLATE NOCASE"
|
||||
@@ -349,7 +349,7 @@ func (qb *MovieStore) FindByName(ctx context.Context, name string, nocase bool)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (qb *MovieStore) FindByNames(ctx context.Context, names []string, nocase bool) ([]*models.Movie, error) {
|
||||
func (qb *GroupStore) FindByNames(ctx context.Context, names []string, nocase bool) ([]*models.Group, error) {
|
||||
// query := "SELECT * FROM movies WHERE name"
|
||||
// if nocase {
|
||||
// query += " COLLATE NOCASE"
|
||||
@@ -374,12 +374,12 @@ func (qb *MovieStore) FindByNames(ctx context.Context, names []string, nocase bo
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (qb *MovieStore) Count(ctx context.Context) (int, error) {
|
||||
func (qb *GroupStore) Count(ctx context.Context) (int, error) {
|
||||
q := dialect.Select(goqu.COUNT("*")).From(qb.table())
|
||||
return count(ctx, q)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) All(ctx context.Context) ([]*models.Movie, error) {
|
||||
func (qb *GroupStore) All(ctx context.Context) ([]*models.Group, error) {
|
||||
table := qb.table()
|
||||
|
||||
return qb.getMany(ctx, qb.selectDataset().Order(
|
||||
@@ -388,24 +388,24 @@ func (qb *MovieStore) All(ctx context.Context) ([]*models.Movie, error) {
|
||||
))
|
||||
}
|
||||
|
||||
func (qb *MovieStore) makeQuery(ctx context.Context, movieFilter *models.MovieFilterType, findFilter *models.FindFilterType) (*queryBuilder, error) {
|
||||
func (qb *GroupStore) makeQuery(ctx context.Context, groupFilter *models.GroupFilterType, findFilter *models.FindFilterType) (*queryBuilder, error) {
|
||||
if findFilter == nil {
|
||||
findFilter = &models.FindFilterType{}
|
||||
}
|
||||
if movieFilter == nil {
|
||||
movieFilter = &models.MovieFilterType{}
|
||||
if groupFilter == nil {
|
||||
groupFilter = &models.GroupFilterType{}
|
||||
}
|
||||
|
||||
query := movieRepository.newQuery()
|
||||
distinctIDs(&query, movieTable)
|
||||
query := groupRepository.newQuery()
|
||||
distinctIDs(&query, groupTable)
|
||||
|
||||
if q := findFilter.Q; q != nil && *q != "" {
|
||||
searchColumns := []string{"movies.name", "movies.aliases"}
|
||||
query.parseQueryString(searchColumns, *q)
|
||||
}
|
||||
|
||||
filter := filterBuilderFromHandler(ctx, &movieFilterHandler{
|
||||
movieFilter: movieFilter,
|
||||
filter := filterBuilderFromHandler(ctx, &groupFilterHandler{
|
||||
groupFilter: groupFilter,
|
||||
})
|
||||
|
||||
if err := query.addFilter(filter); err != nil {
|
||||
@@ -413,7 +413,7 @@ func (qb *MovieStore) makeQuery(ctx context.Context, movieFilter *models.MovieFi
|
||||
}
|
||||
|
||||
var err error
|
||||
query.sortAndPagination, err = qb.getMovieSort(findFilter)
|
||||
query.sortAndPagination, err = qb.getGroupSort(findFilter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -423,8 +423,8 @@ func (qb *MovieStore) makeQuery(ctx context.Context, movieFilter *models.MovieFi
|
||||
return &query, nil
|
||||
}
|
||||
|
||||
func (qb *MovieStore) Query(ctx context.Context, movieFilter *models.MovieFilterType, findFilter *models.FindFilterType) ([]*models.Movie, int, error) {
|
||||
query, err := qb.makeQuery(ctx, movieFilter, findFilter)
|
||||
func (qb *GroupStore) Query(ctx context.Context, groupFilter *models.GroupFilterType, findFilter *models.FindFilterType) ([]*models.Group, int, error) {
|
||||
query, err := qb.makeQuery(ctx, groupFilter, findFilter)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
@@ -434,16 +434,16 @@ func (qb *MovieStore) Query(ctx context.Context, movieFilter *models.MovieFilter
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
movies, err := qb.FindMany(ctx, idsResult)
|
||||
groups, err := qb.FindMany(ctx, idsResult)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return movies, countResult, nil
|
||||
return groups, countResult, nil
|
||||
}
|
||||
|
||||
func (qb *MovieStore) QueryCount(ctx context.Context, movieFilter *models.MovieFilterType, findFilter *models.FindFilterType) (int, error) {
|
||||
query, err := qb.makeQuery(ctx, movieFilter, findFilter)
|
||||
func (qb *GroupStore) QueryCount(ctx context.Context, groupFilter *models.GroupFilterType, findFilter *models.FindFilterType) (int, error) {
|
||||
query, err := qb.makeQuery(ctx, groupFilter, findFilter)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -451,7 +451,7 @@ func (qb *MovieStore) QueryCount(ctx context.Context, movieFilter *models.MovieF
|
||||
return query.executeCount(ctx)
|
||||
}
|
||||
|
||||
var movieSortOptions = sortOptions{
|
||||
var groupSortOptions = sortOptions{
|
||||
"created_at",
|
||||
"date",
|
||||
"duration",
|
||||
@@ -464,7 +464,7 @@ var movieSortOptions = sortOptions{
|
||||
"updated_at",
|
||||
}
|
||||
|
||||
func (qb *MovieStore) getMovieSort(findFilter *models.FindFilterType) (string, error) {
|
||||
func (qb *GroupStore) getGroupSort(findFilter *models.FindFilterType) (string, error) {
|
||||
var sort string
|
||||
var direction string
|
||||
if findFilter == nil {
|
||||
@@ -476,16 +476,16 @@ func (qb *MovieStore) getMovieSort(findFilter *models.FindFilterType) (string, e
|
||||
}
|
||||
|
||||
// CVE-2024-32231 - ensure sort is in the list of allowed sorts
|
||||
if err := movieSortOptions.validateSort(sort); err != nil {
|
||||
if err := groupSortOptions.validateSort(sort); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sortQuery := ""
|
||||
switch sort {
|
||||
case "tag_count":
|
||||
sortQuery += getCountSort(movieTable, moviesTagsTable, movieIDColumn, direction)
|
||||
sortQuery += getCountSort(groupTable, groupsTagsTable, groupIDColumn, direction)
|
||||
case "scenes_count": // generic getSort won't work for this
|
||||
sortQuery += getCountSort(movieTable, moviesScenesTable, movieIDColumn, direction)
|
||||
sortQuery += getCountSort(groupTable, groupsScenesTable, groupIDColumn, direction)
|
||||
default:
|
||||
sortQuery += getSort(sort, direction, "movies")
|
||||
}
|
||||
@@ -495,11 +495,11 @@ func (qb *MovieStore) getMovieSort(findFilter *models.FindFilterType) (string, e
|
||||
return sortQuery, nil
|
||||
}
|
||||
|
||||
func (qb *MovieStore) queryMovies(ctx context.Context, query string, args []interface{}) ([]*models.Movie, error) {
|
||||
func (qb *GroupStore) queryGroups(ctx context.Context, query string, args []interface{}) ([]*models.Group, error) {
|
||||
const single = false
|
||||
var ret []*models.Movie
|
||||
if err := movieRepository.queryFunc(ctx, query, args, single, func(r *sqlx.Rows) error {
|
||||
var f movieRow
|
||||
var ret []*models.Group
|
||||
if err := groupRepository.queryFunc(ctx, query, args, single, func(r *sqlx.Rows) error {
|
||||
var f groupRow
|
||||
if err := r.StructScan(&f); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -515,42 +515,42 @@ func (qb *MovieStore) queryMovies(ctx context.Context, query string, args []inte
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (qb *MovieStore) UpdateFrontImage(ctx context.Context, movieID int, frontImage []byte) error {
|
||||
return qb.UpdateImage(ctx, movieID, movieFrontImageBlobColumn, frontImage)
|
||||
func (qb *GroupStore) UpdateFrontImage(ctx context.Context, groupID int, frontImage []byte) error {
|
||||
return qb.UpdateImage(ctx, groupID, groupFrontImageBlobColumn, frontImage)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) UpdateBackImage(ctx context.Context, movieID int, backImage []byte) error {
|
||||
return qb.UpdateImage(ctx, movieID, movieBackImageBlobColumn, backImage)
|
||||
func (qb *GroupStore) UpdateBackImage(ctx context.Context, groupID int, backImage []byte) error {
|
||||
return qb.UpdateImage(ctx, groupID, groupBackImageBlobColumn, backImage)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) destroyImages(ctx context.Context, movieID int) error {
|
||||
if err := qb.DestroyImage(ctx, movieID, movieFrontImageBlobColumn); err != nil {
|
||||
func (qb *GroupStore) destroyImages(ctx context.Context, groupID int) error {
|
||||
if err := qb.DestroyImage(ctx, groupID, groupFrontImageBlobColumn); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := qb.DestroyImage(ctx, movieID, movieBackImageBlobColumn); err != nil {
|
||||
if err := qb.DestroyImage(ctx, groupID, groupBackImageBlobColumn); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (qb *MovieStore) GetFrontImage(ctx context.Context, movieID int) ([]byte, error) {
|
||||
return qb.GetImage(ctx, movieID, movieFrontImageBlobColumn)
|
||||
func (qb *GroupStore) GetFrontImage(ctx context.Context, groupID int) ([]byte, error) {
|
||||
return qb.GetImage(ctx, groupID, groupFrontImageBlobColumn)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) HasFrontImage(ctx context.Context, movieID int) (bool, error) {
|
||||
return qb.HasImage(ctx, movieID, movieFrontImageBlobColumn)
|
||||
func (qb *GroupStore) HasFrontImage(ctx context.Context, groupID int) (bool, error) {
|
||||
return qb.HasImage(ctx, groupID, groupFrontImageBlobColumn)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) GetBackImage(ctx context.Context, movieID int) ([]byte, error) {
|
||||
return qb.GetImage(ctx, movieID, movieBackImageBlobColumn)
|
||||
func (qb *GroupStore) GetBackImage(ctx context.Context, groupID int) ([]byte, error) {
|
||||
return qb.GetImage(ctx, groupID, groupBackImageBlobColumn)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) HasBackImage(ctx context.Context, movieID int) (bool, error) {
|
||||
return qb.HasImage(ctx, movieID, movieBackImageBlobColumn)
|
||||
func (qb *GroupStore) HasBackImage(ctx context.Context, groupID int) (bool, error) {
|
||||
return qb.HasImage(ctx, groupID, groupBackImageBlobColumn)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) FindByPerformerID(ctx context.Context, performerID int) ([]*models.Movie, error) {
|
||||
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
|
||||
@@ -558,37 +558,37 @@ INNER JOIN performers_scenes ON performers_scenes.scene_id = movies_scenes.scene
|
||||
WHERE performers_scenes.performer_id = ?
|
||||
`
|
||||
args := []interface{}{performerID}
|
||||
return qb.queryMovies(ctx, query, args)
|
||||
return qb.queryGroups(ctx, query, args)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) CountByPerformerID(ctx context.Context, performerID int) (int, error) {
|
||||
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
|
||||
WHERE performers_scenes.performer_id = ?
|
||||
`
|
||||
args := []interface{}{performerID}
|
||||
return movieRepository.runCountQuery(ctx, query, args)
|
||||
return groupRepository.runCountQuery(ctx, query, args)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) FindByStudioID(ctx context.Context, studioID int) ([]*models.Movie, error) {
|
||||
func (qb *GroupStore) FindByStudioID(ctx context.Context, studioID int) ([]*models.Group, error) {
|
||||
query := `SELECT movies.*
|
||||
FROM movies
|
||||
WHERE movies.studio_id = ?
|
||||
`
|
||||
args := []interface{}{studioID}
|
||||
return qb.queryMovies(ctx, query, args)
|
||||
return qb.queryGroups(ctx, query, args)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) CountByStudioID(ctx context.Context, studioID int) (int, error) {
|
||||
func (qb *GroupStore) CountByStudioID(ctx context.Context, studioID int) (int, error) {
|
||||
query := `SELECT COUNT(1) AS count
|
||||
FROM movies
|
||||
WHERE movies.studio_id = ?
|
||||
`
|
||||
args := []interface{}{studioID}
|
||||
return movieRepository.runCountQuery(ctx, query, args)
|
||||
return groupRepository.runCountQuery(ctx, query, args)
|
||||
}
|
||||
|
||||
func (qb *MovieStore) GetURLs(ctx context.Context, movieID int) ([]string, error) {
|
||||
return moviesURLsTableMgr.get(ctx, movieID)
|
||||
func (qb *GroupStore) GetURLs(ctx context.Context, groupID int) ([]string, error) {
|
||||
return groupsURLsTableMgr.get(ctx, groupID)
|
||||
}
|
||||
|
||||
@@ -7,22 +7,22 @@ import (
|
||||
"github.com/stashapp/stash/pkg/models"
|
||||
)
|
||||
|
||||
type movieFilterHandler struct {
|
||||
movieFilter *models.MovieFilterType
|
||||
type groupFilterHandler struct {
|
||||
groupFilter *models.GroupFilterType
|
||||
}
|
||||
|
||||
func (qb *movieFilterHandler) validate() error {
|
||||
movieFilter := qb.movieFilter
|
||||
if movieFilter == nil {
|
||||
func (qb *groupFilterHandler) validate() error {
|
||||
groupFilter := qb.groupFilter
|
||||
if groupFilter == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := validateFilterCombination(movieFilter.OperatorFilter); err != nil {
|
||||
if err := validateFilterCombination(groupFilter.OperatorFilter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if subFilter := movieFilter.SubFilter(); subFilter != nil {
|
||||
sqb := &movieFilterHandler{movieFilter: subFilter}
|
||||
if subFilter := groupFilter.SubFilter(); subFilter != nil {
|
||||
sqb := &groupFilterHandler{groupFilter: subFilter}
|
||||
if err := sqb.validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -31,9 +31,9 @@ func (qb *movieFilterHandler) validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (qb *movieFilterHandler) handle(ctx context.Context, f *filterBuilder) {
|
||||
movieFilter := qb.movieFilter
|
||||
if movieFilter == nil {
|
||||
func (qb *groupFilterHandler) handle(ctx context.Context, f *filterBuilder) {
|
||||
groupFilter := qb.groupFilter
|
||||
if groupFilter == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -42,51 +42,51 @@ func (qb *movieFilterHandler) handle(ctx context.Context, f *filterBuilder) {
|
||||
return
|
||||
}
|
||||
|
||||
sf := movieFilter.SubFilter()
|
||||
sf := groupFilter.SubFilter()
|
||||
if sf != nil {
|
||||
sub := &movieFilterHandler{sf}
|
||||
handleSubFilter(ctx, sub, f, movieFilter.OperatorFilter)
|
||||
sub := &groupFilterHandler{sf}
|
||||
handleSubFilter(ctx, sub, f, groupFilter.OperatorFilter)
|
||||
}
|
||||
|
||||
f.handleCriterion(ctx, qb.criterionHandler())
|
||||
}
|
||||
|
||||
func (qb *movieFilterHandler) criterionHandler() criterionHandler {
|
||||
movieFilter := qb.movieFilter
|
||||
func (qb *groupFilterHandler) criterionHandler() criterionHandler {
|
||||
groupFilter := qb.groupFilter
|
||||
return compoundHandler{
|
||||
stringCriterionHandler(movieFilter.Name, "movies.name"),
|
||||
stringCriterionHandler(movieFilter.Director, "movies.director"),
|
||||
stringCriterionHandler(movieFilter.Synopsis, "movies.synopsis"),
|
||||
intCriterionHandler(movieFilter.Rating100, "movies.rating", nil),
|
||||
floatIntCriterionHandler(movieFilter.Duration, "movies.duration", nil),
|
||||
qb.missingCriterionHandler(movieFilter.IsMissing),
|
||||
qb.urlsCriterionHandler(movieFilter.URL),
|
||||
studioCriterionHandler(movieTable, movieFilter.Studios),
|
||||
qb.performersCriterionHandler(movieFilter.Performers),
|
||||
qb.tagsCriterionHandler(movieFilter.Tags),
|
||||
qb.tagCountCriterionHandler(movieFilter.TagCount),
|
||||
&dateCriterionHandler{movieFilter.Date, "movies.date", nil},
|
||||
×tampCriterionHandler{movieFilter.CreatedAt, "movies.created_at", nil},
|
||||
×tampCriterionHandler{movieFilter.UpdatedAt, "movies.updated_at", nil},
|
||||
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),
|
||||
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},
|
||||
×tampCriterionHandler{groupFilter.CreatedAt, "movies.created_at", nil},
|
||||
×tampCriterionHandler{groupFilter.UpdatedAt, "movies.updated_at", nil},
|
||||
|
||||
&relatedFilterHandler{
|
||||
relatedIDCol: "movies_scenes.scene_id",
|
||||
relatedRepo: sceneRepository.repository,
|
||||
relatedHandler: &sceneFilterHandler{movieFilter.ScenesFilter},
|
||||
relatedHandler: &sceneFilterHandler{groupFilter.ScenesFilter},
|
||||
joinFn: func(f *filterBuilder) {
|
||||
movieRepository.scenes.innerJoin(f, "", "movies.id")
|
||||
groupRepository.scenes.innerJoin(f, "", "movies.id")
|
||||
},
|
||||
},
|
||||
|
||||
&relatedFilterHandler{
|
||||
relatedIDCol: "movies.studio_id",
|
||||
relatedRepo: studioRepository.repository,
|
||||
relatedHandler: &studioFilterHandler{movieFilter.StudiosFilter},
|
||||
relatedHandler: &studioFilterHandler{groupFilter.StudiosFilter},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (qb *movieFilterHandler) missingCriterionHandler(isMissing *string) criterionHandlerFunc {
|
||||
func (qb *groupFilterHandler) missingCriterionHandler(isMissing *string) criterionHandlerFunc {
|
||||
return func(ctx context.Context, f *filterBuilder) {
|
||||
if isMissing != nil && *isMissing != "" {
|
||||
switch *isMissing {
|
||||
@@ -104,21 +104,21 @@ func (qb *movieFilterHandler) missingCriterionHandler(isMissing *string) criteri
|
||||
}
|
||||
}
|
||||
|
||||
func (qb *movieFilterHandler) urlsCriterionHandler(url *models.StringCriterionInput) criterionHandlerFunc {
|
||||
func (qb *groupFilterHandler) urlsCriterionHandler(url *models.StringCriterionInput) criterionHandlerFunc {
|
||||
h := stringListCriterionHandlerBuilder{
|
||||
primaryTable: movieTable,
|
||||
primaryFK: movieIDColumn,
|
||||
joinTable: movieURLsTable,
|
||||
stringColumn: movieURLColumn,
|
||||
primaryTable: groupTable,
|
||||
primaryFK: groupIDColumn,
|
||||
joinTable: groupURLsTable,
|
||||
stringColumn: groupURLColumn,
|
||||
addJoinTable: func(f *filterBuilder) {
|
||||
moviesURLsTableMgr.join(f, "", "movies.id")
|
||||
groupsURLsTableMgr.join(f, "", "movies.id")
|
||||
},
|
||||
}
|
||||
|
||||
return h.handler(url)
|
||||
}
|
||||
|
||||
func (qb *movieFilterHandler) performersCriterionHandler(performers *models.MultiCriterionInput) criterionHandlerFunc {
|
||||
func (qb *groupFilterHandler) performersCriterionHandler(performers *models.MultiCriterionInput) criterionHandlerFunc {
|
||||
return func(ctx context.Context, f *filterBuilder) {
|
||||
if performers != nil {
|
||||
if performers.Modifier == models.CriterionModifierIsNull || performers.Modifier == models.CriterionModifierNotNull {
|
||||
@@ -165,26 +165,26 @@ func (qb *movieFilterHandler) performersCriterionHandler(performers *models.Mult
|
||||
}
|
||||
}
|
||||
|
||||
func (qb *movieFilterHandler) tagsCriterionHandler(tags *models.HierarchicalMultiCriterionInput) criterionHandlerFunc {
|
||||
func (qb *groupFilterHandler) tagsCriterionHandler(tags *models.HierarchicalMultiCriterionInput) criterionHandlerFunc {
|
||||
h := joinedHierarchicalMultiCriterionHandlerBuilder{
|
||||
primaryTable: movieTable,
|
||||
primaryTable: groupTable,
|
||||
foreignTable: tagTable,
|
||||
foreignFK: "tag_id",
|
||||
|
||||
relationsTable: "tags_relations",
|
||||
joinAs: "movie_tag",
|
||||
joinTable: moviesTagsTable,
|
||||
primaryFK: movieIDColumn,
|
||||
joinTable: groupsTagsTable,
|
||||
primaryFK: groupIDColumn,
|
||||
}
|
||||
|
||||
return h.handler(tags)
|
||||
}
|
||||
|
||||
func (qb *movieFilterHandler) tagCountCriterionHandler(count *models.IntCriterionInput) criterionHandlerFunc {
|
||||
func (qb *groupFilterHandler) tagCountCriterionHandler(count *models.IntCriterionInput) criterionHandlerFunc {
|
||||
h := countCriterionHandlerBuilder{
|
||||
primaryTable: movieTable,
|
||||
joinTable: moviesTagsTable,
|
||||
primaryFK: movieIDColumn,
|
||||
primaryTable: groupTable,
|
||||
joinTable: groupsTagsTable,
|
||||
primaryFK: groupIDColumn,
|
||||
}
|
||||
|
||||
return h.handler(count)
|
||||
|
||||
@@ -16,14 +16,14 @@ import (
|
||||
"github.com/stashapp/stash/pkg/models"
|
||||
)
|
||||
|
||||
func loadMovieRelationships(ctx context.Context, expected models.Movie, actual *models.Movie) error {
|
||||
func loadGroupRelationships(ctx context.Context, expected models.Group, actual *models.Group) error {
|
||||
if expected.URLs.Loaded() {
|
||||
if err := actual.LoadURLs(ctx, db.Movie); err != nil {
|
||||
if err := actual.LoadURLs(ctx, db.Group); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if expected.TagIDs.Loaded() {
|
||||
if err := actual.LoadTagIDs(ctx, db.Movie); err != nil {
|
||||
if err := actual.LoadTagIDs(ctx, db.Group); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ func loadMovieRelationships(ctx context.Context, expected models.Movie, actual *
|
||||
return nil
|
||||
}
|
||||
|
||||
func Test_MovieStore_Create(t *testing.T) {
|
||||
func Test_GroupStore_Create(t *testing.T) {
|
||||
var (
|
||||
name = "name"
|
||||
url = "url"
|
||||
@@ -47,21 +47,21 @@ func Test_MovieStore_Create(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
newObject models.Movie
|
||||
newObject models.Group
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
"full",
|
||||
models.Movie{
|
||||
models.Group{
|
||||
Name: name,
|
||||
Duration: &duration,
|
||||
Date: &date,
|
||||
Rating: &rating,
|
||||
StudioID: &studioIDs[studioIdxWithMovie],
|
||||
StudioID: &studioIDs[studioIdxWithGroup],
|
||||
Director: director,
|
||||
Synopsis: synopsis,
|
||||
URLs: models.NewRelatedStrings([]string{url}),
|
||||
TagIDs: models.NewRelatedIDs([]int{tagIDs[tagIdx1WithDupName], tagIDs[tagIdx1WithMovie]}),
|
||||
TagIDs: models.NewRelatedIDs([]int{tagIDs[tagIdx1WithDupName], tagIDs[tagIdx1WithGroup]}),
|
||||
Aliases: aliases,
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: updatedAt,
|
||||
@@ -70,7 +70,7 @@ func Test_MovieStore_Create(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"invalid tag id",
|
||||
models.Movie{
|
||||
models.Group{
|
||||
Name: name,
|
||||
TagIDs: models.NewRelatedIDs([]int{invalidID}),
|
||||
},
|
||||
@@ -78,7 +78,7 @@ func Test_MovieStore_Create(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
qb := db.Movie
|
||||
qb := db.Group
|
||||
|
||||
for _, tt := range tests {
|
||||
runWithRollbackTxn(t, tt.name, func(t *testing.T, ctx context.Context) {
|
||||
@@ -86,7 +86,7 @@ func Test_MovieStore_Create(t *testing.T) {
|
||||
|
||||
p := tt.newObject
|
||||
if err := qb.Create(ctx, &p); (err != nil) != tt.wantErr {
|
||||
t.Errorf("MovieStore.Create() error = %v, wantErr = %v", err, tt.wantErr)
|
||||
t.Errorf("GroupStore.Create() error = %v, wantErr = %v", err, tt.wantErr)
|
||||
}
|
||||
|
||||
if tt.wantErr {
|
||||
@@ -100,17 +100,17 @@ func Test_MovieStore_Create(t *testing.T) {
|
||||
copy.ID = p.ID
|
||||
|
||||
// load relationships
|
||||
if err := loadMovieRelationships(ctx, copy, &p); err != nil {
|
||||
t.Errorf("loadMovieRelationships() error = %v", err)
|
||||
if err := loadGroupRelationships(ctx, copy, &p); err != nil {
|
||||
t.Errorf("loadGroupRelationships() error = %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(copy, p)
|
||||
|
||||
// ensure can find the movie
|
||||
// ensure can find the group
|
||||
found, err := qb.Find(ctx, p.ID)
|
||||
if err != nil {
|
||||
t.Errorf("MovieStore.Find() error = %v", err)
|
||||
t.Errorf("GroupStore.Find() error = %v", err)
|
||||
}
|
||||
|
||||
if !assert.NotNil(found) {
|
||||
@@ -118,8 +118,8 @@ func Test_MovieStore_Create(t *testing.T) {
|
||||
}
|
||||
|
||||
// load relationships
|
||||
if err := loadMovieRelationships(ctx, copy, found); err != nil {
|
||||
t.Errorf("loadMovieRelationships() error = %v", err)
|
||||
if err := loadGroupRelationships(ctx, copy, found); err != nil {
|
||||
t.Errorf("loadGroupRelationships() error = %v", err)
|
||||
return
|
||||
}
|
||||
assert.Equal(copy, *found)
|
||||
@@ -129,7 +129,7 @@ func Test_MovieStore_Create(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_movieQueryBuilder_Update(t *testing.T) {
|
||||
func Test_groupQueryBuilder_Update(t *testing.T) {
|
||||
var (
|
||||
name = "name"
|
||||
url = "url"
|
||||
@@ -145,22 +145,22 @@ func Test_movieQueryBuilder_Update(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
updatedObject *models.Movie
|
||||
updatedObject *models.Group
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
"full",
|
||||
&models.Movie{
|
||||
ID: movieIDs[movieIdxWithTag],
|
||||
&models.Group{
|
||||
ID: groupIDs[groupIdxWithTag],
|
||||
Name: name,
|
||||
Duration: &duration,
|
||||
Date: &date,
|
||||
Rating: &rating,
|
||||
StudioID: &studioIDs[studioIdxWithMovie],
|
||||
StudioID: &studioIDs[studioIdxWithGroup],
|
||||
Director: director,
|
||||
Synopsis: synopsis,
|
||||
URLs: models.NewRelatedStrings([]string{url}),
|
||||
TagIDs: models.NewRelatedIDs([]int{tagIDs[tagIdx1WithDupName], tagIDs[tagIdx1WithMovie]}),
|
||||
TagIDs: models.NewRelatedIDs([]int{tagIDs[tagIdx1WithDupName], tagIDs[tagIdx1WithGroup]}),
|
||||
Aliases: aliases,
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: updatedAt,
|
||||
@@ -169,8 +169,8 @@ func Test_movieQueryBuilder_Update(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"clear tag ids",
|
||||
&models.Movie{
|
||||
ID: movieIDs[movieIdxWithTag],
|
||||
&models.Group{
|
||||
ID: groupIDs[groupIdxWithTag],
|
||||
Name: name,
|
||||
TagIDs: models.NewRelatedIDs([]int{}),
|
||||
},
|
||||
@@ -178,8 +178,8 @@ func Test_movieQueryBuilder_Update(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"invalid studio id",
|
||||
&models.Movie{
|
||||
ID: movieIDs[movieIdxWithScene],
|
||||
&models.Group{
|
||||
ID: groupIDs[groupIdxWithScene],
|
||||
Name: name,
|
||||
StudioID: &invalidID,
|
||||
},
|
||||
@@ -187,8 +187,8 @@ func Test_movieQueryBuilder_Update(t *testing.T) {
|
||||
},
|
||||
{
|
||||
"invalid tag id",
|
||||
&models.Movie{
|
||||
ID: movieIDs[movieIdxWithScene],
|
||||
&models.Group{
|
||||
ID: groupIDs[groupIdxWithScene],
|
||||
Name: name,
|
||||
TagIDs: models.NewRelatedIDs([]int{invalidID}),
|
||||
},
|
||||
@@ -196,7 +196,7 @@ func Test_movieQueryBuilder_Update(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
qb := db.Movie
|
||||
qb := db.Group
|
||||
for _, tt := range tests {
|
||||
runWithRollbackTxn(t, tt.name, func(t *testing.T, ctx context.Context) {
|
||||
assert := assert.New(t)
|
||||
@@ -204,7 +204,7 @@ func Test_movieQueryBuilder_Update(t *testing.T) {
|
||||
copy := *tt.updatedObject
|
||||
|
||||
if err := qb.Update(ctx, tt.updatedObject); (err != nil) != tt.wantErr {
|
||||
t.Errorf("movieQueryBuilder.Update() error = %v, wantErr %v", err, tt.wantErr)
|
||||
t.Errorf("groupQueryBuilder.Update() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
|
||||
if tt.wantErr {
|
||||
@@ -213,12 +213,12 @@ func Test_movieQueryBuilder_Update(t *testing.T) {
|
||||
|
||||
s, err := qb.Find(ctx, tt.updatedObject.ID)
|
||||
if err != nil {
|
||||
t.Errorf("movieQueryBuilder.Find() error = %v", err)
|
||||
t.Errorf("groupQueryBuilder.Find() error = %v", err)
|
||||
}
|
||||
|
||||
// load relationships
|
||||
if err := loadMovieRelationships(ctx, copy, s); err != nil {
|
||||
t.Errorf("loadMovieRelationships() error = %v", err)
|
||||
if err := loadGroupRelationships(ctx, copy, s); err != nil {
|
||||
t.Errorf("loadGroupRelationships() error = %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -227,9 +227,9 @@ func Test_movieQueryBuilder_Update(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func clearMoviePartial() models.MoviePartial {
|
||||
func clearGroupPartial() models.GroupPartial {
|
||||
// leave mandatory fields
|
||||
return models.MoviePartial{
|
||||
return models.GroupPartial{
|
||||
Aliases: models.OptionalString{Set: true, Null: true},
|
||||
Synopsis: models.OptionalString{Set: true, Null: true},
|
||||
Director: models.OptionalString{Set: true, Null: true},
|
||||
@@ -242,7 +242,7 @@ func clearMoviePartial() models.MoviePartial {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_movieQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
func Test_groupQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
var (
|
||||
name = "name"
|
||||
url = "url"
|
||||
@@ -259,14 +259,14 @@ func Test_movieQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
id int
|
||||
partial models.MoviePartial
|
||||
want models.Movie
|
||||
partial models.GroupPartial
|
||||
want models.Group
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
"full",
|
||||
movieIDs[movieIdxWithScene],
|
||||
models.MoviePartial{
|
||||
groupIDs[groupIdxWithScene],
|
||||
models.GroupPartial{
|
||||
Name: models.NewOptionalString(name),
|
||||
Director: models.NewOptionalString(director),
|
||||
Synopsis: models.NewOptionalString(synopsis),
|
||||
@@ -278,16 +278,16 @@ func Test_movieQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
Date: models.NewOptionalDate(date),
|
||||
Duration: models.NewOptionalInt(duration),
|
||||
Rating: models.NewOptionalInt(rating),
|
||||
StudioID: models.NewOptionalInt(studioIDs[studioIdxWithMovie]),
|
||||
StudioID: models.NewOptionalInt(studioIDs[studioIdxWithGroup]),
|
||||
CreatedAt: models.NewOptionalTime(createdAt),
|
||||
UpdatedAt: models.NewOptionalTime(updatedAt),
|
||||
TagIDs: &models.UpdateIDs{
|
||||
IDs: []int{tagIDs[tagIdx1WithMovie], tagIDs[tagIdx1WithDupName]},
|
||||
IDs: []int{tagIDs[tagIdx1WithGroup], tagIDs[tagIdx1WithDupName]},
|
||||
Mode: models.RelationshipUpdateModeSet,
|
||||
},
|
||||
},
|
||||
models.Movie{
|
||||
ID: movieIDs[movieIdxWithScene],
|
||||
models.Group{
|
||||
ID: groupIDs[groupIdxWithScene],
|
||||
Name: name,
|
||||
Director: director,
|
||||
Synopsis: synopsis,
|
||||
@@ -296,20 +296,20 @@ func Test_movieQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
Date: &date,
|
||||
Duration: &duration,
|
||||
Rating: &rating,
|
||||
StudioID: &studioIDs[studioIdxWithMovie],
|
||||
StudioID: &studioIDs[studioIdxWithGroup],
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: updatedAt,
|
||||
TagIDs: models.NewRelatedIDs([]int{tagIDs[tagIdx1WithDupName], tagIDs[tagIdx1WithMovie]}),
|
||||
TagIDs: models.NewRelatedIDs([]int{tagIDs[tagIdx1WithDupName], tagIDs[tagIdx1WithGroup]}),
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"clear all",
|
||||
movieIDs[movieIdxWithScene],
|
||||
clearMoviePartial(),
|
||||
models.Movie{
|
||||
ID: movieIDs[movieIdxWithScene],
|
||||
Name: movieNames[movieIdxWithScene],
|
||||
groupIDs[groupIdxWithScene],
|
||||
clearGroupPartial(),
|
||||
models.Group{
|
||||
ID: groupIDs[groupIdxWithScene],
|
||||
Name: groupNames[groupIdxWithScene],
|
||||
TagIDs: models.NewRelatedIDs([]int{}),
|
||||
},
|
||||
false,
|
||||
@@ -317,20 +317,20 @@ func Test_movieQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
{
|
||||
"invalid id",
|
||||
invalidID,
|
||||
models.MoviePartial{},
|
||||
models.Movie{},
|
||||
models.GroupPartial{},
|
||||
models.Group{},
|
||||
true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
qb := db.Movie
|
||||
qb := db.Group
|
||||
|
||||
runWithRollbackTxn(t, tt.name, func(t *testing.T, ctx context.Context) {
|
||||
assert := assert.New(t)
|
||||
|
||||
got, err := qb.UpdatePartial(ctx, tt.id, tt.partial)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("movieQueryBuilder.UpdatePartial() error = %v, wantErr %v", err, tt.wantErr)
|
||||
t.Errorf("groupQueryBuilder.UpdatePartial() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -339,8 +339,8 @@ func Test_movieQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
}
|
||||
|
||||
// load relationships
|
||||
if err := loadMovieRelationships(ctx, tt.want, got); err != nil {
|
||||
t.Errorf("loadMovieRelationships() error = %v", err)
|
||||
if err := loadGroupRelationships(ctx, tt.want, got); err != nil {
|
||||
t.Errorf("loadGroupRelationships() error = %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -348,12 +348,12 @@ func Test_movieQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
|
||||
s, err := qb.Find(ctx, tt.id)
|
||||
if err != nil {
|
||||
t.Errorf("movieQueryBuilder.Find() error = %v", err)
|
||||
t.Errorf("groupQueryBuilder.Find() error = %v", err)
|
||||
}
|
||||
|
||||
// load relationships
|
||||
if err := loadMovieRelationships(ctx, tt.want, s); err != nil {
|
||||
t.Errorf("loadMovieRelationships() error = %v", err)
|
||||
if err := loadGroupRelationships(ctx, tt.want, s); err != nil {
|
||||
t.Errorf("loadGroupRelationships() error = %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -362,65 +362,65 @@ func Test_movieQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMovieFindByName(t *testing.T) {
|
||||
func TestGroupFindByName(t *testing.T) {
|
||||
withTxn(func(ctx context.Context) error {
|
||||
mqb := db.Movie
|
||||
mqb := db.Group
|
||||
|
||||
name := movieNames[movieIdxWithScene] // find a movie by name
|
||||
name := groupNames[groupIdxWithScene] // find a group by name
|
||||
|
||||
movie, err := mqb.FindByName(ctx, name, false)
|
||||
group, err := mqb.FindByName(ctx, name, false)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Error finding movies: %s", err.Error())
|
||||
t.Errorf("Error finding groups: %s", err.Error())
|
||||
}
|
||||
|
||||
assert.Equal(t, movieNames[movieIdxWithScene], movie.Name)
|
||||
assert.Equal(t, groupNames[groupIdxWithScene], group.Name)
|
||||
|
||||
name = movieNames[movieIdxWithDupName] // find a movie by name nocase
|
||||
name = groupNames[groupIdxWithDupName] // find a group by name nocase
|
||||
|
||||
movie, err = mqb.FindByName(ctx, name, true)
|
||||
group, err = mqb.FindByName(ctx, name, true)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Error finding movies: %s", err.Error())
|
||||
t.Errorf("Error finding groups: %s", err.Error())
|
||||
}
|
||||
// movieIdxWithDupName and movieIdxWithScene should have similar names ( only diff should be Name vs NaMe)
|
||||
//movie.Name should match with movieIdxWithScene since its ID is before moveIdxWithDupName
|
||||
assert.Equal(t, movieNames[movieIdxWithScene], movie.Name)
|
||||
//movie.Name should match with movieIdxWithDupName if the check is not case sensitive
|
||||
assert.Equal(t, strings.ToLower(movieNames[movieIdxWithDupName]), strings.ToLower(movie.Name))
|
||||
// groupIdxWithDupName and groupIdxWithScene should have similar names ( only diff should be Name vs NaMe)
|
||||
//group.Name should match with groupIdxWithScene since its ID is before moveIdxWithDupName
|
||||
assert.Equal(t, groupNames[groupIdxWithScene], group.Name)
|
||||
//group.Name should match with groupIdxWithDupName if the check is not case sensitive
|
||||
assert.Equal(t, strings.ToLower(groupNames[groupIdxWithDupName]), strings.ToLower(group.Name))
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func TestMovieFindByNames(t *testing.T) {
|
||||
func TestGroupFindByNames(t *testing.T) {
|
||||
withTxn(func(ctx context.Context) error {
|
||||
var names []string
|
||||
|
||||
mqb := db.Movie
|
||||
mqb := db.Group
|
||||
|
||||
names = append(names, movieNames[movieIdxWithScene]) // find movies by names
|
||||
names = append(names, groupNames[groupIdxWithScene]) // find groups by names
|
||||
|
||||
movies, err := mqb.FindByNames(ctx, names, false)
|
||||
groups, err := mqb.FindByNames(ctx, names, false)
|
||||
if err != nil {
|
||||
t.Errorf("Error finding movies: %s", err.Error())
|
||||
t.Errorf("Error finding groups: %s", err.Error())
|
||||
}
|
||||
assert.Len(t, movies, 1)
|
||||
assert.Equal(t, movieNames[movieIdxWithScene], movies[0].Name)
|
||||
assert.Len(t, groups, 1)
|
||||
assert.Equal(t, groupNames[groupIdxWithScene], groups[0].Name)
|
||||
|
||||
movies, err = mqb.FindByNames(ctx, names, true) // find movies by names nocase
|
||||
groups, err = mqb.FindByNames(ctx, names, true) // find groups by names nocase
|
||||
if err != nil {
|
||||
t.Errorf("Error finding movies: %s", err.Error())
|
||||
t.Errorf("Error finding groups: %s", err.Error())
|
||||
}
|
||||
assert.Len(t, movies, 2) // movieIdxWithScene and movieIdxWithDupName
|
||||
assert.Equal(t, strings.ToLower(movieNames[movieIdxWithScene]), strings.ToLower(movies[0].Name))
|
||||
assert.Equal(t, strings.ToLower(movieNames[movieIdxWithScene]), strings.ToLower(movies[1].Name))
|
||||
assert.Len(t, groups, 2) // groupIdxWithScene and groupIdxWithDupName
|
||||
assert.Equal(t, strings.ToLower(groupNames[groupIdxWithScene]), strings.ToLower(groups[0].Name))
|
||||
assert.Equal(t, strings.ToLower(groupNames[groupIdxWithScene]), strings.ToLower(groups[1].Name))
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func moviesToIDs(i []*models.Movie) []int {
|
||||
func groupsToIDs(i []*models.Group) []int {
|
||||
ret := make([]int, len(i))
|
||||
for i, v := range i {
|
||||
ret[i] = v.ID
|
||||
@@ -429,7 +429,7 @@ func moviesToIDs(i []*models.Movie) []int {
|
||||
return ret
|
||||
}
|
||||
|
||||
func TestMovieQuery(t *testing.T) {
|
||||
func TestGroupQuery(t *testing.T) {
|
||||
var (
|
||||
frontImage = "front_image"
|
||||
backImage = "back_image"
|
||||
@@ -438,7 +438,7 @@ func TestMovieQuery(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
findFilter *models.FindFilterType
|
||||
filter *models.MovieFilterType
|
||||
filter *models.GroupFilterType
|
||||
includeIdxs []int
|
||||
excludeIdxs []int
|
||||
wantErr bool
|
||||
@@ -446,7 +446,7 @@ func TestMovieQuery(t *testing.T) {
|
||||
{
|
||||
"is missing front image",
|
||||
nil,
|
||||
&models.MovieFilterType{
|
||||
&models.GroupFilterType{
|
||||
IsMissing: &frontImage,
|
||||
},
|
||||
// just ensure that it doesn't error
|
||||
@@ -457,7 +457,7 @@ func TestMovieQuery(t *testing.T) {
|
||||
{
|
||||
"is missing back image",
|
||||
nil,
|
||||
&models.MovieFilterType{
|
||||
&models.GroupFilterType{
|
||||
IsMissing: &backImage,
|
||||
},
|
||||
// just ensure that it doesn't error
|
||||
@@ -471,13 +471,13 @@ func TestMovieQuery(t *testing.T) {
|
||||
runWithRollbackTxn(t, tt.name, func(t *testing.T, ctx context.Context) {
|
||||
assert := assert.New(t)
|
||||
|
||||
results, _, err := db.Movie.Query(ctx, tt.filter, tt.findFilter)
|
||||
results, _, err := db.Group.Query(ctx, tt.filter, tt.findFilter)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("MovieQueryBuilder.Query() error = %v, wantErr %v", err, tt.wantErr)
|
||||
t.Errorf("GroupQueryBuilder.Query() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
ids := moviesToIDs(results)
|
||||
ids := groupsToIDs(results)
|
||||
include := indexesToIDs(performerIDs, tt.includeIdxs)
|
||||
exclude := indexesToIDs(performerIDs, tt.excludeIdxs)
|
||||
|
||||
@@ -491,66 +491,66 @@ func TestMovieQuery(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMovieQueryStudio(t *testing.T) {
|
||||
func TestGroupQueryStudio(t *testing.T) {
|
||||
withTxn(func(ctx context.Context) error {
|
||||
mqb := db.Movie
|
||||
mqb := db.Group
|
||||
studioCriterion := models.HierarchicalMultiCriterionInput{
|
||||
Value: []string{
|
||||
strconv.Itoa(studioIDs[studioIdxWithMovie]),
|
||||
strconv.Itoa(studioIDs[studioIdxWithGroup]),
|
||||
},
|
||||
Modifier: models.CriterionModifierIncludes,
|
||||
}
|
||||
|
||||
movieFilter := models.MovieFilterType{
|
||||
groupFilter := models.GroupFilterType{
|
||||
Studios: &studioCriterion,
|
||||
}
|
||||
|
||||
movies, _, err := mqb.Query(ctx, &movieFilter, nil)
|
||||
groups, _, err := mqb.Query(ctx, &groupFilter, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Error querying movie: %s", err.Error())
|
||||
t.Errorf("Error querying group: %s", err.Error())
|
||||
}
|
||||
|
||||
assert.Len(t, movies, 1)
|
||||
assert.Len(t, groups, 1)
|
||||
|
||||
// ensure id is correct
|
||||
assert.Equal(t, movieIDs[movieIdxWithStudio], movies[0].ID)
|
||||
assert.Equal(t, groupIDs[groupIdxWithStudio], groups[0].ID)
|
||||
|
||||
studioCriterion = models.HierarchicalMultiCriterionInput{
|
||||
Value: []string{
|
||||
strconv.Itoa(studioIDs[studioIdxWithMovie]),
|
||||
strconv.Itoa(studioIDs[studioIdxWithGroup]),
|
||||
},
|
||||
Modifier: models.CriterionModifierExcludes,
|
||||
}
|
||||
|
||||
q := getMovieStringValue(movieIdxWithStudio, titleField)
|
||||
q := getGroupStringValue(groupIdxWithStudio, titleField)
|
||||
findFilter := models.FindFilterType{
|
||||
Q: &q,
|
||||
}
|
||||
|
||||
movies, _, err = mqb.Query(ctx, &movieFilter, &findFilter)
|
||||
groups, _, err = mqb.Query(ctx, &groupFilter, &findFilter)
|
||||
if err != nil {
|
||||
t.Errorf("Error querying movie: %s", err.Error())
|
||||
t.Errorf("Error querying group: %s", err.Error())
|
||||
}
|
||||
assert.Len(t, movies, 0)
|
||||
assert.Len(t, groups, 0)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func TestMovieQueryURL(t *testing.T) {
|
||||
func TestGroupQueryURL(t *testing.T) {
|
||||
const sceneIdx = 1
|
||||
movieURL := getMovieStringValue(sceneIdx, urlField)
|
||||
groupURL := getGroupStringValue(sceneIdx, urlField)
|
||||
|
||||
urlCriterion := models.StringCriterionInput{
|
||||
Value: movieURL,
|
||||
Value: groupURL,
|
||||
Modifier: models.CriterionModifierEquals,
|
||||
}
|
||||
|
||||
filter := models.MovieFilterType{
|
||||
filter := models.GroupFilterType{
|
||||
URL: &urlCriterion,
|
||||
}
|
||||
|
||||
verifyFn := func(n *models.Movie) {
|
||||
verifyFn := func(n *models.Group) {
|
||||
t.Helper()
|
||||
|
||||
urls := n.URLs.List()
|
||||
@@ -562,93 +562,93 @@ func TestMovieQueryURL(t *testing.T) {
|
||||
verifyString(t, url, urlCriterion)
|
||||
}
|
||||
|
||||
verifyMovieQuery(t, filter, verifyFn)
|
||||
verifyGroupQuery(t, filter, verifyFn)
|
||||
|
||||
urlCriterion.Modifier = models.CriterionModifierNotEquals
|
||||
verifyMovieQuery(t, filter, verifyFn)
|
||||
verifyGroupQuery(t, filter, verifyFn)
|
||||
|
||||
urlCriterion.Modifier = models.CriterionModifierMatchesRegex
|
||||
urlCriterion.Value = "movie_.*1_URL"
|
||||
verifyMovieQuery(t, filter, verifyFn)
|
||||
urlCriterion.Value = "group_.*1_URL"
|
||||
verifyGroupQuery(t, filter, verifyFn)
|
||||
|
||||
urlCriterion.Modifier = models.CriterionModifierNotMatchesRegex
|
||||
verifyMovieQuery(t, filter, verifyFn)
|
||||
verifyGroupQuery(t, filter, verifyFn)
|
||||
|
||||
urlCriterion.Modifier = models.CriterionModifierIsNull
|
||||
urlCriterion.Value = ""
|
||||
verifyMovieQuery(t, filter, verifyFn)
|
||||
verifyGroupQuery(t, filter, verifyFn)
|
||||
|
||||
urlCriterion.Modifier = models.CriterionModifierNotNull
|
||||
verifyMovieQuery(t, filter, verifyFn)
|
||||
verifyGroupQuery(t, filter, verifyFn)
|
||||
}
|
||||
|
||||
func TestMovieQueryURLExcludes(t *testing.T) {
|
||||
func TestGroupQueryURLExcludes(t *testing.T) {
|
||||
withRollbackTxn(func(ctx context.Context) error {
|
||||
mqb := db.Movie
|
||||
mqb := db.Group
|
||||
|
||||
// create movie with two URLs
|
||||
movie := models.Movie{
|
||||
Name: "TestMovieQueryURLExcludes",
|
||||
// create group with two URLs
|
||||
group := models.Group{
|
||||
Name: "TestGroupQueryURLExcludes",
|
||||
URLs: models.NewRelatedStrings([]string{
|
||||
"aaa",
|
||||
"bbb",
|
||||
}),
|
||||
}
|
||||
|
||||
err := mqb.Create(ctx, &movie)
|
||||
err := mqb.Create(ctx, &group)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating movie: %w", err)
|
||||
return fmt.Errorf("Error creating group: %w", err)
|
||||
}
|
||||
|
||||
// query for movies that exclude the URL "aaa"
|
||||
// query for groups that exclude the URL "aaa"
|
||||
urlCriterion := models.StringCriterionInput{
|
||||
Value: "aaa",
|
||||
Modifier: models.CriterionModifierExcludes,
|
||||
}
|
||||
|
||||
nameCriterion := models.StringCriterionInput{
|
||||
Value: movie.Name,
|
||||
Value: group.Name,
|
||||
Modifier: models.CriterionModifierEquals,
|
||||
}
|
||||
|
||||
filter := models.MovieFilterType{
|
||||
filter := models.GroupFilterType{
|
||||
URL: &urlCriterion,
|
||||
Name: &nameCriterion,
|
||||
}
|
||||
|
||||
movies := queryMovies(ctx, t, &filter, nil)
|
||||
assert.Len(t, movies, 0, "Expected no movies to be found")
|
||||
groups := queryGroups(ctx, t, &filter, nil)
|
||||
assert.Len(t, groups, 0, "Expected no groups to be found")
|
||||
|
||||
// query for movies that exclude the URL "ccc"
|
||||
// query for groups that exclude the URL "ccc"
|
||||
urlCriterion.Value = "ccc"
|
||||
movies = queryMovies(ctx, t, &filter, nil)
|
||||
groups = queryGroups(ctx, t, &filter, nil)
|
||||
|
||||
if assert.Len(t, movies, 1, "Expected one movie to be found") {
|
||||
assert.Equal(t, movie.Name, movies[0].Name)
|
||||
if assert.Len(t, groups, 1, "Expected one group to be found") {
|
||||
assert.Equal(t, group.Name, groups[0].Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func verifyMovieQuery(t *testing.T, filter models.MovieFilterType, verifyFn func(s *models.Movie)) {
|
||||
func verifyGroupQuery(t *testing.T, filter models.GroupFilterType, verifyFn func(s *models.Group)) {
|
||||
withTxn(func(ctx context.Context) error {
|
||||
t.Helper()
|
||||
sqb := db.Movie
|
||||
sqb := db.Group
|
||||
|
||||
movies := queryMovies(ctx, t, &filter, nil)
|
||||
groups := queryGroups(ctx, t, &filter, nil)
|
||||
|
||||
for _, movie := range movies {
|
||||
if err := movie.LoadURLs(ctx, sqb); err != nil {
|
||||
t.Errorf("Error loading movie relationships: %v", err)
|
||||
for _, group := range groups {
|
||||
if err := group.LoadURLs(ctx, sqb); err != nil {
|
||||
t.Errorf("Error loading group relationships: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// assume it should find at least one
|
||||
assert.Greater(t, len(movies), 0)
|
||||
assert.Greater(t, len(groups), 0)
|
||||
|
||||
for _, m := range movies {
|
||||
for _, m := range groups {
|
||||
verifyFn(m)
|
||||
}
|
||||
|
||||
@@ -656,102 +656,102 @@ func verifyMovieQuery(t *testing.T, filter models.MovieFilterType, verifyFn func
|
||||
})
|
||||
}
|
||||
|
||||
func queryMovies(ctx context.Context, t *testing.T, movieFilter *models.MovieFilterType, findFilter *models.FindFilterType) []*models.Movie {
|
||||
sqb := db.Movie
|
||||
movies, _, err := sqb.Query(ctx, movieFilter, findFilter)
|
||||
func queryGroups(ctx context.Context, t *testing.T, groupFilter *models.GroupFilterType, findFilter *models.FindFilterType) []*models.Group {
|
||||
sqb := db.Group
|
||||
groups, _, err := sqb.Query(ctx, groupFilter, findFilter)
|
||||
if err != nil {
|
||||
t.Errorf("Error querying movie: %s", err.Error())
|
||||
t.Errorf("Error querying group: %s", err.Error())
|
||||
}
|
||||
|
||||
return movies
|
||||
return groups
|
||||
}
|
||||
|
||||
func TestMovieQueryTags(t *testing.T) {
|
||||
func TestGroupQueryTags(t *testing.T) {
|
||||
withTxn(func(ctx context.Context) error {
|
||||
tagCriterion := models.HierarchicalMultiCriterionInput{
|
||||
Value: []string{
|
||||
strconv.Itoa(tagIDs[tagIdxWithMovie]),
|
||||
strconv.Itoa(tagIDs[tagIdx1WithMovie]),
|
||||
strconv.Itoa(tagIDs[tagIdxWithGroup]),
|
||||
strconv.Itoa(tagIDs[tagIdx1WithGroup]),
|
||||
},
|
||||
Modifier: models.CriterionModifierIncludes,
|
||||
}
|
||||
|
||||
movieFilter := models.MovieFilterType{
|
||||
groupFilter := models.GroupFilterType{
|
||||
Tags: &tagCriterion,
|
||||
}
|
||||
|
||||
// ensure ids are correct
|
||||
movies := queryMovies(ctx, t, &movieFilter, nil)
|
||||
assert.Len(t, movies, 3)
|
||||
for _, movie := range movies {
|
||||
assert.True(t, movie.ID == movieIDs[movieIdxWithTag] || movie.ID == movieIDs[movieIdxWithTwoTags] || movie.ID == movieIDs[movieIdxWithThreeTags])
|
||||
groups := queryGroups(ctx, t, &groupFilter, nil)
|
||||
assert.Len(t, groups, 3)
|
||||
for _, group := range groups {
|
||||
assert.True(t, group.ID == groupIDs[groupIdxWithTag] || group.ID == groupIDs[groupIdxWithTwoTags] || group.ID == groupIDs[groupIdxWithThreeTags])
|
||||
}
|
||||
|
||||
tagCriterion = models.HierarchicalMultiCriterionInput{
|
||||
Value: []string{
|
||||
strconv.Itoa(tagIDs[tagIdx1WithMovie]),
|
||||
strconv.Itoa(tagIDs[tagIdx2WithMovie]),
|
||||
strconv.Itoa(tagIDs[tagIdx1WithGroup]),
|
||||
strconv.Itoa(tagIDs[tagIdx2WithGroup]),
|
||||
},
|
||||
Modifier: models.CriterionModifierIncludesAll,
|
||||
}
|
||||
|
||||
movies = queryMovies(ctx, t, &movieFilter, nil)
|
||||
groups = queryGroups(ctx, t, &groupFilter, nil)
|
||||
|
||||
if assert.Len(t, movies, 2) {
|
||||
assert.Equal(t, sceneIDs[movieIdxWithTwoTags], movies[0].ID)
|
||||
assert.Equal(t, sceneIDs[movieIdxWithThreeTags], movies[1].ID)
|
||||
if assert.Len(t, groups, 2) {
|
||||
assert.Equal(t, sceneIDs[groupIdxWithTwoTags], groups[0].ID)
|
||||
assert.Equal(t, sceneIDs[groupIdxWithThreeTags], groups[1].ID)
|
||||
}
|
||||
|
||||
tagCriterion = models.HierarchicalMultiCriterionInput{
|
||||
Value: []string{
|
||||
strconv.Itoa(tagIDs[tagIdx1WithMovie]),
|
||||
strconv.Itoa(tagIDs[tagIdx1WithGroup]),
|
||||
},
|
||||
Modifier: models.CriterionModifierExcludes,
|
||||
}
|
||||
|
||||
q := getSceneStringValue(movieIdxWithTwoTags, titleField)
|
||||
q := getSceneStringValue(groupIdxWithTwoTags, titleField)
|
||||
findFilter := models.FindFilterType{
|
||||
Q: &q,
|
||||
}
|
||||
|
||||
movies = queryMovies(ctx, t, &movieFilter, &findFilter)
|
||||
assert.Len(t, movies, 0)
|
||||
groups = queryGroups(ctx, t, &groupFilter, &findFilter)
|
||||
assert.Len(t, groups, 0)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func TestMovieQueryTagCount(t *testing.T) {
|
||||
func TestGroupQueryTagCount(t *testing.T) {
|
||||
const tagCount = 1
|
||||
tagCountCriterion := models.IntCriterionInput{
|
||||
Value: tagCount,
|
||||
Modifier: models.CriterionModifierEquals,
|
||||
}
|
||||
|
||||
verifyMoviesTagCount(t, tagCountCriterion)
|
||||
verifyGroupsTagCount(t, tagCountCriterion)
|
||||
|
||||
tagCountCriterion.Modifier = models.CriterionModifierNotEquals
|
||||
verifyMoviesTagCount(t, tagCountCriterion)
|
||||
verifyGroupsTagCount(t, tagCountCriterion)
|
||||
|
||||
tagCountCriterion.Modifier = models.CriterionModifierGreaterThan
|
||||
verifyMoviesTagCount(t, tagCountCriterion)
|
||||
verifyGroupsTagCount(t, tagCountCriterion)
|
||||
|
||||
tagCountCriterion.Modifier = models.CriterionModifierLessThan
|
||||
verifyMoviesTagCount(t, tagCountCriterion)
|
||||
verifyGroupsTagCount(t, tagCountCriterion)
|
||||
}
|
||||
|
||||
func verifyMoviesTagCount(t *testing.T, tagCountCriterion models.IntCriterionInput) {
|
||||
func verifyGroupsTagCount(t *testing.T, tagCountCriterion models.IntCriterionInput) {
|
||||
withTxn(func(ctx context.Context) error {
|
||||
sqb := db.Movie
|
||||
movieFilter := models.MovieFilterType{
|
||||
sqb := db.Group
|
||||
groupFilter := models.GroupFilterType{
|
||||
TagCount: &tagCountCriterion,
|
||||
}
|
||||
|
||||
movies := queryMovies(ctx, t, &movieFilter, nil)
|
||||
assert.Greater(t, len(movies), 0)
|
||||
groups := queryGroups(ctx, t, &groupFilter, nil)
|
||||
assert.Greater(t, len(groups), 0)
|
||||
|
||||
for _, movie := range movies {
|
||||
ids, err := sqb.GetTagIDs(ctx, movie.ID)
|
||||
for _, group := range groups {
|
||||
ids, err := sqb.GetTagIDs(ctx, group.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -762,7 +762,7 @@ func verifyMoviesTagCount(t *testing.T, tagCountCriterion models.IntCriterionInp
|
||||
})
|
||||
}
|
||||
|
||||
func TestMovieQuerySorting(t *testing.T) {
|
||||
func TestGroupQuerySorting(t *testing.T) {
|
||||
sort := "scenes_count"
|
||||
direction := models.SortDirectionEnumDesc
|
||||
findFilter := models.FindFilterType{
|
||||
@@ -771,60 +771,60 @@ func TestMovieQuerySorting(t *testing.T) {
|
||||
}
|
||||
|
||||
withTxn(func(ctx context.Context) error {
|
||||
movies := queryMovies(ctx, t, nil, &findFilter)
|
||||
groups := queryGroups(ctx, t, nil, &findFilter)
|
||||
|
||||
// scenes should be in same order as indexes
|
||||
firstMovie := movies[0]
|
||||
firstGroup := groups[0]
|
||||
|
||||
assert.Equal(t, movieIDs[movieIdxWithScene], firstMovie.ID)
|
||||
assert.Equal(t, groupIDs[groupIdxWithScene], firstGroup.ID)
|
||||
|
||||
// sort in descending order
|
||||
direction = models.SortDirectionEnumAsc
|
||||
|
||||
movies = queryMovies(ctx, t, nil, &findFilter)
|
||||
lastMovie := movies[len(movies)-1]
|
||||
groups = queryGroups(ctx, t, nil, &findFilter)
|
||||
lastGroup := groups[len(groups)-1]
|
||||
|
||||
assert.Equal(t, movieIDs[movieIdxWithScene], lastMovie.ID)
|
||||
assert.Equal(t, groupIDs[groupIdxWithScene], lastGroup.ID)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func TestMovieUpdateFrontImage(t *testing.T) {
|
||||
func TestGroupUpdateFrontImage(t *testing.T) {
|
||||
if err := withRollbackTxn(func(ctx context.Context) error {
|
||||
qb := db.Movie
|
||||
qb := db.Group
|
||||
|
||||
// create movie to test against
|
||||
const name = "TestMovieUpdateMovieImages"
|
||||
movie := models.Movie{
|
||||
// create group to test against
|
||||
const name = "TestGroupUpdateGroupImages"
|
||||
group := models.Group{
|
||||
Name: name,
|
||||
}
|
||||
err := qb.Create(ctx, &movie)
|
||||
err := qb.Create(ctx, &group)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating movie: %s", err.Error())
|
||||
return fmt.Errorf("Error creating group: %s", err.Error())
|
||||
}
|
||||
|
||||
return testUpdateImage(t, ctx, movie.ID, qb.UpdateFrontImage, qb.GetFrontImage)
|
||||
return testUpdateImage(t, ctx, group.ID, qb.UpdateFrontImage, qb.GetFrontImage)
|
||||
}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestMovieUpdateBackImage(t *testing.T) {
|
||||
func TestGroupUpdateBackImage(t *testing.T) {
|
||||
if err := withRollbackTxn(func(ctx context.Context) error {
|
||||
qb := db.Movie
|
||||
qb := db.Group
|
||||
|
||||
// create movie to test against
|
||||
const name = "TestMovieUpdateMovieImages"
|
||||
movie := models.Movie{
|
||||
// create group to test against
|
||||
const name = "TestGroupUpdateGroupImages"
|
||||
group := models.Group{
|
||||
Name: name,
|
||||
}
|
||||
err := qb.Create(ctx, &movie)
|
||||
err := qb.Create(ctx, &group)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating movie: %s", err.Error())
|
||||
return fmt.Errorf("Error creating group: %s", err.Error())
|
||||
}
|
||||
|
||||
return testUpdateImage(t, ctx, movie.ID, qb.UpdateBackImage, qb.GetBackImage)
|
||||
return testUpdateImage(t, ctx, group.ID, qb.UpdateBackImage, qb.GetBackImage)
|
||||
}); err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ const (
|
||||
performersScenesTable = "performers_scenes"
|
||||
scenesTagsTable = "scenes_tags"
|
||||
scenesGalleriesTable = "scenes_galleries"
|
||||
moviesScenesTable = "movies_scenes"
|
||||
groupsScenesTable = "movies_scenes"
|
||||
scenesURLsTable = "scene_urls"
|
||||
sceneURLColumn = "url"
|
||||
scenesViewDatesTable = "scenes_view_dates"
|
||||
@@ -173,7 +173,7 @@ type sceneRepositoryType struct {
|
||||
galleries joinRepository
|
||||
tags joinRepository
|
||||
performers joinRepository
|
||||
movies repository
|
||||
groups repository
|
||||
|
||||
files filesRepository
|
||||
|
||||
@@ -209,8 +209,8 @@ var (
|
||||
},
|
||||
fkColumn: performerIDColumn,
|
||||
},
|
||||
movies: repository{
|
||||
tableName: moviesScenesTable,
|
||||
groups: repository{
|
||||
tableName: groupsScenesTable,
|
||||
idColumn: sceneIDColumn,
|
||||
},
|
||||
files: filesRepository{
|
||||
@@ -343,8 +343,8 @@ func (qb *SceneStore) Create(ctx context.Context, newObject *models.Scene, fileI
|
||||
}
|
||||
}
|
||||
|
||||
if newObject.Movies.Loaded() {
|
||||
if err := scenesMoviesTableMgr.insertJoins(ctx, id, newObject.Movies.List()); err != nil {
|
||||
if newObject.Groups.Loaded() {
|
||||
if err := scenesGroupsTableMgr.insertJoins(ctx, id, newObject.Groups.List()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -399,8 +399,8 @@ func (qb *SceneStore) UpdatePartial(ctx context.Context, id int, partial models.
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if partial.MovieIDs != nil {
|
||||
if err := scenesMoviesTableMgr.modifyJoins(ctx, id, partial.MovieIDs.Movies, partial.MovieIDs.Mode); err != nil {
|
||||
if partial.GroupIDs != nil {
|
||||
if err := scenesGroupsTableMgr.modifyJoins(ctx, id, partial.GroupIDs.Groups, partial.GroupIDs.Mode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -451,8 +451,8 @@ func (qb *SceneStore) Update(ctx context.Context, updatedObject *models.Scene) e
|
||||
}
|
||||
}
|
||||
|
||||
if updatedObject.Movies.Loaded() {
|
||||
if err := scenesMoviesTableMgr.replaceJoins(ctx, updatedObject.ID, updatedObject.Movies.List()); err != nil {
|
||||
if updatedObject.Groups.Loaded() {
|
||||
if err := scenesGroupsTableMgr.replaceJoins(ctx, updatedObject.ID, updatedObject.Groups.List()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -778,23 +778,23 @@ func (qb *SceneStore) OCountByPerformerID(ctx context.Context, performerID int)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (qb *SceneStore) FindByMovieID(ctx context.Context, movieID int) ([]*models.Scene, error) {
|
||||
sq := dialect.From(scenesMoviesJoinTable).Select(scenesMoviesJoinTable.Col(sceneIDColumn)).Where(
|
||||
scenesMoviesJoinTable.Col(movieIDColumn).Eq(movieID),
|
||||
func (qb *SceneStore) FindByGroupID(ctx context.Context, groupID int) ([]*models.Scene, error) {
|
||||
sq := dialect.From(scenesGroupsJoinTable).Select(scenesGroupsJoinTable.Col(sceneIDColumn)).Where(
|
||||
scenesGroupsJoinTable.Col(groupIDColumn).Eq(groupID),
|
||||
)
|
||||
ret, err := qb.findBySubquery(ctx, sq)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting scenes for movie %d: %w", movieID, err)
|
||||
return nil, fmt.Errorf("getting scenes for group %d: %w", groupID, err)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (qb *SceneStore) CountByMovieID(ctx context.Context, movieID int) (int, error) {
|
||||
joinTable := scenesMoviesJoinTable
|
||||
func (qb *SceneStore) CountByGroupID(ctx context.Context, groupID int) (int, error) {
|
||||
joinTable := scenesGroupsJoinTable
|
||||
|
||||
q := dialect.Select(goqu.COUNT("*")).From(joinTable).Where(joinTable.Col(movieIDColumn).Eq(movieID))
|
||||
q := dialect.Select(goqu.COUNT("*")).From(joinTable).Where(joinTable.Col(groupIDColumn).Eq(groupID))
|
||||
return count(ctx, q)
|
||||
}
|
||||
|
||||
@@ -1142,8 +1142,8 @@ func (qb *SceneStore) setSceneSort(query *queryBuilder, findFilter *models.FindF
|
||||
direction := findFilter.GetDirection()
|
||||
switch sort {
|
||||
case "movie_scene_number", "group_scene_number":
|
||||
query.join(moviesScenesTable, "", "scenes.id = movies_scenes.scene_id")
|
||||
query.sortAndPagination += getSort("scene_index", direction, moviesScenesTable)
|
||||
query.join(groupsScenesTable, "", "scenes.id = movies_scenes.scene_id")
|
||||
query.sortAndPagination += getSort("scene_index", direction, groupsScenesTable)
|
||||
case "tag_count":
|
||||
query.sortAndPagination += getCountSort(sceneTable, scenesTagsTable, sceneIDColumn, direction)
|
||||
case "performer_count":
|
||||
@@ -1270,11 +1270,11 @@ func (qb *SceneStore) AssignFiles(ctx context.Context, sceneID int, fileIDs []mo
|
||||
return scenesFilesTableMgr.insertJoins(ctx, sceneID, firstPrimary, fileIDs)
|
||||
}
|
||||
|
||||
func (qb *SceneStore) GetMovies(ctx context.Context, id int) (ret []models.MoviesScenes, err error) {
|
||||
ret = []models.MoviesScenes{}
|
||||
func (qb *SceneStore) GetGroups(ctx context.Context, id int) (ret []models.GroupsScenes, err error) {
|
||||
ret = []models.GroupsScenes{}
|
||||
|
||||
if err := sceneRepository.movies.getAll(ctx, id, func(rows *sqlx.Rows) error {
|
||||
var ms moviesScenesRow
|
||||
if err := sceneRepository.groups.getAll(ctx, id, func(rows *sqlx.Rows) error {
|
||||
var ms groupsScenesRow
|
||||
if err := rows.StructScan(&ms); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -195,10 +195,10 @@ func (qb *sceneFilterHandler) criterionHandler() criterionHandler {
|
||||
|
||||
&relatedFilterHandler{
|
||||
relatedIDCol: "movies_scenes.movie_id",
|
||||
relatedRepo: movieRepository.repository,
|
||||
relatedHandler: &movieFilterHandler{sceneFilter.MoviesFilter},
|
||||
relatedRepo: groupRepository.repository,
|
||||
relatedHandler: &groupFilterHandler{sceneFilter.MoviesFilter},
|
||||
joinFn: func(f *filterBuilder) {
|
||||
sceneRepository.movies.innerJoin(f, "", "scenes.id")
|
||||
sceneRepository.groups.innerJoin(f, "", "scenes.id")
|
||||
},
|
||||
},
|
||||
|
||||
@@ -320,7 +320,7 @@ func (qb *sceneFilterHandler) isMissingCriterionHandler(isMissing *string) crite
|
||||
case "studio":
|
||||
f.addWhere("scenes.studio_id IS NULL")
|
||||
case "movie":
|
||||
sceneRepository.movies.join(f, "movies_join", "scenes.id")
|
||||
sceneRepository.groups.join(f, "movies_join", "scenes.id")
|
||||
f.addWhere("movies_join.scene_id IS NULL")
|
||||
case "performers":
|
||||
sceneRepository.performers.join(f, "performers_join", "scenes.id")
|
||||
@@ -485,10 +485,10 @@ func (qb *sceneFilterHandler) performerAgeCriterionHandler(performerAge *models.
|
||||
|
||||
func (qb *sceneFilterHandler) groupsCriterionHandler(movies *models.MultiCriterionInput) criterionHandlerFunc {
|
||||
addJoinsFunc := func(f *filterBuilder) {
|
||||
sceneRepository.movies.join(f, "", "scenes.id")
|
||||
sceneRepository.groups.join(f, "", "scenes.id")
|
||||
f.addLeftJoin("movies", "", "movies_scenes.movie_id = movies.id")
|
||||
}
|
||||
h := qb.getMultiCriterionHandlerBuilder(movieTable, moviesScenesTable, "movie_id", addJoinsFunc)
|
||||
h := qb.getMultiCriterionHandlerBuilder(groupTable, groupsScenesTable, "movie_id", addJoinsFunc)
|
||||
return h.handler(movies)
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ func loadSceneRelationships(ctx context.Context, expected models.Scene, actual *
|
||||
return err
|
||||
}
|
||||
}
|
||||
if expected.Movies.Loaded() {
|
||||
if err := actual.LoadMovies(ctx, db.Scene); err != nil {
|
||||
if expected.Groups.Loaded() {
|
||||
if err := actual.LoadGroups(ctx, db.Scene); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -120,13 +120,13 @@ func Test_sceneQueryBuilder_Create(t *testing.T) {
|
||||
GalleryIDs: models.NewRelatedIDs([]int{galleryIDs[galleryIdxWithScene]}),
|
||||
TagIDs: models.NewRelatedIDs([]int{tagIDs[tagIdx1WithDupName], tagIDs[tagIdx1WithScene]}),
|
||||
PerformerIDs: models.NewRelatedIDs([]int{performerIDs[performerIdx1WithScene], performerIDs[performerIdx1WithDupName]}),
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithScene],
|
||||
GroupID: groupIDs[groupIdxWithScene],
|
||||
SceneIndex: &sceneIndex,
|
||||
},
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithStudio],
|
||||
GroupID: groupIDs[groupIdxWithStudio],
|
||||
SceneIndex: &sceneIndex2,
|
||||
},
|
||||
}),
|
||||
@@ -165,13 +165,13 @@ func Test_sceneQueryBuilder_Create(t *testing.T) {
|
||||
GalleryIDs: models.NewRelatedIDs([]int{galleryIDs[galleryIdxWithScene]}),
|
||||
TagIDs: models.NewRelatedIDs([]int{tagIDs[tagIdx1WithDupName], tagIDs[tagIdx1WithScene]}),
|
||||
PerformerIDs: models.NewRelatedIDs([]int{performerIDs[performerIdx1WithScene], performerIDs[performerIdx1WithDupName]}),
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithScene],
|
||||
GroupID: groupIDs[groupIdxWithScene],
|
||||
SceneIndex: &sceneIndex,
|
||||
},
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithStudio],
|
||||
GroupID: groupIDs[groupIdxWithStudio],
|
||||
SceneIndex: &sceneIndex2,
|
||||
},
|
||||
}),
|
||||
@@ -219,11 +219,11 @@ func Test_sceneQueryBuilder_Create(t *testing.T) {
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid movie id",
|
||||
"invalid group id",
|
||||
models.Scene{
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{
|
||||
{
|
||||
MovieID: invalidID,
|
||||
GroupID: invalidID,
|
||||
SceneIndex: &sceneIndex,
|
||||
},
|
||||
}),
|
||||
@@ -349,13 +349,13 @@ func Test_sceneQueryBuilder_Update(t *testing.T) {
|
||||
GalleryIDs: models.NewRelatedIDs([]int{galleryIDs[galleryIdxWithScene]}),
|
||||
TagIDs: models.NewRelatedIDs([]int{tagIDs[tagIdx1WithDupName], tagIDs[tagIdx1WithScene]}),
|
||||
PerformerIDs: models.NewRelatedIDs([]int{performerIDs[performerIdx1WithScene], performerIDs[performerIdx1WithDupName]}),
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithScene],
|
||||
GroupID: groupIDs[groupIdxWithScene],
|
||||
SceneIndex: &sceneIndex,
|
||||
},
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithStudio],
|
||||
GroupID: groupIDs[groupIdxWithStudio],
|
||||
SceneIndex: &sceneIndex2,
|
||||
},
|
||||
}),
|
||||
@@ -381,7 +381,7 @@ func Test_sceneQueryBuilder_Update(t *testing.T) {
|
||||
GalleryIDs: models.NewRelatedIDs([]int{}),
|
||||
TagIDs: models.NewRelatedIDs([]int{}),
|
||||
PerformerIDs: models.NewRelatedIDs([]int{}),
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{}),
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{}),
|
||||
StashIDs: models.NewRelatedStashIDs([]models.StashID{}),
|
||||
},
|
||||
false,
|
||||
@@ -411,10 +411,10 @@ func Test_sceneQueryBuilder_Update(t *testing.T) {
|
||||
false,
|
||||
},
|
||||
{
|
||||
"clear movies",
|
||||
"clear groups",
|
||||
&models.Scene{
|
||||
ID: sceneIDs[sceneIdxWithMovie],
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{}),
|
||||
ID: sceneIDs[sceneIdxWithGroup],
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{}),
|
||||
},
|
||||
false,
|
||||
},
|
||||
@@ -451,12 +451,12 @@ func Test_sceneQueryBuilder_Update(t *testing.T) {
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid movie id",
|
||||
"invalid group id",
|
||||
&models.Scene{
|
||||
ID: sceneIDs[sceneIdxWithSpacedName],
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{
|
||||
{
|
||||
MovieID: invalidID,
|
||||
GroupID: invalidID,
|
||||
SceneIndex: &sceneIndex,
|
||||
},
|
||||
}),
|
||||
@@ -573,14 +573,14 @@ func Test_sceneQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
IDs: []int{performerIDs[performerIdx1WithScene], performerIDs[performerIdx1WithDupName]},
|
||||
Mode: models.RelationshipUpdateModeSet,
|
||||
},
|
||||
MovieIDs: &models.UpdateMovieIDs{
|
||||
Movies: []models.MoviesScenes{
|
||||
GroupIDs: &models.UpdateGroupIDs{
|
||||
Groups: []models.GroupsScenes{
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithScene],
|
||||
GroupID: groupIDs[groupIdxWithScene],
|
||||
SceneIndex: &sceneIndex,
|
||||
},
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithStudio],
|
||||
GroupID: groupIDs[groupIdxWithStudio],
|
||||
SceneIndex: &sceneIndex2,
|
||||
},
|
||||
},
|
||||
@@ -621,13 +621,13 @@ func Test_sceneQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
GalleryIDs: models.NewRelatedIDs([]int{galleryIDs[galleryIdxWithScene]}),
|
||||
TagIDs: models.NewRelatedIDs([]int{tagIDs[tagIdx1WithDupName], tagIDs[tagIdx1WithScene]}),
|
||||
PerformerIDs: models.NewRelatedIDs([]int{performerIDs[performerIdx1WithScene], performerIDs[performerIdx1WithDupName]}),
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithScene],
|
||||
GroupID: groupIDs[groupIdxWithScene],
|
||||
SceneIndex: &sceneIndex,
|
||||
},
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithStudio],
|
||||
GroupID: groupIDs[groupIdxWithStudio],
|
||||
SceneIndex: &sceneIndex2,
|
||||
},
|
||||
}),
|
||||
@@ -658,7 +658,7 @@ func Test_sceneQueryBuilder_UpdatePartial(t *testing.T) {
|
||||
GalleryIDs: models.NewRelatedIDs([]int{}),
|
||||
TagIDs: models.NewRelatedIDs([]int{}),
|
||||
PerformerIDs: models.NewRelatedIDs([]int{}),
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{}),
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{}),
|
||||
StashIDs: models.NewRelatedStashIDs([]models.StashID{}),
|
||||
PlayDuration: getScenePlayDuration(sceneIdxWithSpacedName),
|
||||
ResumeTime: getSceneResumeTime(sceneIdxWithSpacedName),
|
||||
@@ -727,13 +727,13 @@ func Test_sceneQueryBuilder_UpdatePartialRelationships(t *testing.T) {
|
||||
stashID1 = "stashid1"
|
||||
stashID2 = "stashid2"
|
||||
|
||||
movieScenes = []models.MoviesScenes{
|
||||
groupScenes = []models.GroupsScenes{
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithDupName],
|
||||
GroupID: groupIDs[groupIdxWithDupName],
|
||||
SceneIndex: &sceneIndex,
|
||||
},
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithStudio],
|
||||
GroupID: groupIDs[groupIdxWithStudio],
|
||||
SceneIndex: &sceneIndex2,
|
||||
},
|
||||
}
|
||||
@@ -863,40 +863,40 @@ func Test_sceneQueryBuilder_UpdatePartialRelationships(t *testing.T) {
|
||||
false,
|
||||
},
|
||||
{
|
||||
"add movies",
|
||||
sceneIDs[sceneIdxWithMovie],
|
||||
"add groups",
|
||||
sceneIDs[sceneIdxWithGroup],
|
||||
models.ScenePartial{
|
||||
MovieIDs: &models.UpdateMovieIDs{
|
||||
Movies: movieScenes,
|
||||
GroupIDs: &models.UpdateGroupIDs{
|
||||
Groups: groupScenes,
|
||||
Mode: models.RelationshipUpdateModeAdd,
|
||||
},
|
||||
},
|
||||
models.Scene{
|
||||
Movies: models.NewRelatedMovies(append([]models.MoviesScenes{
|
||||
Groups: models.NewRelatedGroups(append([]models.GroupsScenes{
|
||||
{
|
||||
MovieID: indexesToIDs(movieIDs, sceneMovies[sceneIdxWithMovie])[0],
|
||||
GroupID: indexesToIDs(groupIDs, sceneGroups[sceneIdxWithGroup])[0],
|
||||
},
|
||||
}, movieScenes...)),
|
||||
}, groupScenes...)),
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"add movies to empty",
|
||||
"add groups to empty",
|
||||
sceneIDs[sceneIdx1WithPerformer],
|
||||
models.ScenePartial{
|
||||
MovieIDs: &models.UpdateMovieIDs{
|
||||
Movies: movieScenes,
|
||||
GroupIDs: &models.UpdateGroupIDs{
|
||||
Groups: groupScenes,
|
||||
Mode: models.RelationshipUpdateModeAdd,
|
||||
},
|
||||
},
|
||||
models.Scene{
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithDupName],
|
||||
GroupID: groupIDs[groupIdxWithDupName],
|
||||
SceneIndex: &sceneIndex,
|
||||
},
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithStudio],
|
||||
GroupID: groupIDs[groupIdxWithStudio],
|
||||
SceneIndex: &sceneIndex2,
|
||||
},
|
||||
}),
|
||||
@@ -967,27 +967,27 @@ func Test_sceneQueryBuilder_UpdatePartialRelationships(t *testing.T) {
|
||||
false,
|
||||
},
|
||||
{
|
||||
"add duplicate movies",
|
||||
sceneIDs[sceneIdxWithMovie],
|
||||
"add duplicate groups",
|
||||
sceneIDs[sceneIdxWithGroup],
|
||||
models.ScenePartial{
|
||||
MovieIDs: &models.UpdateMovieIDs{
|
||||
Movies: append([]models.MoviesScenes{
|
||||
GroupIDs: &models.UpdateGroupIDs{
|
||||
Groups: append([]models.GroupsScenes{
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithScene],
|
||||
GroupID: groupIDs[groupIdxWithScene],
|
||||
SceneIndex: &sceneIndex,
|
||||
},
|
||||
},
|
||||
movieScenes...,
|
||||
groupScenes...,
|
||||
),
|
||||
Mode: models.RelationshipUpdateModeAdd,
|
||||
},
|
||||
},
|
||||
models.Scene{
|
||||
Movies: models.NewRelatedMovies(append([]models.MoviesScenes{
|
||||
Groups: models.NewRelatedGroups(append([]models.GroupsScenes{
|
||||
{
|
||||
MovieID: indexesToIDs(movieIDs, sceneMovies[sceneIdxWithMovie])[0],
|
||||
GroupID: indexesToIDs(groupIDs, sceneGroups[sceneIdxWithGroup])[0],
|
||||
},
|
||||
}, movieScenes...)),
|
||||
}, groupScenes...)),
|
||||
},
|
||||
false,
|
||||
},
|
||||
@@ -1044,13 +1044,13 @@ func Test_sceneQueryBuilder_UpdatePartialRelationships(t *testing.T) {
|
||||
true,
|
||||
},
|
||||
{
|
||||
"add invalid movies",
|
||||
sceneIDs[sceneIdxWithMovie],
|
||||
"add invalid groups",
|
||||
sceneIDs[sceneIdxWithGroup],
|
||||
models.ScenePartial{
|
||||
MovieIDs: &models.UpdateMovieIDs{
|
||||
Movies: []models.MoviesScenes{
|
||||
GroupIDs: &models.UpdateGroupIDs{
|
||||
Groups: []models.GroupsScenes{
|
||||
{
|
||||
MovieID: invalidID,
|
||||
GroupID: invalidID,
|
||||
},
|
||||
},
|
||||
Mode: models.RelationshipUpdateModeAdd,
|
||||
@@ -1102,20 +1102,20 @@ func Test_sceneQueryBuilder_UpdatePartialRelationships(t *testing.T) {
|
||||
false,
|
||||
},
|
||||
{
|
||||
"remove movies",
|
||||
sceneIDs[sceneIdxWithMovie],
|
||||
"remove groups",
|
||||
sceneIDs[sceneIdxWithGroup],
|
||||
models.ScenePartial{
|
||||
MovieIDs: &models.UpdateMovieIDs{
|
||||
Movies: []models.MoviesScenes{
|
||||
GroupIDs: &models.UpdateGroupIDs{
|
||||
Groups: []models.GroupsScenes{
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithScene],
|
||||
GroupID: groupIDs[groupIdxWithScene],
|
||||
},
|
||||
},
|
||||
Mode: models.RelationshipUpdateModeRemove,
|
||||
},
|
||||
},
|
||||
models.Scene{
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{}),
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{}),
|
||||
},
|
||||
false,
|
||||
},
|
||||
@@ -1176,22 +1176,22 @@ func Test_sceneQueryBuilder_UpdatePartialRelationships(t *testing.T) {
|
||||
false,
|
||||
},
|
||||
{
|
||||
"remove unrelated movies",
|
||||
sceneIDs[sceneIdxWithMovie],
|
||||
"remove unrelated groups",
|
||||
sceneIDs[sceneIdxWithGroup],
|
||||
models.ScenePartial{
|
||||
MovieIDs: &models.UpdateMovieIDs{
|
||||
Movies: []models.MoviesScenes{
|
||||
GroupIDs: &models.UpdateGroupIDs{
|
||||
Groups: []models.GroupsScenes{
|
||||
{
|
||||
MovieID: movieIDs[movieIdxWithDupName],
|
||||
GroupID: groupIDs[groupIdxWithDupName],
|
||||
},
|
||||
},
|
||||
Mode: models.RelationshipUpdateModeRemove,
|
||||
},
|
||||
},
|
||||
models.Scene{
|
||||
Movies: models.NewRelatedMovies([]models.MoviesScenes{
|
||||
Groups: models.NewRelatedGroups([]models.GroupsScenes{
|
||||
{
|
||||
MovieID: indexesToIDs(movieIDs, sceneMovies[sceneIdxWithMovie])[0],
|
||||
GroupID: indexesToIDs(groupIDs, sceneGroups[sceneIdxWithGroup])[0],
|
||||
},
|
||||
}),
|
||||
},
|
||||
@@ -1257,9 +1257,9 @@ func Test_sceneQueryBuilder_UpdatePartialRelationships(t *testing.T) {
|
||||
assert.ElementsMatch(tt.want.GalleryIDs.List(), got.GalleryIDs.List())
|
||||
assert.ElementsMatch(tt.want.GalleryIDs.List(), s.GalleryIDs.List())
|
||||
}
|
||||
if tt.partial.MovieIDs != nil {
|
||||
assert.ElementsMatch(tt.want.Movies.List(), got.Movies.List())
|
||||
assert.ElementsMatch(tt.want.Movies.List(), s.Movies.List())
|
||||
if tt.partial.GroupIDs != nil {
|
||||
assert.ElementsMatch(tt.want.Groups.List(), got.Groups.List())
|
||||
assert.ElementsMatch(tt.want.Groups.List(), s.Groups.List())
|
||||
}
|
||||
if tt.partial.StashIDs != nil {
|
||||
assert.ElementsMatch(tt.want.StashIDs.List(), got.StashIDs.List())
|
||||
@@ -1467,9 +1467,9 @@ func Test_sceneQueryBuilder_Find(t *testing.T) {
|
||||
false,
|
||||
},
|
||||
{
|
||||
"with movies",
|
||||
sceneIDs[sceneIdxWithMovie],
|
||||
makeSceneWithID(sceneIdxWithMovie),
|
||||
"with groups",
|
||||
sceneIDs[sceneIdxWithGroup],
|
||||
makeSceneWithID(sceneIdxWithGroup),
|
||||
false,
|
||||
},
|
||||
}
|
||||
@@ -1527,13 +1527,13 @@ func Test_sceneQueryBuilder_FindMany(t *testing.T) {
|
||||
sceneIDs[sceneIdxWithGallery],
|
||||
sceneIDs[sceneIdxWithTwoPerformers],
|
||||
sceneIDs[sceneIdxWithTwoTags],
|
||||
sceneIDs[sceneIdxWithMovie],
|
||||
sceneIDs[sceneIdxWithGroup],
|
||||
},
|
||||
[]*models.Scene{
|
||||
makeSceneWithID(sceneIdxWithGallery),
|
||||
makeSceneWithID(sceneIdxWithTwoPerformers),
|
||||
makeSceneWithID(sceneIdxWithTwoTags),
|
||||
makeSceneWithID(sceneIdxWithMovie),
|
||||
makeSceneWithID(sceneIdxWithGroup),
|
||||
},
|
||||
false,
|
||||
},
|
||||
@@ -1608,9 +1608,9 @@ func Test_sceneQueryBuilder_FindByChecksum(t *testing.T) {
|
||||
false,
|
||||
},
|
||||
{
|
||||
"with movies",
|
||||
getChecksum(sceneIdxWithMovie),
|
||||
[]*models.Scene{makeSceneWithID(sceneIdxWithMovie)},
|
||||
"with groups",
|
||||
getChecksum(sceneIdxWithGroup),
|
||||
[]*models.Scene{makeSceneWithID(sceneIdxWithGroup)},
|
||||
false,
|
||||
},
|
||||
}
|
||||
@@ -1678,9 +1678,9 @@ func Test_sceneQueryBuilder_FindByOSHash(t *testing.T) {
|
||||
false,
|
||||
},
|
||||
{
|
||||
"with movies",
|
||||
getOSHash(sceneIdxWithMovie),
|
||||
[]*models.Scene{makeSceneWithID(sceneIdxWithMovie)},
|
||||
"with groups",
|
||||
getOSHash(sceneIdxWithGroup),
|
||||
[]*models.Scene{makeSceneWithID(sceneIdxWithGroup)},
|
||||
false,
|
||||
},
|
||||
}
|
||||
@@ -1749,9 +1749,9 @@ func Test_sceneQueryBuilder_FindByPath(t *testing.T) {
|
||||
false,
|
||||
},
|
||||
{
|
||||
"with movies",
|
||||
getPath(sceneIdxWithMovie),
|
||||
[]*models.Scene{makeSceneWithID(sceneIdxWithMovie)},
|
||||
"with groups",
|
||||
getPath(sceneIdxWithGroup),
|
||||
[]*models.Scene{makeSceneWithID(sceneIdxWithGroup)},
|
||||
false,
|
||||
},
|
||||
}
|
||||
@@ -2107,7 +2107,7 @@ func TestSceneQuery(t *testing.T) {
|
||||
},
|
||||
},
|
||||
[]int{sceneIdxWithGallery},
|
||||
[]int{sceneIdxWithMovie},
|
||||
[]int{sceneIdxWithGroup},
|
||||
false,
|
||||
},
|
||||
{
|
||||
@@ -2120,7 +2120,7 @@ func TestSceneQuery(t *testing.T) {
|
||||
},
|
||||
},
|
||||
[]int{sceneIdxWithGallery},
|
||||
[]int{sceneIdxWithMovie},
|
||||
[]int{sceneIdxWithGroup},
|
||||
false,
|
||||
},
|
||||
// {
|
||||
@@ -2133,7 +2133,7 @@ func TestSceneQuery(t *testing.T) {
|
||||
// },
|
||||
// },
|
||||
// []int{sceneIdxWithGallery},
|
||||
// []int{sceneIdxWithMovie},
|
||||
// []int{sceneIdxWithGroup},
|
||||
// false,
|
||||
// },
|
||||
{
|
||||
@@ -3108,7 +3108,7 @@ func TestSceneQueryIsMissingMovies(t *testing.T) {
|
||||
IsMissing: &isMissing,
|
||||
}
|
||||
|
||||
q := getSceneStringValue(sceneIdxWithMovie, titleField)
|
||||
q := getSceneStringValue(sceneIdxWithGroup, titleField)
|
||||
findFilter := models.FindFilterType{
|
||||
Q: &q,
|
||||
}
|
||||
@@ -3122,7 +3122,7 @@ func TestSceneQueryIsMissingMovies(t *testing.T) {
|
||||
|
||||
// ensure non of the ids equal the one with movies
|
||||
for _, scene := range scenes {
|
||||
assert.NotEqual(t, sceneIDs[sceneIdxWithMovie], scene.ID)
|
||||
assert.NotEqual(t, sceneIDs[sceneIdxWithGroup], scene.ID)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -3878,7 +3878,7 @@ func TestSceneQueryMovies(t *testing.T) {
|
||||
sqb := db.Scene
|
||||
movieCriterion := models.MultiCriterionInput{
|
||||
Value: []string{
|
||||
strconv.Itoa(movieIDs[movieIdxWithScene]),
|
||||
strconv.Itoa(groupIDs[groupIdxWithScene]),
|
||||
},
|
||||
Modifier: models.CriterionModifierIncludes,
|
||||
}
|
||||
@@ -3892,16 +3892,16 @@ func TestSceneQueryMovies(t *testing.T) {
|
||||
assert.Len(t, scenes, 1)
|
||||
|
||||
// ensure id is correct
|
||||
assert.Equal(t, sceneIDs[sceneIdxWithMovie], scenes[0].ID)
|
||||
assert.Equal(t, sceneIDs[sceneIdxWithGroup], scenes[0].ID)
|
||||
|
||||
movieCriterion = models.MultiCriterionInput{
|
||||
Value: []string{
|
||||
strconv.Itoa(movieIDs[movieIdxWithScene]),
|
||||
strconv.Itoa(groupIDs[groupIdxWithScene]),
|
||||
},
|
||||
Modifier: models.CriterionModifierExcludes,
|
||||
}
|
||||
|
||||
q := getSceneStringValue(sceneIdxWithMovie, titleField)
|
||||
q := getSceneStringValue(sceneIdxWithGroup, titleField)
|
||||
findFilter := models.FindFilterType{
|
||||
Q: &q,
|
||||
}
|
||||
@@ -4212,22 +4212,22 @@ func TestSceneCountByTagID(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestSceneCountByMovieID(t *testing.T) {
|
||||
func TestSceneCountByGroupID(t *testing.T) {
|
||||
withTxn(func(ctx context.Context) error {
|
||||
sqb := db.Scene
|
||||
|
||||
sceneCount, err := sqb.CountByMovieID(ctx, movieIDs[movieIdxWithScene])
|
||||
sceneCount, err := sqb.CountByGroupID(ctx, groupIDs[groupIdxWithScene])
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("error calling CountByMovieID: %s", err.Error())
|
||||
t.Errorf("error calling CountByGroupID: %s", err.Error())
|
||||
}
|
||||
|
||||
assert.Equal(t, 1, sceneCount)
|
||||
|
||||
sceneCount, err = sqb.CountByMovieID(ctx, 0)
|
||||
sceneCount, err = sqb.CountByGroupID(ctx, 0)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("error calling CountByMovieID: %s", err.Error())
|
||||
t.Errorf("error calling CountByGroupID: %s", err.Error())
|
||||
}
|
||||
|
||||
assert.Equal(t, 0, sceneCount)
|
||||
@@ -4264,16 +4264,16 @@ func TestFindByMovieID(t *testing.T) {
|
||||
withTxn(func(ctx context.Context) error {
|
||||
sqb := db.Scene
|
||||
|
||||
scenes, err := sqb.FindByMovieID(ctx, movieIDs[movieIdxWithScene])
|
||||
scenes, err := sqb.FindByGroupID(ctx, groupIDs[groupIdxWithScene])
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("error calling FindByMovieID: %s", err.Error())
|
||||
}
|
||||
|
||||
assert.Len(t, scenes, 1)
|
||||
assert.Equal(t, sceneIDs[sceneIdxWithMovie], scenes[0].ID)
|
||||
assert.Equal(t, sceneIDs[sceneIdxWithGroup], scenes[0].ID)
|
||||
|
||||
scenes, err = sqb.FindByMovieID(ctx, 0)
|
||||
scenes, err = sqb.FindByGroupID(ctx, 0)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("error calling FindByMovieID: %s", err.Error())
|
||||
|
||||
@@ -54,7 +54,7 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
sceneIdxWithMovie = iota
|
||||
sceneIdxWithGroup = iota
|
||||
sceneIdxWithGallery
|
||||
sceneIdxWithPerformer
|
||||
sceneIdx1WithPerformer
|
||||
@@ -148,17 +148,17 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
movieIdxWithScene = iota
|
||||
movieIdxWithStudio
|
||||
movieIdxWithTag
|
||||
movieIdxWithTwoTags
|
||||
movieIdxWithThreeTags
|
||||
// movies with dup names start from the end
|
||||
// create 7 more basic movies (can remove this if we add more indexes)
|
||||
movieIdxWithDupName = movieIdxWithStudio + 7
|
||||
groupIdxWithScene = iota
|
||||
groupIdxWithStudio
|
||||
groupIdxWithTag
|
||||
groupIdxWithTwoTags
|
||||
groupIdxWithThreeTags
|
||||
// groups with dup names start from the end
|
||||
// create 7 more basic groups (can remove this if we add more indexes)
|
||||
groupIdxWithDupName = groupIdxWithStudio + 7
|
||||
|
||||
moviesNameCase = movieIdxWithDupName
|
||||
moviesNameNoCase = 1
|
||||
groupsNameCase = groupIdxWithDupName
|
||||
groupsNameNoCase = 1
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -220,10 +220,10 @@ const (
|
||||
tagIdxWithParentAndChild
|
||||
tagIdxWithGrandParent
|
||||
tagIdx2WithMarkers
|
||||
tagIdxWithMovie
|
||||
tagIdx1WithMovie
|
||||
tagIdx2WithMovie
|
||||
tagIdx3WithMovie
|
||||
tagIdxWithGroup
|
||||
tagIdx1WithGroup
|
||||
tagIdx2WithGroup
|
||||
tagIdx3WithGroup
|
||||
// new indexes above
|
||||
// tags with dup names start from the end
|
||||
tagIdx1WithDupName
|
||||
@@ -238,7 +238,7 @@ const (
|
||||
const (
|
||||
studioIdxWithScene = iota
|
||||
studioIdxWithTwoScenes
|
||||
studioIdxWithMovie
|
||||
studioIdxWithGroup
|
||||
studioIdxWithChildStudio
|
||||
studioIdxWithParentStudio
|
||||
studioIdxWithImage
|
||||
@@ -305,7 +305,7 @@ var (
|
||||
sceneIDs []int
|
||||
imageIDs []int
|
||||
performerIDs []int
|
||||
movieIDs []int
|
||||
groupIDs []int
|
||||
galleryIDs []int
|
||||
tagIDs []int
|
||||
studioIDs []int
|
||||
@@ -316,7 +316,7 @@ var (
|
||||
|
||||
tagNames []string
|
||||
studioNames []string
|
||||
movieNames []string
|
||||
groupNames []string
|
||||
performerNames []string
|
||||
)
|
||||
|
||||
@@ -389,8 +389,8 @@ var (
|
||||
sceneIdxWithGallery: {galleryIdxWithScene},
|
||||
}
|
||||
|
||||
sceneMovies = linkMap{
|
||||
sceneIdxWithMovie: {movieIdxWithScene},
|
||||
sceneGroups = linkMap{
|
||||
sceneIdxWithGroup: {groupIdxWithScene},
|
||||
}
|
||||
|
||||
sceneStudios = map[int]int{
|
||||
@@ -496,14 +496,14 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
movieStudioLinks = [][2]int{
|
||||
{movieIdxWithStudio, studioIdxWithMovie},
|
||||
groupStudioLinks = [][2]int{
|
||||
{groupIdxWithStudio, studioIdxWithGroup},
|
||||
}
|
||||
|
||||
movieTags = linkMap{
|
||||
movieIdxWithTag: {tagIdxWithMovie},
|
||||
movieIdxWithTwoTags: {tagIdx1WithMovie, tagIdx2WithMovie},
|
||||
movieIdxWithThreeTags: {tagIdx1WithMovie, tagIdx2WithMovie, tagIdx3WithMovie},
|
||||
groupTags = linkMap{
|
||||
groupIdxWithTag: {tagIdxWithGroup},
|
||||
groupIdxWithTwoTags: {tagIdx1WithGroup, tagIdx2WithGroup},
|
||||
groupIdxWithThreeTags: {tagIdx1WithGroup, tagIdx2WithGroup, tagIdx3WithGroup},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -653,8 +653,8 @@ func populateDB() error {
|
||||
return fmt.Errorf("error creating tags: %s", err.Error())
|
||||
}
|
||||
|
||||
if err := createMovies(ctx, db.Movie, moviesNameCase, moviesNameNoCase); err != nil {
|
||||
return fmt.Errorf("error creating movies: %s", err.Error())
|
||||
if err := createGroups(ctx, db.Group, groupsNameCase, groupsNameNoCase); err != nil {
|
||||
return fmt.Errorf("error creating groups: %s", err.Error())
|
||||
}
|
||||
|
||||
if err := createPerformers(ctx, performersNameCase, performersNameNoCase); err != nil {
|
||||
@@ -685,8 +685,8 @@ func populateDB() error {
|
||||
return fmt.Errorf("error creating saved filters: %s", err.Error())
|
||||
}
|
||||
|
||||
if err := linkMovieStudios(ctx, db.Movie); err != nil {
|
||||
return fmt.Errorf("error linking movie studios: %s", err.Error())
|
||||
if err := linkGroupStudios(ctx, db.Group); err != nil {
|
||||
return fmt.Errorf("error linking group studios: %s", err.Error())
|
||||
}
|
||||
|
||||
if err := linkStudiosParent(ctx); err != nil {
|
||||
@@ -1069,12 +1069,12 @@ func makeScene(i int) *models.Scene {
|
||||
pids := indexesToIDs(performerIDs, scenePerformers[i])
|
||||
tids := indexesToIDs(tagIDs, sceneTags[i])
|
||||
|
||||
mids := indexesToIDs(movieIDs, sceneMovies[i])
|
||||
mids := indexesToIDs(groupIDs, sceneGroups[i])
|
||||
|
||||
movies := make([]models.MoviesScenes, len(mids))
|
||||
groups := make([]models.GroupsScenes, len(mids))
|
||||
for i, m := range mids {
|
||||
movies[i] = models.MoviesScenes{
|
||||
MovieID: m,
|
||||
groups[i] = models.GroupsScenes{
|
||||
GroupID: m,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1092,7 +1092,7 @@ func makeScene(i int) *models.Scene {
|
||||
GalleryIDs: models.NewRelatedIDs(gids),
|
||||
PerformerIDs: models.NewRelatedIDs(pids),
|
||||
TagIDs: models.NewRelatedIDs(tids),
|
||||
Movies: models.NewRelatedMovies(movies),
|
||||
Groups: models.NewRelatedGroups(groups),
|
||||
StashIDs: models.NewRelatedStashIDs([]models.StashID{
|
||||
sceneStashID(i),
|
||||
}),
|
||||
@@ -1320,18 +1320,18 @@ func createGalleries(ctx context.Context, n int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getMovieStringValue(index int, field string) string {
|
||||
return getPrefixedStringValue("movie", index, field)
|
||||
func getGroupStringValue(index int, field string) string {
|
||||
return getPrefixedStringValue("group", index, field)
|
||||
}
|
||||
|
||||
func getMovieNullStringValue(index int, field string) string {
|
||||
ret := getPrefixedNullStringValue("movie", index, field)
|
||||
func getGroupNullStringValue(index int, field string) string {
|
||||
ret := getPrefixedNullStringValue("group", index, field)
|
||||
|
||||
return ret.String
|
||||
}
|
||||
|
||||
func getMovieEmptyString(index int, field string) string {
|
||||
v := getPrefixedNullStringValue("movie", index, field)
|
||||
func getGroupEmptyString(index int, field string) string {
|
||||
v := getPrefixedNullStringValue("group", index, field)
|
||||
if !v.Valid {
|
||||
return ""
|
||||
}
|
||||
@@ -1339,8 +1339,8 @@ func getMovieEmptyString(index int, field string) string {
|
||||
return v.String
|
||||
}
|
||||
|
||||
// createMoviees creates n movies with plain Name and o movies with camel cased NaMe included
|
||||
func createMovies(ctx context.Context, mqb models.MovieReaderWriter, n int, o int) error {
|
||||
// createGroups creates n groups with plain Name and o groups with camel cased NaMe included
|
||||
func createGroups(ctx context.Context, mqb models.GroupReaderWriter, n int, o int) error {
|
||||
const namePlain = "Name"
|
||||
const nameNoCase = "NaMe"
|
||||
|
||||
@@ -1348,31 +1348,31 @@ func createMovies(ctx context.Context, mqb models.MovieReaderWriter, n int, o in
|
||||
index := i
|
||||
name := namePlain
|
||||
|
||||
tids := indexesToIDs(tagIDs, movieTags[i])
|
||||
tids := indexesToIDs(tagIDs, groupTags[i])
|
||||
|
||||
if i >= n { // i<n tags get normal names
|
||||
name = nameNoCase // i>=n movies get dup names if case is not checked
|
||||
name = nameNoCase // i>=n groups get dup names if case is not checked
|
||||
index = n + o - (i + 1) // for the name to be the same the number (index) must be the same also
|
||||
} // so count backwards to 0 as needed
|
||||
// movies [ i ] and [ n + o - i - 1 ] should have similar names with only the Name!=NaMe part different
|
||||
// groups [ i ] and [ n + o - i - 1 ] should have similar names with only the Name!=NaMe part different
|
||||
|
||||
name = getMovieStringValue(index, name)
|
||||
movie := models.Movie{
|
||||
name = getGroupStringValue(index, name)
|
||||
group := models.Group{
|
||||
Name: name,
|
||||
URLs: models.NewRelatedStrings([]string{
|
||||
getMovieEmptyString(i, urlField),
|
||||
getGroupEmptyString(i, urlField),
|
||||
}),
|
||||
TagIDs: models.NewRelatedIDs(tids),
|
||||
}
|
||||
|
||||
err := mqb.Create(ctx, &movie)
|
||||
err := mqb.Create(ctx, &group)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating movie [%d] %v+: %s", i, movie, err.Error())
|
||||
return fmt.Errorf("Error creating group [%d] %v+: %s", i, group, err.Error())
|
||||
}
|
||||
|
||||
movieIDs = append(movieIDs, movie.ID)
|
||||
movieNames = append(movieNames, movie.Name)
|
||||
groupIDs = append(groupIDs, group.ID)
|
||||
groupNames = append(groupNames, group.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1709,7 +1709,7 @@ func createStudios(ctx context.Context, n int, o int) error {
|
||||
TagIDs: models.NewRelatedIDs(tids),
|
||||
}
|
||||
// only add aliases for some scenes
|
||||
if i == studioIdxWithMovie || i%5 == 0 {
|
||||
if i == studioIdxWithGroup || i%5 == 0 {
|
||||
alias := getStudioStringValue(i, "Alias")
|
||||
studio.Aliases = models.NewRelatedStrings([]string{alias})
|
||||
}
|
||||
@@ -1842,12 +1842,12 @@ func doLinks(links [][2]int, fn func(idx1, idx2 int) error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func linkMovieStudios(ctx context.Context, mqb models.MovieWriter) error {
|
||||
return doLinks(movieStudioLinks, func(movieIndex, studioIndex int) error {
|
||||
movie := models.MoviePartial{
|
||||
func linkGroupStudios(ctx context.Context, mqb models.GroupWriter) error {
|
||||
return doLinks(groupStudioLinks, func(groupIndex, studioIndex int) error {
|
||||
group := models.GroupPartial{
|
||||
StudioID: models.NewOptionalInt(studioIDs[studioIndex]),
|
||||
}
|
||||
_, err := mqb.UpdatePartial(ctx, movieIDs[movieIndex], movie)
|
||||
_, err := mqb.UpdatePartial(ctx, groupIDs[groupIndex], group)
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
@@ -216,7 +216,7 @@ func TestStudioQueryForAutoTag(t *testing.T) {
|
||||
withTxn(func(ctx context.Context) error {
|
||||
tqb := db.Studio
|
||||
|
||||
name := studioNames[studioIdxWithMovie] // find a studio by name
|
||||
name := studioNames[studioIdxWithGroup] // find a studio by name
|
||||
|
||||
studios, err := tqb.QueryForAutoTag(ctx, []string{name})
|
||||
|
||||
@@ -225,16 +225,16 @@ func TestStudioQueryForAutoTag(t *testing.T) {
|
||||
}
|
||||
|
||||
assert.Len(t, studios, 1)
|
||||
assert.Equal(t, strings.ToLower(studioNames[studioIdxWithMovie]), strings.ToLower(studios[0].Name))
|
||||
assert.Equal(t, strings.ToLower(studioNames[studioIdxWithGroup]), strings.ToLower(studios[0].Name))
|
||||
|
||||
name = getStudioStringValue(studioIdxWithMovie, "Alias")
|
||||
name = getStudioStringValue(studioIdxWithGroup, "Alias")
|
||||
studios, err = tqb.QueryForAutoTag(ctx, []string{name})
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Error finding studios: %s", err.Error())
|
||||
}
|
||||
if assert.Len(t, studios, 1) {
|
||||
assert.Equal(t, studioIDs[studioIdxWithMovie], studios[0].ID)
|
||||
assert.Equal(t, studioIDs[studioIdxWithGroup], studios[0].ID)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@@ -911,7 +911,7 @@ func TestStudioQueryName(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestStudioQueryAlias(t *testing.T) {
|
||||
const studioIdx = studioIdxWithMovie
|
||||
const studioIdx = studioIdxWithGroup
|
||||
studioName := getStudioStringValue(studioIdx, "Alias")
|
||||
|
||||
aliasCriterion := &models.StringCriterionInput{
|
||||
|
||||
@@ -588,30 +588,30 @@ func (t *orderedValueTable[T]) modifyJoins(ctx context.Context, id int, v []T, m
|
||||
return nil
|
||||
}
|
||||
|
||||
type scenesMoviesTable struct {
|
||||
type scenesGroupsTable struct {
|
||||
table
|
||||
}
|
||||
|
||||
type moviesScenesRow struct {
|
||||
type groupsScenesRow struct {
|
||||
SceneID null.Int `db:"scene_id"`
|
||||
MovieID null.Int `db:"movie_id"`
|
||||
GroupID null.Int `db:"movie_id"`
|
||||
SceneIndex null.Int `db:"scene_index"`
|
||||
}
|
||||
|
||||
func (r moviesScenesRow) resolve(sceneID int) models.MoviesScenes {
|
||||
return models.MoviesScenes{
|
||||
MovieID: int(r.MovieID.Int64),
|
||||
func (r groupsScenesRow) resolve(sceneID int) models.GroupsScenes {
|
||||
return models.GroupsScenes{
|
||||
GroupID: int(r.GroupID.Int64),
|
||||
SceneIndex: nullIntPtr(r.SceneIndex),
|
||||
}
|
||||
}
|
||||
|
||||
func (t *scenesMoviesTable) get(ctx context.Context, id int) ([]models.MoviesScenes, error) {
|
||||
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))
|
||||
|
||||
const single = false
|
||||
var ret []models.MoviesScenes
|
||||
var ret []models.GroupsScenes
|
||||
if err := queryFunc(ctx, q, single, func(rows *sqlx.Rows) error {
|
||||
var v moviesScenesRow
|
||||
var v groupsScenesRow
|
||||
if err := rows.StructScan(&v); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -620,15 +620,15 @@ func (t *scenesMoviesTable) get(ctx context.Context, id int) ([]models.MoviesSce
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("getting scene movies from %s: %w", t.table.table.GetTable(), err)
|
||||
return nil, fmt.Errorf("getting scene groups from %s: %w", t.table.table.GetTable(), err)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (t *scenesMoviesTable) insertJoin(ctx context.Context, id int, v models.MoviesScenes) (sql.Result, error) {
|
||||
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(
|
||||
goqu.Vals{id, v.MovieID, intFromPtr(v.SceneIndex)},
|
||||
goqu.Vals{id, v.GroupID, intFromPtr(v.SceneIndex)},
|
||||
)
|
||||
ret, err := exec(ctx, q)
|
||||
if err != nil {
|
||||
@@ -638,7 +638,7 @@ func (t *scenesMoviesTable) insertJoin(ctx context.Context, id int, v models.Mov
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (t *scenesMoviesTable) insertJoins(ctx context.Context, id int, v []models.MoviesScenes) error {
|
||||
func (t *scenesGroupsTable) insertJoins(ctx context.Context, id int, v []models.GroupsScenes) error {
|
||||
for _, fk := range v {
|
||||
if _, err := t.insertJoin(ctx, id, fk); err != nil {
|
||||
return err
|
||||
@@ -648,7 +648,7 @@ func (t *scenesMoviesTable) insertJoins(ctx context.Context, id int, v []models.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *scenesMoviesTable) replaceJoins(ctx context.Context, id int, v []models.MoviesScenes) error {
|
||||
func (t *scenesGroupsTable) replaceJoins(ctx context.Context, id int, v []models.GroupsScenes) error {
|
||||
if err := t.destroy(ctx, []int{id}); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -656,7 +656,7 @@ func (t *scenesMoviesTable) replaceJoins(ctx context.Context, id int, v []models
|
||||
return t.insertJoins(ctx, id, v)
|
||||
}
|
||||
|
||||
func (t *scenesMoviesTable) addJoins(ctx context.Context, id int, v []models.MoviesScenes) error {
|
||||
func (t *scenesGroupsTable) addJoins(ctx context.Context, id int, v []models.GroupsScenes) error {
|
||||
// get existing foreign keys
|
||||
fks, err := t.get(ctx, id)
|
||||
if err != nil {
|
||||
@@ -664,12 +664,12 @@ func (t *scenesMoviesTable) addJoins(ctx context.Context, id int, v []models.Mov
|
||||
}
|
||||
|
||||
// only add values that are not already present
|
||||
var filtered []models.MoviesScenes
|
||||
var filtered []models.GroupsScenes
|
||||
for _, vv := range v {
|
||||
found := false
|
||||
|
||||
for _, e := range fks {
|
||||
if vv.MovieID == e.MovieID {
|
||||
if vv.GroupID == e.GroupID {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
@@ -682,11 +682,11 @@ func (t *scenesMoviesTable) addJoins(ctx context.Context, id int, v []models.Mov
|
||||
return t.insertJoins(ctx, id, filtered)
|
||||
}
|
||||
|
||||
func (t *scenesMoviesTable) destroyJoins(ctx context.Context, id int, v []models.MoviesScenes) error {
|
||||
func (t *scenesGroupsTable) destroyJoins(ctx context.Context, id int, v []models.GroupsScenes) error {
|
||||
for _, vv := range v {
|
||||
q := dialect.Delete(t.table.table).Where(
|
||||
t.idColumn.Eq(id),
|
||||
t.table.table.Col("movie_id").Eq(vv.MovieID),
|
||||
t.table.table.Col("movie_id").Eq(vv.GroupID),
|
||||
)
|
||||
|
||||
if _, err := exec(ctx, q); err != nil {
|
||||
@@ -697,7 +697,7 @@ func (t *scenesMoviesTable) destroyJoins(ctx context.Context, id int, v []models
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *scenesMoviesTable) modifyJoins(ctx context.Context, id int, v []models.MoviesScenes, mode models.RelationshipUpdateMode) error {
|
||||
func (t *scenesGroupsTable) modifyJoins(ctx context.Context, id int, v []models.GroupsScenes, mode models.RelationshipUpdateMode) error {
|
||||
switch mode {
|
||||
case models.RelationshipUpdateModeSet:
|
||||
return t.replaceJoins(ctx, id, v)
|
||||
|
||||
@@ -25,7 +25,7 @@ var (
|
||||
scenesTagsJoinTable = goqu.T(scenesTagsTable)
|
||||
scenesPerformersJoinTable = goqu.T(performersScenesTable)
|
||||
scenesStashIDsJoinTable = goqu.T("scene_stash_ids")
|
||||
scenesMoviesJoinTable = goqu.T(moviesScenesTable)
|
||||
scenesGroupsJoinTable = goqu.T(groupsScenesTable)
|
||||
scenesURLsJoinTable = goqu.T(scenesURLsTable)
|
||||
|
||||
performersAliasesJoinTable = goqu.T(performersAliasesTable)
|
||||
@@ -37,8 +37,8 @@ var (
|
||||
studiosTagsJoinTable = goqu.T(studiosTagsTable)
|
||||
studiosStashIDsJoinTable = goqu.T("studio_stash_ids")
|
||||
|
||||
moviesURLsJoinTable = goqu.T(movieURLsTable)
|
||||
moviesTagsJoinTable = goqu.T(moviesTagsTable)
|
||||
groupsURLsJoinTable = goqu.T(groupURLsTable)
|
||||
groupsTagsJoinTable = goqu.T(groupsTagsTable)
|
||||
|
||||
tagsAliasesJoinTable = goqu.T(tagAliasesTable)
|
||||
tagRelationsJoinTable = goqu.T(tagRelationsTable)
|
||||
@@ -184,10 +184,10 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
scenesMoviesTableMgr = &scenesMoviesTable{
|
||||
scenesGroupsTableMgr = &scenesGroupsTable{
|
||||
table: table{
|
||||
table: scenesMoviesJoinTable,
|
||||
idColumn: scenesMoviesJoinTable.Col(sceneIDColumn),
|
||||
table: scenesGroupsJoinTable,
|
||||
idColumn: scenesGroupsJoinTable.Col(sceneIDColumn),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -337,25 +337,25 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
movieTableMgr = &table{
|
||||
table: goqu.T(movieTable),
|
||||
idColumn: goqu.T(movieTable).Col(idColumn),
|
||||
groupTableMgr = &table{
|
||||
table: goqu.T(groupTable),
|
||||
idColumn: goqu.T(groupTable).Col(idColumn),
|
||||
}
|
||||
|
||||
moviesURLsTableMgr = &orderedValueTable[string]{
|
||||
groupsURLsTableMgr = &orderedValueTable[string]{
|
||||
table: table{
|
||||
table: moviesURLsJoinTable,
|
||||
idColumn: moviesURLsJoinTable.Col(movieIDColumn),
|
||||
table: groupsURLsJoinTable,
|
||||
idColumn: groupsURLsJoinTable.Col(groupIDColumn),
|
||||
},
|
||||
valueColumn: moviesURLsJoinTable.Col(movieURLColumn),
|
||||
valueColumn: groupsURLsJoinTable.Col(groupURLColumn),
|
||||
}
|
||||
|
||||
moviesTagsTableMgr = &joinTable{
|
||||
groupsTagsTableMgr = &joinTable{
|
||||
table: table{
|
||||
table: moviesTagsJoinTable,
|
||||
idColumn: moviesTagsJoinTable.Col(movieIDColumn),
|
||||
table: groupsTagsJoinTable,
|
||||
idColumn: groupsTagsJoinTable.Col(groupIDColumn),
|
||||
},
|
||||
fkColumn: moviesTagsJoinTable.Col(tagIDColumn),
|
||||
fkColumn: groupsTagsJoinTable.Col(tagIDColumn),
|
||||
foreignTable: tagTableMgr,
|
||||
orderBy: tagTableMgr.table.Col("name").Asc(),
|
||||
}
|
||||
|
||||
@@ -424,7 +424,7 @@ func (qb *TagStore) FindByGalleryID(ctx context.Context, galleryID int) ([]*mode
|
||||
return qb.queryTags(ctx, query, args)
|
||||
}
|
||||
|
||||
func (qb *TagStore) FindByMovieID(ctx context.Context, movieID int) ([]*models.Tag, error) {
|
||||
func (qb *TagStore) FindByGroupID(ctx context.Context, movieID int) ([]*models.Tag, error) {
|
||||
query := `
|
||||
SELECT tags.* FROM tags
|
||||
LEFT JOIN movies_tags as movies_join on movies_join.tag_id = tags.id
|
||||
@@ -637,6 +637,7 @@ func (qb *TagStore) Query(ctx context.Context, tagFilter *models.TagFilterType,
|
||||
var tagSortOptions = sortOptions{
|
||||
"created_at",
|
||||
"galleries_count",
|
||||
"groups_count",
|
||||
"id",
|
||||
"images_count",
|
||||
"movies_count",
|
||||
@@ -684,7 +685,7 @@ func (qb *TagStore) getTagSort(query *queryBuilder, findFilter *models.FindFilte
|
||||
case "studios_count":
|
||||
sortQuery += getCountSort(tagTable, studiosTagsTable, tagIDColumn, direction)
|
||||
case "movies_count", "groups_count":
|
||||
sortQuery += getCountSort(tagTable, moviesTagsTable, tagIDColumn, direction)
|
||||
sortQuery += getCountSort(tagTable, groupsTagsTable, tagIDColumn, direction)
|
||||
default:
|
||||
sortQuery += getSort(sort, direction, "tags")
|
||||
}
|
||||
|
||||
@@ -190,11 +190,11 @@ func (qb *tagFilterHandler) studioCountCriterionHandler(studioCount *models.IntC
|
||||
}
|
||||
}
|
||||
|
||||
func (qb *tagFilterHandler) groupCountCriterionHandler(movieCount *models.IntCriterionInput) criterionHandlerFunc {
|
||||
func (qb *tagFilterHandler) groupCountCriterionHandler(groupCount *models.IntCriterionInput) criterionHandlerFunc {
|
||||
return func(ctx context.Context, f *filterBuilder) {
|
||||
if movieCount != nil {
|
||||
if groupCount != nil {
|
||||
f.addLeftJoin("movies_tags", "", "movies_tags.tag_id = tags.id")
|
||||
clause, args := getIntCriterionWhereClause("count(distinct movies_tags.movie_id)", *movieCount)
|
||||
clause, args := getIntCriterionWhereClause("count(distinct movies_tags.movie_id)", *groupCount)
|
||||
|
||||
f.addHaving(clause, args...)
|
||||
}
|
||||
|
||||
@@ -42,22 +42,22 @@ func TestMarkerFindBySceneMarkerID(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestTagFindByMovieID(t *testing.T) {
|
||||
func TestTagFindByGroupID(t *testing.T) {
|
||||
withTxn(func(ctx context.Context) error {
|
||||
tqb := db.Tag
|
||||
|
||||
movieID := movieIDs[movieIdxWithTag]
|
||||
groupID := groupIDs[groupIdxWithTag]
|
||||
|
||||
tags, err := tqb.FindByMovieID(ctx, movieID)
|
||||
tags, err := tqb.FindByGroupID(ctx, groupID)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Error finding tags: %s", err.Error())
|
||||
}
|
||||
|
||||
assert.Len(t, tags, 1)
|
||||
assert.Equal(t, tagIDs[tagIdxWithMovie], tags[0].ID)
|
||||
assert.Equal(t, tagIDs[tagIdxWithGroup], tags[0].ID)
|
||||
|
||||
tags, err = tqb.FindByMovieID(ctx, 0)
|
||||
tags, err = tqb.FindByGroupID(ctx, 0)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Error finding tags: %s", err.Error())
|
||||
@@ -236,7 +236,7 @@ func TestTagQuerySort(t *testing.T) {
|
||||
|
||||
sortBy = "movies_count"
|
||||
tags = queryTags(ctx, t, sqb, nil, findFilter)
|
||||
assert.Equal(tagIDs[tagIdx1WithMovie], tags[0].ID)
|
||||
assert.Equal(tagIDs[tagIdx1WithGroup], tags[0].ID)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -132,7 +132,7 @@ func (db *Database) Repository() models.Repository {
|
||||
Gallery: db.Gallery,
|
||||
GalleryChapter: db.GalleryChapter,
|
||||
Image: db.Image,
|
||||
Movie: db.Movie,
|
||||
Group: db.Group,
|
||||
Performer: db.Performer,
|
||||
Scene: db.Scene,
|
||||
SceneMarker: db.SceneMarker,
|
||||
|
||||
Reference in New Issue
Block a user