Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gender support for performer #371

Merged
merged 12 commits into from
Mar 31, 2020
1 change: 1 addition & 0 deletions graphql/documents/data/performer-slim.graphql
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
fragment SlimPerformerData on Performer {
id
name
gender
image_path
}
1 change: 1 addition & 0 deletions graphql/documents/data/performer.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ fragment PerformerData on Performer {
checksum
name
url
gender
twitter
instagram
birthdate
Expand Down
4 changes: 4 additions & 0 deletions graphql/documents/mutations/performer.graphql
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mutation PerformerCreate(
$name: String,
$url: String,
$gender: GenderEnum,
$birthdate: String,
$ethnicity: String,
$country: String,
Expand All @@ -20,6 +21,7 @@ mutation PerformerCreate(
performerCreate(input: {
name: $name,
url: $url,
gender: $gender,
birthdate: $birthdate,
ethnicity: $ethnicity,
country: $country,
Expand All @@ -44,6 +46,7 @@ mutation PerformerUpdate(
$id: ID!,
$name: String,
$url: String,
$gender: GenderEnum,
$birthdate: String,
$ethnicity: String,
$country: String,
Expand All @@ -64,6 +67,7 @@ mutation PerformerUpdate(
id: $id,
name: $name,
url: $url,
gender: $gender,
birthdate: $birthdate,
ethnicity: $ethnicity,
country: $country,
Expand Down
7 changes: 7 additions & 0 deletions graphql/schema/types/filters.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ input PerformerFilterType {
piercings: StringCriterionInput
"""Filter by aliases"""
aliases: StringCriterionInput
"""Filter by gender"""
gender: GenderCriterionInput
}

input SceneMarkerFilterType {
Expand Down Expand Up @@ -114,4 +116,9 @@ input IntCriterionInput {
input MultiCriterionInput {
value: [ID!]
modifier: CriterionModifier!
}

input GenderCriterionInput {
value: GenderEnum
modifier: CriterionModifier!
}
11 changes: 11 additions & 0 deletions graphql/schema/types/performer.graphql
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
enum GenderEnum {
MALE
FEMALE
TRANSGENDER_MALE
TRANSGENDER_FEMALE
INTERSEX
}

type Performer {
id: ID!
checksum: String!
name: String
url: String
gender: GenderEnum
twitter: String
instagram: String
birthdate: String
Expand All @@ -26,6 +35,7 @@ type Performer {
input PerformerCreateInput {
name: String
url: String
gender: GenderEnum
birthdate: String
ethnicity: String
country: String
Expand All @@ -48,6 +58,7 @@ input PerformerUpdateInput {
id: ID!
name: String
url: String
gender: GenderEnum
birthdate: String
ethnicity: String
country: String
Expand Down
14 changes: 14 additions & 0 deletions pkg/api/resolver_model_performer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package api

import (
"context"

"github.com/stashapp/stash/pkg/api/urlbuilders"
"github.com/stashapp/stash/pkg/models"
)
Expand All @@ -20,6 +21,19 @@ func (r *performerResolver) URL(ctx context.Context, obj *models.Performer) (*st
return nil, nil
}

func (r *performerResolver) Gender(ctx context.Context, obj *models.Performer) (*models.GenderEnum, error) {
var ret models.GenderEnum

if obj.Gender.Valid {
ret = models.GenderEnum(obj.Gender.String)
if ret.IsValid() {
return &ret, nil
}
}

return nil, nil
}

func (r *performerResolver) Twitter(ctx context.Context, obj *models.Performer) (*string, error) {
if obj.Twitter.Valid {
return &obj.Twitter.String, nil
Expand Down
6 changes: 6 additions & 0 deletions pkg/api/resolver_mutation_performer.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ func (r *mutationResolver) PerformerCreate(ctx context.Context, input models.Per
if input.URL != nil {
newPerformer.URL = sql.NullString{String: *input.URL, Valid: true}
}
if input.Gender != nil {
newPerformer.Gender = sql.NullString{String: input.Gender.String(), Valid: true}
}
if input.Birthdate != nil {
newPerformer.Birthdate = models.SQLiteDate{String: *input.Birthdate, Valid: true}
}
Expand Down Expand Up @@ -128,6 +131,9 @@ func (r *mutationResolver) PerformerUpdate(ctx context.Context, input models.Per
if input.URL != nil {
updatedPerformer.URL = sql.NullString{String: *input.URL, Valid: true}
}
if input.Gender != nil {
updatedPerformer.Gender = sql.NullString{String: input.Gender.String(), Valid: true}
}
if input.Birthdate != nil {
updatedPerformer.Birthdate = models.SQLiteDate{String: *input.Birthdate, Valid: true}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (

var DB *sqlx.DB
var dbPath string
var appSchemaVersion uint = 4
var appSchemaVersion uint = 5
var databaseSchemaVersion uint

const sqlite3Driver = "sqlite3_regexp"
Expand Down
89 changes: 89 additions & 0 deletions pkg/database/migrations/5_performer_gender.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@

PRAGMA foreign_keys=off;

-- need to re-create the performers table without the added column.
-- also need re-create the performers_scenes table due to the foreign key

-- rename existing performers table
ALTER TABLE `performers` RENAME TO `performers_old`;
ALTER TABLE `performers_scenes` RENAME TO `performers_scenes_old`;

-- drop the indexes
DROP INDEX IF EXISTS `index_performers_on_name`;
DROP INDEX IF EXISTS `index_performers_on_checksum`;
DROP INDEX IF EXISTS `index_performers_scenes_on_scene_id`;
DROP INDEX IF EXISTS `index_performers_scenes_on_performer_id`;

-- recreate the tables
CREATE TABLE `performers` (
`id` integer not null primary key autoincrement,
`image` blob not null,
`checksum` varchar(255) not null,
`name` varchar(255),
`url` varchar(255),
`twitter` varchar(255),
`instagram` varchar(255),
`birthdate` date,
`ethnicity` varchar(255),
`country` varchar(255),
`eye_color` varchar(255),
`height` varchar(255),
`measurements` varchar(255),
`fake_tits` varchar(255),
`career_length` varchar(255),
`tattoos` varchar(255),
`piercings` varchar(255),
`aliases` varchar(255),
`favorite` boolean not null default '0',
`created_at` datetime not null,
`updated_at` datetime not null
);

CREATE TABLE `performers_scenes` (
`performer_id` integer,
`scene_id` integer,
foreign key(`performer_id`) references `performers`(`id`),
foreign key(`scene_id`) references `scenes`(`id`)
);

INSERT INTO `performers`
SELECT
`id`,
`image`,
`checksum`,
`name`,
`url`,
`twitter`,
`instagram`,
`birthdate`,
`ethnicity`,
`country`,
`eye_color`,
`height`,
`measurements`,
`fake_tits`,
`career_length`,
`tattoos`,
`piercings`,
`aliases`,
`favorite`,
`created_at`,
`updated_at`
FROM `performers_old`;

INSERT INTO `performers_scenes`
SELECT
`performer_id`,
`scene_id`
FROM `performers_scenes_old`;

DROP TABLE `performers_scenes_old`;
DROP TABLE `performers_old`;

-- re-create the indexes after removing the old tables
CREATE INDEX `index_performers_on_name` on `performers` (`name`);
CREATE INDEX `index_performers_on_checksum` on `performers` (`checksum`);
CREATE INDEX `index_performers_scenes_on_scene_id` on `performers_scenes` (`scene_id`);
CREATE INDEX `index_performers_scenes_on_performer_id` on `performers_scenes` (`performer_id`);

PRAGMA foreign_keys=on;
1 change: 1 addition & 0 deletions pkg/database/migrations/5_performer_gender.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE `performers` ADD COLUMN `gender` varchar(20);
4 changes: 3 additions & 1 deletion pkg/manager/jsonschema/performer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package jsonschema
import (
"encoding/json"
"fmt"
"github.com/stashapp/stash/pkg/models"
"os"

"github.com/stashapp/stash/pkg/models"
)

type Performer struct {
Name string `json:"name,omitempty"`
Gender string `json:"gender,omitempty"`
URL string `json:"url,omitempty"`
Twitter string `json:"twitter,omitempty"`
Instagram string `json:"instagram,omitempty"`
Expand Down
3 changes: 3 additions & 0 deletions pkg/manager/task_export.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ func (t *ExportTask) ExportPerformers(ctx context.Context) {
if performer.Name.Valid {
newPerformerJSON.Name = performer.Name.String
}
if performer.Gender.Valid {
newPerformerJSON.Gender = performer.Gender.String
}
if performer.URL.Valid {
newPerformerJSON.URL = performer.URL.String
}
Expand Down
29 changes: 16 additions & 13 deletions pkg/manager/task_import.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ func (t *ImportTask) ImportPerformers(ctx context.Context) {
if performerJSON.Name != "" {
newPerformer.Name = sql.NullString{String: performerJSON.Name, Valid: true}
}
if performerJSON.Gender != "" {
newPerformer.Gender = sql.NullString{String: performerJSON.Gender, Valid: true}
}
if performerJSON.URL != "" {
newPerformer.URL = sql.NullString{String: performerJSON.URL, Valid: true}
}
Expand Down Expand Up @@ -241,19 +244,19 @@ func (t *ImportTask) ImportMovies(ctx context.Context) {

// Populate a new movie from the input
newMovie := models.Movie{
FrontImage: frontimageData,
BackImage: backimageData,
Checksum: checksum,
Name: sql.NullString{String: movieJSON.Name, Valid: true},
Aliases: sql.NullString{String: movieJSON.Aliases, Valid: true},
Date: models.SQLiteDate{String: movieJSON.Date, Valid: true},
Duration: sql.NullString{String: movieJSON.Duration, Valid: true},
Rating: sql.NullString{String: movieJSON.Rating, Valid: true},
Director: sql.NullString{String: movieJSON.Director, Valid: true},
Synopsis: sql.NullString{String: movieJSON.Synopsis, Valid: true},
URL: sql.NullString{String: movieJSON.URL, Valid: true},
CreatedAt: models.SQLiteTimestamp{Timestamp: t.getTimeFromJSONTime(movieJSON.CreatedAt)},
UpdatedAt: models.SQLiteTimestamp{Timestamp: t.getTimeFromJSONTime(movieJSON.UpdatedAt)},
FrontImage: frontimageData,
BackImage: backimageData,
Checksum: checksum,
Name: sql.NullString{String: movieJSON.Name, Valid: true},
Aliases: sql.NullString{String: movieJSON.Aliases, Valid: true},
Date: models.SQLiteDate{String: movieJSON.Date, Valid: true},
Duration: sql.NullString{String: movieJSON.Duration, Valid: true},
Rating: sql.NullString{String: movieJSON.Rating, Valid: true},
Director: sql.NullString{String: movieJSON.Director, Valid: true},
Synopsis: sql.NullString{String: movieJSON.Synopsis, Valid: true},
URL: sql.NullString{String: movieJSON.URL, Valid: true},
CreatedAt: models.SQLiteTimestamp{Timestamp: t.getTimeFromJSONTime(movieJSON.CreatedAt)},
UpdatedAt: models.SQLiteTimestamp{Timestamp: t.getTimeFromJSONTime(movieJSON.UpdatedAt)},
}

_, err = qb.Create(newMovie, tx)
Expand Down
1 change: 1 addition & 0 deletions pkg/models/model_performer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Performer struct {
Image []byte `db:"image" json:"image"`
Checksum string `db:"checksum" json:"checksum"`
Name sql.NullString `db:"name" json:"name"`
Gender sql.NullString `db:"gender" json:"gender"`
URL sql.NullString `db:"url" json:"url"`
Twitter sql.NullString `db:"twitter" json:"twitter"`
Instagram sql.NullString `db:"instagram" json:"instagram"`
Expand Down
9 changes: 7 additions & 2 deletions pkg/models/querybuilder_performer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ func NewPerformerQueryBuilder() PerformerQueryBuilder {
func (qb *PerformerQueryBuilder) Create(newPerformer Performer, tx *sqlx.Tx) (*Performer, error) {
ensureTx(tx)
result, err := tx.NamedExec(
`INSERT INTO performers (image, checksum, name, url, twitter, instagram, birthdate, ethnicity, country,
`INSERT INTO performers (image, checksum, name, url, gender, twitter, instagram, birthdate, ethnicity, country,
eye_color, height, measurements, fake_tits, career_length, tattoos, piercings,
aliases, favorite, created_at, updated_at)
VALUES (:image, :checksum, :name, :url, :twitter, :instagram, :birthdate, :ethnicity, :country,
VALUES (:image, :checksum, :name, :url, :gender, :twitter, :instagram, :birthdate, :ethnicity, :country,
:eye_color, :height, :measurements, :fake_tits, :career_length, :tattoos, :piercings,
:aliases, :favorite, :created_at, :updated_at)
`,
Expand Down Expand Up @@ -153,6 +153,11 @@ func (qb *PerformerQueryBuilder) Query(performerFilter *PerformerFilterType, fin
query.addArg(thisArgs...)
}

if gender := performerFilter.Gender; gender != nil {
query.addWhere("performers.gender = ?")
query.addArg(gender.Value.String())
}

handleStringCriterion(tableName+".ethnicity", performerFilter.Ethnicity, &query)
handleStringCriterion(tableName+".country", performerFilter.Country, &query)
handleStringCriterion(tableName+".eye_color", performerFilter.EyeColor, &query)
Expand Down
Loading