2021-01-18 01:23:20 +00:00
package sqlite
2019-02-09 12:30:49 +00:00
import (
"database/sql"
2020-09-15 07:28:53 +00:00
"fmt"
2019-11-07 04:36:48 +00:00
"strconv"
2021-04-26 02:51:31 +00:00
"strings"
2019-08-14 21:40:51 +00:00
2021-01-18 01:23:20 +00:00
"github.com/stashapp/stash/pkg/models"
2019-02-09 12:30:49 +00:00
)
2021-01-18 01:23:20 +00:00
const performerTable = "performers"
const performerIDColumn = "performer_id"
2021-03-10 01:25:51 +00:00
const performersTagsTable = "performers_tags"
2021-05-24 07:45:51 +00:00
const performersImageTable = "performers_image" // performer cover image
2021-03-10 01:25:51 +00:00
var countPerformersForTagQuery = `
SELECT tag_id AS id FROM performers_tags
WHERE performers_tags . tag_id = ?
GROUP BY performers_tags . performer_id
`
2019-02-09 12:30:49 +00:00
2021-01-18 01:23:20 +00:00
type performerQueryBuilder struct {
repository
2019-02-09 12:30:49 +00:00
}
2021-01-18 01:23:20 +00:00
func NewPerformerReaderWriter ( tx dbi ) * performerQueryBuilder {
return & performerQueryBuilder {
repository {
tx : tx ,
tableName : performerTable ,
idColumn : idColumn ,
} ,
2019-02-09 12:30:49 +00:00
}
2021-01-18 01:23:20 +00:00
}
2019-02-09 12:30:49 +00:00
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) Create ( newObject models . Performer ) ( * models . Performer , error ) {
var ret models . Performer
if err := qb . insertObject ( newObject , & ret ) ; err != nil {
2019-02-09 12:30:49 +00:00
return nil , err
}
2021-01-18 01:23:20 +00:00
return & ret , nil
2019-02-09 12:30:49 +00:00
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) Update ( updatedObject models . PerformerPartial ) ( * models . Performer , error ) {
const partial = true
if err := qb . update ( updatedObject . ID , updatedObject , partial ) ; err != nil {
2020-12-04 01:42:56 +00:00
return nil , err
}
2021-01-18 01:23:20 +00:00
var ret models . Performer
if err := qb . get ( updatedObject . ID , & ret ) ; err != nil {
2020-12-04 01:42:56 +00:00
return nil , err
}
2021-01-18 01:23:20 +00:00
2020-12-04 01:42:56 +00:00
return & ret , nil
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) UpdateFull ( updatedObject models . Performer ) ( * models . Performer , error ) {
const partial = false
if err := qb . update ( updatedObject . ID , updatedObject , partial ) ; err != nil {
2019-02-09 12:30:49 +00:00
return nil , err
}
2021-01-18 01:23:20 +00:00
var ret models . Performer
if err := qb . get ( updatedObject . ID , & ret ) ; err != nil {
2019-02-09 12:30:49 +00:00
return nil , err
}
2021-01-18 01:23:20 +00:00
return & ret , nil
2019-02-09 12:30:49 +00:00
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) Destroy ( id int ) error {
// TODO - add on delete cascade to performers_scenes
_ , err := qb . tx . Exec ( "DELETE FROM performers_scenes WHERE performer_id = ?" , id )
2019-08-14 21:40:51 +00:00
if err != nil {
return err
}
2021-01-18 01:23:20 +00:00
return qb . destroyExisting ( [ ] int { id } )
2019-08-14 21:40:51 +00:00
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) Find ( id int ) ( * models . Performer , error ) {
var ret models . Performer
if err := qb . get ( id , & ret ) ; err != nil {
if err == sql . ErrNoRows {
return nil , nil
}
2019-02-09 12:30:49 +00:00
return nil , err
}
2021-01-18 01:23:20 +00:00
return & ret , nil
2019-02-09 12:30:49 +00:00
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) FindMany ( ids [ ] int ) ( [ ] * models . Performer , error ) {
var performers [ ] * models . Performer
2020-09-15 07:28:53 +00:00
for _ , id := range ids {
performer , err := qb . Find ( id )
if err != nil {
return nil , err
}
if performer == nil {
return nil , fmt . Errorf ( "performer with id %d not found" , id )
}
performers = append ( performers , performer )
}
return performers , nil
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) FindBySceneID ( sceneID int ) ( [ ] * models . Performer , error ) {
2020-05-11 05:19:11 +00:00
query := selectAll ( "performers" ) + `
2019-02-09 12:30:49 +00:00
LEFT JOIN performers_scenes as scenes_join on scenes_join . performer_id = performers . id
2020-05-11 05:19:11 +00:00
WHERE scenes_join . scene_id = ?
2019-02-09 12:30:49 +00:00
`
args := [ ] interface { } { sceneID }
2021-01-18 01:23:20 +00:00
return qb . queryPerformers ( query , args )
2019-02-09 12:30:49 +00:00
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) FindByImageID ( imageID int ) ( [ ] * models . Performer , error ) {
2020-10-12 23:12:46 +00:00
query := selectAll ( "performers" ) + `
LEFT JOIN performers_images as images_join on images_join . performer_id = performers . id
WHERE images_join . image_id = ?
`
args := [ ] interface { } { imageID }
2021-01-18 01:23:20 +00:00
return qb . queryPerformers ( query , args )
2020-10-12 23:12:46 +00:00
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) FindByGalleryID ( galleryID int ) ( [ ] * models . Performer , error ) {
2020-10-12 23:12:46 +00:00
query := selectAll ( "performers" ) + `
LEFT JOIN performers_galleries as galleries_join on galleries_join . performer_id = performers . id
WHERE galleries_join . gallery_id = ?
`
args := [ ] interface { } { galleryID }
2021-01-18 01:23:20 +00:00
return qb . queryPerformers ( query , args )
2020-10-12 23:12:46 +00:00
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) FindNamesBySceneID ( sceneID int ) ( [ ] * models . Performer , error ) {
2020-04-24 02:52:21 +00:00
query := `
SELECT performers . name FROM performers
LEFT JOIN performers_scenes as scenes_join on scenes_join . performer_id = performers . id
WHERE scenes_join . scene_id = ?
`
args := [ ] interface { } { sceneID }
2021-01-18 01:23:20 +00:00
return qb . queryPerformers ( query , args )
2020-04-24 02:52:21 +00:00
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) FindByNames ( names [ ] string , nocase bool ) ( [ ] * models . Performer , error ) {
2020-05-24 06:19:22 +00:00
query := "SELECT * FROM performers WHERE name"
if nocase {
query += " COLLATE NOCASE"
}
query += " IN " + getInBinding ( len ( names ) )
2019-02-09 12:30:49 +00:00
var args [ ] interface { }
for _ , name := range names {
args = append ( args , name )
}
2021-01-18 01:23:20 +00:00
return qb . queryPerformers ( query , args )
2019-02-09 12:30:49 +00:00
}
2021-03-10 01:25:51 +00:00
func ( qb * performerQueryBuilder ) CountByTagID ( tagID int ) ( int , error ) {
args := [ ] interface { } { tagID }
return qb . runCountQuery ( qb . buildCountQuery ( countPerformersForTagQuery ) , args )
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) Count ( ) ( int , error ) {
return qb . runCountQuery ( qb . buildCountQuery ( "SELECT performers.id FROM performers" ) , nil )
2019-02-11 20:36:10 +00:00
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) All ( ) ( [ ] * models . Performer , error ) {
return qb . queryPerformers ( selectAll ( "performers" ) + qb . getPerformerSort ( nil ) , nil )
2019-02-09 12:30:49 +00:00
}
2021-04-26 02:51:31 +00:00
func ( qb * performerQueryBuilder ) QueryForAutoTag ( words [ ] string ) ( [ ] * models . Performer , error ) {
// TODO - Query needs to be changed to support queries of this type, and
// this method should be removed
query := selectAll ( performerTable )
var whereClauses [ ] string
var args [ ] interface { }
for _ , w := range words {
whereClauses = append ( whereClauses , "name like ?" )
args = append ( args , "%" + w + "%" )
whereClauses = append ( whereClauses , "aliases like ?" )
args = append ( args , "%" + w + "%" )
}
where := strings . Join ( whereClauses , " OR " )
return qb . queryPerformers ( query + " WHERE " + where , args )
}
2021-05-22 07:07:03 +00:00
func ( qb * performerQueryBuilder ) validateFilter ( filter * models . PerformerFilterType ) error {
const and = "AND"
const or = "OR"
const not = "NOT"
if filter . And != nil {
if filter . Or != nil {
return illegalFilterCombination ( and , or )
}
if filter . Not != nil {
return illegalFilterCombination ( and , not )
}
return qb . validateFilter ( filter . And )
}
if filter . Or != nil {
if filter . Not != nil {
return illegalFilterCombination ( or , not )
}
return qb . validateFilter ( filter . Or )
}
if filter . Not != nil {
return qb . validateFilter ( filter . Not )
}
return nil
}
func ( qb * performerQueryBuilder ) makeFilter ( filter * models . PerformerFilterType ) * filterBuilder {
query := & filterBuilder { }
if filter . And != nil {
query . and ( qb . makeFilter ( filter . And ) )
}
if filter . Or != nil {
query . or ( qb . makeFilter ( filter . Or ) )
}
if filter . Not != nil {
query . not ( qb . makeFilter ( filter . Not ) )
}
const tableName = performerTable
query . handleCriterionFunc ( boolCriterionHandler ( filter . FilterFavorites , tableName + ".favorite" ) )
query . handleCriterionFunc ( yearFilterCriterionHandler ( filter . BirthYear , tableName + ".birthdate" ) )
query . handleCriterionFunc ( yearFilterCriterionHandler ( filter . DeathYear , tableName + ".death_date" ) )
query . handleCriterionFunc ( performerAgeFilterCriterionHandler ( filter . Age ) )
query . handleCriterionFunc ( func ( f * filterBuilder ) {
if gender := filter . Gender ; gender != nil {
f . addWhere ( tableName + ".gender = ?" , gender . Value . String ( ) )
}
} )
query . handleCriterionFunc ( performerIsMissingCriterionHandler ( qb , filter . IsMissing ) )
query . handleCriterionFunc ( stringCriterionHandler ( filter . Ethnicity , tableName + ".ethnicity" ) )
query . handleCriterionFunc ( stringCriterionHandler ( filter . Country , tableName + ".country" ) )
query . handleCriterionFunc ( stringCriterionHandler ( filter . EyeColor , tableName + ".eye_color" ) )
query . handleCriterionFunc ( stringCriterionHandler ( filter . Height , tableName + ".height" ) )
query . handleCriterionFunc ( stringCriterionHandler ( filter . Measurements , tableName + ".measurements" ) )
query . handleCriterionFunc ( stringCriterionHandler ( filter . FakeTits , tableName + ".fake_tits" ) )
query . handleCriterionFunc ( stringCriterionHandler ( filter . CareerLength , tableName + ".career_length" ) )
query . handleCriterionFunc ( stringCriterionHandler ( filter . Tattoos , tableName + ".tattoos" ) )
query . handleCriterionFunc ( stringCriterionHandler ( filter . Piercings , tableName + ".piercings" ) )
query . handleCriterionFunc ( intCriterionHandler ( filter . Rating , tableName + ".rating" ) )
query . handleCriterionFunc ( stringCriterionHandler ( filter . HairColor , tableName + ".hair_color" ) )
query . handleCriterionFunc ( stringCriterionHandler ( filter . URL , tableName + ".url" ) )
query . handleCriterionFunc ( intCriterionHandler ( filter . Weight , tableName + ".weight" ) )
query . handleCriterionFunc ( func ( f * filterBuilder ) {
if filter . StashID != nil {
qb . stashIDRepository ( ) . join ( f , "performer_stash_ids" , "performers.id" )
stringCriterionHandler ( filter . StashID , "performer_stash_ids.stash_id" ) ( f )
}
} )
// TODO - need better handling of aliases
query . handleCriterionFunc ( stringCriterionHandler ( filter . Aliases , tableName + ".aliases" ) )
query . handleCriterionFunc ( performerTagsCriterionHandler ( qb , filter . Tags ) )
query . handleCriterionFunc ( performerStudiosCriterionHandler ( filter . Studios ) )
query . handleCriterionFunc ( performerTagCountCriterionHandler ( qb , filter . TagCount ) )
query . handleCriterionFunc ( performerSceneCountCriterionHandler ( qb , filter . SceneCount ) )
query . handleCriterionFunc ( performerImageCountCriterionHandler ( qb , filter . ImageCount ) )
query . handleCriterionFunc ( performerGalleryCountCriterionHandler ( qb , filter . GalleryCount ) )
return query
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) Query ( performerFilter * models . PerformerFilterType , findFilter * models . FindFilterType ) ( [ ] * models . Performer , int , error ) {
2019-02-09 12:30:49 +00:00
if performerFilter == nil {
2021-01-18 01:23:20 +00:00
performerFilter = & models . PerformerFilterType { }
2019-02-09 12:30:49 +00:00
}
if findFilter == nil {
2021-01-18 01:23:20 +00:00
findFilter = & models . FindFilterType { }
2019-02-09 12:30:49 +00:00
}
2020-03-02 23:30:29 +00:00
tableName := "performers"
2021-01-18 01:23:20 +00:00
query := qb . newQuery ( )
2019-11-07 04:36:48 +00:00
2020-03-02 23:30:29 +00:00
query . body = selectDistinctIDs ( tableName )
2019-02-09 12:30:49 +00:00
if q := findFilter . Q ; q != nil && * q != "" {
2021-03-30 03:04:57 +00:00
searchColumns := [ ] string { "performers.name" , "performers.aliases" }
2019-11-07 04:36:48 +00:00
clause , thisArgs := getSearchBinding ( searchColumns , * q , false )
query . addWhere ( clause )
query . addArg ( thisArgs ... )
2019-02-09 12:30:49 +00:00
}
2021-05-22 07:07:03 +00:00
if err := qb . validateFilter ( performerFilter ) ; err != nil {
return nil , 0 , err
2019-11-07 04:36:48 +00:00
}
2021-05-22 07:07:03 +00:00
filter := qb . makeFilter ( performerFilter )
2019-11-07 04:36:48 +00:00
2021-05-22 07:07:03 +00:00
query . addFilter ( filter )
query . sortAndPagination = qb . getPerformerSort ( findFilter ) + getPagination ( findFilter )
idsResult , countResult , err := query . executeFind ( )
if err != nil {
return nil , 0 , err
2021-04-16 06:06:35 +00:00
}
2021-05-22 07:07:03 +00:00
var performers [ ] * models . Performer
for _ , id := range idsResult {
performer , err := qb . Find ( id )
if err != nil {
return nil , 0 , err
}
performers = append ( performers , performer )
2019-11-07 04:36:48 +00:00
}
2021-05-22 07:07:03 +00:00
return performers , countResult , nil
}
func performerIsMissingCriterionHandler ( qb * performerQueryBuilder , isMissing * string ) criterionHandlerFunc {
return func ( f * filterBuilder ) {
if isMissing != nil && * isMissing != "" {
switch * isMissing {
2021-05-25 00:45:26 +00:00
case "scenes" : // Deprecated: use `scene_count == 0` filter instead
2021-05-22 07:07:03 +00:00
f . addJoin ( performersScenesTable , "scenes_join" , "scenes_join.performer_id = performers.id" )
f . addWhere ( "scenes_join.scene_id IS NULL" )
case "image" :
2021-05-24 07:45:51 +00:00
f . addJoin ( performersImageTable , "image_join" , "image_join.performer_id = performers.id" )
f . addWhere ( "image_join.performer_id IS NULL" )
2021-05-22 07:07:03 +00:00
default :
f . addWhere ( "(performers." + * isMissing + " IS NULL OR TRIM(performers." + * isMissing + ") = '')" )
}
}
2019-02-09 12:30:49 +00:00
}
2021-05-22 07:07:03 +00:00
}
2019-02-09 12:30:49 +00:00
2021-05-22 07:07:03 +00:00
func yearFilterCriterionHandler ( year * models . IntCriterionInput , col string ) criterionHandlerFunc {
return func ( f * filterBuilder ) {
if year != nil && year . Modifier . IsValid ( ) {
yearStr := strconv . Itoa ( year . Value )
startOfYear := yearStr + "-01-01"
endOfYear := yearStr + "-12-31"
switch year . Modifier {
case models . CriterionModifierEquals :
// between yyyy-01-01 and yyyy-12-31
f . addWhere ( col + " >= ?" , startOfYear )
f . addWhere ( col + " <= ?" , endOfYear )
case models . CriterionModifierNotEquals :
// outside of yyyy-01-01 to yyyy-12-31
f . addWhere ( col + " < ? OR " + col + " > ?" , startOfYear , endOfYear )
case models . CriterionModifierGreaterThan :
// > yyyy-12-31
f . addWhere ( col + " > ?" , endOfYear )
case models . CriterionModifierLessThan :
// < yyyy-01-01
f . addWhere ( col + " < ?" , startOfYear )
}
}
2020-03-31 22:36:38 +00:00
}
2021-05-22 07:07:03 +00:00
}
2020-03-31 22:36:38 +00:00
2021-05-22 07:07:03 +00:00
func performerAgeFilterCriterionHandler ( age * models . IntCriterionInput ) criterionHandlerFunc {
return func ( f * filterBuilder ) {
if age != nil && age . Modifier . IsValid ( ) {
var op string
switch age . Modifier {
case models . CriterionModifierEquals :
op = "=="
case models . CriterionModifierNotEquals :
op = "!="
case models . CriterionModifierGreaterThan :
op = ">"
case models . CriterionModifierLessThan :
op = "<"
}
if op != "" {
f . addWhere ( "cast(IFNULL(strftime('%Y.%m%d', performers.death_date), strftime('%Y.%m%d', 'now')) - strftime('%Y.%m%d', performers.birthdate) as int) " + op + " ?" , age . Value )
}
2020-04-08 04:21:05 +00:00
}
}
2021-05-22 07:07:03 +00:00
}
2020-04-08 04:21:05 +00:00
2021-05-22 07:07:03 +00:00
func performerTagsCriterionHandler ( qb * performerQueryBuilder , tags * models . MultiCriterionInput ) criterionHandlerFunc {
h := joinedMultiCriterionHandlerBuilder {
primaryTable : performerTable ,
joinTable : performersTagsTable ,
joinAs : "tags_join" ,
primaryFK : performerIDColumn ,
foreignFK : tagIDColumn ,
2019-11-07 04:36:48 +00:00
2021-05-22 07:07:03 +00:00
addJoinTable : func ( f * filterBuilder ) {
qb . tagsRepository ( ) . join ( f , "tags_join" , "performers.id" )
} ,
}
2019-11-07 04:36:48 +00:00
2021-05-22 07:07:03 +00:00
return h . handler ( tags )
}
2021-03-10 01:25:51 +00:00
2021-05-22 07:07:03 +00:00
func performerTagCountCriterionHandler ( qb * performerQueryBuilder , count * models . IntCriterionInput ) criterionHandlerFunc {
h := countCriterionHandlerBuilder {
primaryTable : performerTable ,
joinTable : performersTagsTable ,
primaryFK : performerIDColumn ,
2021-03-10 01:25:51 +00:00
}
2021-05-22 07:07:03 +00:00
return h . handler ( count )
}
2021-04-09 08:46:00 +00:00
2021-05-22 07:07:03 +00:00
func performerSceneCountCriterionHandler ( qb * performerQueryBuilder , count * models . IntCriterionInput ) criterionHandlerFunc {
h := countCriterionHandlerBuilder {
primaryTable : performerTable ,
joinTable : performersScenesTable ,
primaryFK : performerIDColumn ,
2021-01-18 01:23:20 +00:00
}
2019-02-09 12:30:49 +00:00
2021-05-22 07:07:03 +00:00
return h . handler ( count )
}
func performerImageCountCriterionHandler ( qb * performerQueryBuilder , count * models . IntCriterionInput ) criterionHandlerFunc {
h := countCriterionHandlerBuilder {
primaryTable : performerTable ,
joinTable : performersImagesTable ,
primaryFK : performerIDColumn ,
2019-02-09 12:30:49 +00:00
}
2021-05-22 07:07:03 +00:00
return h . handler ( count )
2019-02-09 12:30:49 +00:00
}
2021-05-22 07:07:03 +00:00
func performerGalleryCountCriterionHandler ( qb * performerQueryBuilder , count * models . IntCriterionInput ) criterionHandlerFunc {
h := countCriterionHandlerBuilder {
primaryTable : performerTable ,
joinTable : performersGalleriesTable ,
primaryFK : performerIDColumn ,
2019-11-07 04:36:48 +00:00
}
2021-05-22 07:07:03 +00:00
return h . handler ( count )
2019-11-07 04:36:48 +00:00
}
2021-05-22 07:07:03 +00:00
func performerStudiosCriterionHandler ( studios * models . MultiCriterionInput ) criterionHandlerFunc {
return func ( f * filterBuilder ) {
if studios != nil {
var countCondition string
var clauseJoin string
if studios . Modifier == models . CriterionModifierIncludes {
// return performers who appear in scenes/images/galleries with any of the given studios
countCondition = " > 0"
clauseJoin = " OR "
} else if studios . Modifier == models . CriterionModifierExcludes {
// exclude performers who appear in scenes/images/galleries with any of the given studios
countCondition = " = 0"
clauseJoin = " AND "
} else {
return
}
templStr := "(SELECT COUNT(DISTINCT %[1]s.id) FROM %[1]s LEFT JOIN %[2]s ON %[1]s.id = %[2]s.%[3]s WHERE %[2]s.performer_id = performers.id AND %[1]s.studio_id IN %[4]s)" + countCondition
inBinding := getInBinding ( len ( studios . Value ) )
clauses := [ ] string {
fmt . Sprintf ( templStr , sceneTable , performersScenesTable , sceneIDColumn , inBinding ) ,
fmt . Sprintf ( templStr , imageTable , performersImagesTable , imageIDColumn , inBinding ) ,
fmt . Sprintf ( templStr , galleryTable , performersGalleriesTable , galleryIDColumn , inBinding ) ,
}
var args [ ] interface { }
for _ , tagID := range studios . Value {
args = append ( args , tagID )
}
// this is a bit gross. We need the args three times
combinedArgs := append ( args , append ( args , args ... ) ... )
f . addWhere ( fmt . Sprintf ( "(%s)" , strings . Join ( clauses , clauseJoin ) ) , combinedArgs ... )
2019-11-07 04:36:48 +00:00
}
}
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) getPerformerSort ( findFilter * models . FindFilterType ) string {
2019-02-09 12:30:49 +00:00
var sort string
var direction string
if findFilter == nil {
sort = "name"
direction = "ASC"
} else {
sort = findFilter . GetSort ( "name" )
direction = findFilter . GetDirection ( )
}
2021-04-09 08:46:00 +00:00
if sort == "tag_count" {
return getCountSort ( performerTable , performersTagsTable , performerIDColumn , direction )
}
2021-05-24 07:45:51 +00:00
if sort == "scenes_count" {
return getCountSort ( performerTable , performersScenesTable , performerIDColumn , direction )
}
2021-04-09 08:46:00 +00:00
2019-02-09 12:30:49 +00:00
return getSort ( sort , direction , "performers" )
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) queryPerformers ( query string , args [ ] interface { } ) ( [ ] * models . Performer , error ) {
var ret models . Performers
if err := qb . query ( query , args , & ret ) ; err != nil {
2019-02-09 12:30:49 +00:00
return nil , err
}
2021-01-18 01:23:20 +00:00
return [ ] * models . Performer ( ret ) , nil
2019-02-14 22:53:32 +00:00
}
2020-06-22 23:19:19 +00:00
2021-03-10 01:25:51 +00:00
func ( qb * performerQueryBuilder ) tagsRepository ( ) * joinRepository {
return & joinRepository {
repository : repository {
tx : qb . tx ,
tableName : performersTagsTable ,
idColumn : performerIDColumn ,
} ,
fkColumn : tagIDColumn ,
}
}
func ( qb * performerQueryBuilder ) GetTagIDs ( id int ) ( [ ] int , error ) {
return qb . tagsRepository ( ) . getIDs ( id )
}
func ( qb * performerQueryBuilder ) UpdateTags ( id int , tagIDs [ ] int ) error {
// Delete the existing joins and then create new ones
return qb . tagsRepository ( ) . replace ( id , tagIDs )
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) imageRepository ( ) * imageRepository {
return & imageRepository {
repository : repository {
tx : qb . tx ,
tableName : "performers_image" ,
idColumn : performerIDColumn ,
} ,
imageColumn : "image" ,
2020-06-22 23:19:19 +00:00
}
2021-01-18 01:23:20 +00:00
}
2020-06-22 23:19:19 +00:00
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) GetImage ( performerID int ) ( [ ] byte , error ) {
return qb . imageRepository ( ) . get ( performerID )
}
2020-06-22 23:19:19 +00:00
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) UpdateImage ( performerID int , image [ ] byte ) error {
return qb . imageRepository ( ) . replace ( performerID , image )
2020-06-22 23:19:19 +00:00
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) DestroyImage ( performerID int ) error {
return qb . imageRepository ( ) . destroy ( [ ] int { performerID } )
}
2020-06-22 23:19:19 +00:00
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) stashIDRepository ( ) * stashIDRepository {
return & stashIDRepository {
repository {
tx : qb . tx ,
tableName : "performer_stash_ids" ,
idColumn : performerIDColumn ,
} ,
2020-06-22 23:19:19 +00:00
}
}
2021-01-18 01:23:20 +00:00
func ( qb * performerQueryBuilder ) GetStashIDs ( performerID int ) ( [ ] * models . StashID , error ) {
return qb . stashIDRepository ( ) . get ( performerID )
}
func ( qb * performerQueryBuilder ) UpdateStashIDs ( performerID int , stashIDs [ ] models . StashID ) error {
return qb . stashIDRepository ( ) . replace ( performerID , stashIDs )
2020-06-22 23:19:19 +00:00
}
2021-05-03 04:21:20 +00:00
func ( qb * performerQueryBuilder ) FindByStashIDStatus ( hasStashID bool , stashboxEndpoint string ) ( [ ] * models . Performer , error ) {
query := selectAll ( "performers" ) + `
LEFT JOIN performer_stash_ids on performer_stash_ids . performer_id = performers . id
`
if hasStashID {
query += `
WHERE performer_stash_ids . stash_id IS NOT NULL
AND performer_stash_ids . endpoint = ?
`
} else {
query += `
WHERE performer_stash_ids . stash_id IS NULL
`
}
args := [ ] interface { } { stashboxEndpoint }
return qb . queryPerformers ( query , args )
}