mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
Use changesets correctly when updating objects (#976)
This commit is contained in:
@@ -25,55 +25,17 @@ mutation GalleryCreate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutation GalleryUpdate(
|
mutation GalleryUpdate(
|
||||||
$id: ID!,
|
$input: GalleryUpdateInput!) {
|
||||||
$title: String,
|
|
||||||
$details: String,
|
|
||||||
$url: String,
|
|
||||||
$date: String,
|
|
||||||
$rating: Int,
|
|
||||||
$scene_id: ID,
|
|
||||||
$studio_id: ID,
|
|
||||||
$performer_ids: [ID!] = [],
|
|
||||||
$tag_ids: [ID!] = []) {
|
|
||||||
|
|
||||||
galleryUpdate(input: {
|
galleryUpdate(input: $input) {
|
||||||
id: $id,
|
|
||||||
title: $title,
|
|
||||||
details: $details,
|
|
||||||
url: $url,
|
|
||||||
date: $date,
|
|
||||||
rating: $rating,
|
|
||||||
scene_id: $scene_id,
|
|
||||||
studio_id: $studio_id,
|
|
||||||
tag_ids: $tag_ids,
|
|
||||||
performer_ids: $performer_ids
|
|
||||||
}) {
|
|
||||||
...GalleryData
|
...GalleryData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutation BulkGalleryUpdate(
|
mutation BulkGalleryUpdate(
|
||||||
$ids: [ID!] = [],
|
$input: BulkGalleryUpdateInput!) {
|
||||||
$url: String,
|
|
||||||
$date: String,
|
|
||||||
$details: String,
|
|
||||||
$rating: Int,
|
|
||||||
$scene_id: ID,
|
|
||||||
$studio_id: ID,
|
|
||||||
$tag_ids: BulkUpdateIds,
|
|
||||||
$performer_ids: BulkUpdateIds) {
|
|
||||||
|
|
||||||
bulkGalleryUpdate(input: {
|
bulkGalleryUpdate(input: $input) {
|
||||||
ids: $ids,
|
|
||||||
details: $details,
|
|
||||||
url: $url,
|
|
||||||
date: $date,
|
|
||||||
rating: $rating,
|
|
||||||
scene_id: $scene_id,
|
|
||||||
studio_id: $studio_id,
|
|
||||||
tag_ids: $tag_ids,
|
|
||||||
performer_ids: $performer_ids
|
|
||||||
}) {
|
|
||||||
...GalleryData
|
...GalleryData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,15 @@
|
|||||||
mutation ImageUpdate(
|
mutation ImageUpdate(
|
||||||
$id: ID!,
|
$input: ImageUpdateInput!) {
|
||||||
$title: String,
|
|
||||||
$rating: Int,
|
|
||||||
$studio_id: ID,
|
|
||||||
$gallery_ids: [ID!] = [],
|
|
||||||
$performer_ids: [ID!] = [],
|
|
||||||
$tag_ids: [ID!] = []) {
|
|
||||||
|
|
||||||
imageUpdate(input: {
|
imageUpdate(input: $input) {
|
||||||
id: $id,
|
|
||||||
title: $title,
|
|
||||||
rating: $rating,
|
|
||||||
studio_id: $studio_id,
|
|
||||||
gallery_ids: $gallery_ids,
|
|
||||||
performer_ids: $performer_ids,
|
|
||||||
tag_ids: $tag_ids
|
|
||||||
}) {
|
|
||||||
...SlimImageData
|
...SlimImageData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutation BulkImageUpdate(
|
mutation BulkImageUpdate(
|
||||||
$ids: [ID!] = [],
|
$input: BulkImageUpdateInput!) {
|
||||||
$title: String,
|
|
||||||
$rating: Int,
|
|
||||||
$studio_id: ID,
|
|
||||||
$gallery_ids: BulkUpdateIds,
|
|
||||||
$performer_ids: BulkUpdateIds,
|
|
||||||
$tag_ids: BulkUpdateIds) {
|
|
||||||
|
|
||||||
bulkImageUpdate(input: {
|
bulkImageUpdate(input: $input) {
|
||||||
ids: $ids,
|
|
||||||
title: $title,
|
|
||||||
rating: $rating,
|
|
||||||
studio_id: $studio_id,
|
|
||||||
gallery_ids: $gallery_ids,
|
|
||||||
performer_ids: $performer_ids,
|
|
||||||
tag_ids: $tag_ids
|
|
||||||
}) {
|
|
||||||
...SlimImageData
|
...SlimImageData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,21 +16,8 @@ mutation MovieCreate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutation MovieUpdate(
|
mutation MovieUpdate($input: MovieUpdateInput!) {
|
||||||
$id: ID!
|
movieUpdate(input: $input) {
|
||||||
$name: String,
|
|
||||||
$aliases: String,
|
|
||||||
$duration: Int,
|
|
||||||
$date: String,
|
|
||||||
$rating: Int,
|
|
||||||
$studio_id: ID,
|
|
||||||
$director: String,
|
|
||||||
$synopsis: String,
|
|
||||||
$url: String,
|
|
||||||
$front_image: String,
|
|
||||||
$back_image: String) {
|
|
||||||
|
|
||||||
movieUpdate(input: { id: $id, name: $name, aliases: $aliases, duration: $duration, date: $date, rating: $rating, studio_id: $studio_id, director: $director, synopsis: $synopsis, url: $url, front_image: $front_image, back_image: $back_image }) {
|
|
||||||
...MovieData
|
...MovieData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,49 +45,9 @@ mutation PerformerCreate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutation PerformerUpdate(
|
mutation PerformerUpdate(
|
||||||
$id: ID!,
|
$input: PerformerUpdateInput!) {
|
||||||
$name: String,
|
|
||||||
$url: String,
|
|
||||||
$gender: GenderEnum,
|
|
||||||
$birthdate: String,
|
|
||||||
$ethnicity: String,
|
|
||||||
$country: String,
|
|
||||||
$eye_color: String,
|
|
||||||
$height: String,
|
|
||||||
$measurements: String,
|
|
||||||
$fake_tits: String,
|
|
||||||
$career_length: String,
|
|
||||||
$tattoos: String,
|
|
||||||
$piercings: String,
|
|
||||||
$aliases: String,
|
|
||||||
$twitter: String,
|
|
||||||
$instagram: String,
|
|
||||||
$favorite: Boolean,
|
|
||||||
$stash_ids: [StashIDInput!],
|
|
||||||
$image: String) {
|
|
||||||
|
|
||||||
performerUpdate(input: {
|
performerUpdate(input: $input) {
|
||||||
id: $id,
|
|
||||||
name: $name,
|
|
||||||
url: $url,
|
|
||||||
gender: $gender,
|
|
||||||
birthdate: $birthdate,
|
|
||||||
ethnicity: $ethnicity,
|
|
||||||
country: $country,
|
|
||||||
eye_color: $eye_color,
|
|
||||||
height: $height,
|
|
||||||
measurements: $measurements,
|
|
||||||
fake_tits: $fake_tits,
|
|
||||||
career_length: $career_length,
|
|
||||||
tattoos: $tattoos,
|
|
||||||
piercings: $piercings,
|
|
||||||
aliases: $aliases,
|
|
||||||
twitter: $twitter,
|
|
||||||
instagram: $instagram,
|
|
||||||
favorite: $favorite,
|
|
||||||
stash_ids: $stash_ids,
|
|
||||||
image: $image
|
|
||||||
}) {
|
|
||||||
...PerformerData
|
...PerformerData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,61 +1,15 @@
|
|||||||
mutation SceneUpdate(
|
mutation SceneUpdate(
|
||||||
$id: ID!,
|
$input: SceneUpdateInput!) {
|
||||||
$title: String,
|
|
||||||
$details: String,
|
|
||||||
$url: String,
|
|
||||||
$date: String,
|
|
||||||
$rating: Int,
|
|
||||||
$studio_id: ID,
|
|
||||||
$gallery_id: ID,
|
|
||||||
$performer_ids: [ID!] = [],
|
|
||||||
$movies: [SceneMovieInput!] = [],
|
|
||||||
$tag_ids: [ID!] = [],
|
|
||||||
$stash_ids: [StashIDInput!],
|
|
||||||
$cover_image: String) {
|
|
||||||
|
|
||||||
sceneUpdate(input: {
|
sceneUpdate(input: $input) {
|
||||||
id: $id,
|
|
||||||
title: $title,
|
|
||||||
details: $details,
|
|
||||||
url: $url,
|
|
||||||
date: $date,
|
|
||||||
rating: $rating,
|
|
||||||
studio_id: $studio_id,
|
|
||||||
gallery_id: $gallery_id,
|
|
||||||
performer_ids: $performer_ids,
|
|
||||||
movies: $movies,
|
|
||||||
tag_ids: $tag_ids,
|
|
||||||
stash_ids: $stash_ids,
|
|
||||||
cover_image: $cover_image
|
|
||||||
}) {
|
|
||||||
...SceneData
|
...SceneData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutation BulkSceneUpdate(
|
mutation BulkSceneUpdate(
|
||||||
$ids: [ID!] = [],
|
$input: BulkSceneUpdateInput!) {
|
||||||
$title: String,
|
|
||||||
$details: String,
|
|
||||||
$url: String,
|
|
||||||
$date: String,
|
|
||||||
$rating: Int,
|
|
||||||
$studio_id: ID,
|
|
||||||
$gallery_id: ID,
|
|
||||||
$performer_ids: BulkUpdateIds,
|
|
||||||
$tag_ids: BulkUpdateIds) {
|
|
||||||
|
|
||||||
bulkSceneUpdate(input: {
|
bulkSceneUpdate(input: $input) {
|
||||||
ids: $ids,
|
|
||||||
title: $title,
|
|
||||||
details: $details,
|
|
||||||
url: $url,
|
|
||||||
date: $date,
|
|
||||||
rating: $rating,
|
|
||||||
studio_id: $studio_id,
|
|
||||||
gallery_id: $gallery_id,
|
|
||||||
performer_ids: $performer_ids,
|
|
||||||
tag_ids: $tag_ids
|
|
||||||
}) {
|
|
||||||
...SceneData
|
...SceneData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,14 +11,9 @@ mutation StudioCreate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutation StudioUpdate(
|
mutation StudioUpdate(
|
||||||
$id: ID!
|
$input: StudioUpdateInput!) {
|
||||||
$name: String,
|
|
||||||
$url: String,
|
|
||||||
$image: String,
|
|
||||||
$stash_ids: [StashIDInput!],
|
|
||||||
$parent_id: ID) {
|
|
||||||
|
|
||||||
studioUpdate(input: { id: $id, name: $name, url: $url, image: $image, stash_ids: $stash_ids, parent_id: $parent_id }) {
|
studioUpdate(input: $input) {
|
||||||
...StudioData
|
...StudioData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ mutation TagDestroy($id: ID!) {
|
|||||||
tagDestroy(input: { id: $id })
|
tagDestroy(input: { id: $id })
|
||||||
}
|
}
|
||||||
|
|
||||||
mutation TagUpdate($id: ID!, $name: String!, $image: String) {
|
mutation TagUpdate($input: TagUpdateInput!) {
|
||||||
tagUpdate(input: { id: $id, name: $name, image: $image }) {
|
tagUpdate(input: $input) {
|
||||||
...TagData
|
...TagData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
134
pkg/api/changeset_translator.go
Normal file
134
pkg/api/changeset_translator.go
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/99designs/gqlgen/graphql"
|
||||||
|
"github.com/stashapp/stash/pkg/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
const updateInputField = "input"
|
||||||
|
|
||||||
|
func getArgumentMap(ctx context.Context) map[string]interface{} {
|
||||||
|
rctx := graphql.GetResolverContext(ctx)
|
||||||
|
reqCtx := graphql.GetRequestContext(ctx)
|
||||||
|
return rctx.Field.ArgumentMap(reqCtx.Variables)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUpdateInputMap(ctx context.Context) map[string]interface{} {
|
||||||
|
args := getArgumentMap(ctx)
|
||||||
|
|
||||||
|
input, _ := args[updateInputField]
|
||||||
|
var ret map[string]interface{}
|
||||||
|
if input != nil {
|
||||||
|
ret, _ = input.(map[string]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
if ret == nil {
|
||||||
|
ret = make(map[string]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUpdateInputMaps(ctx context.Context) []map[string]interface{} {
|
||||||
|
args := getArgumentMap(ctx)
|
||||||
|
|
||||||
|
input, _ := args[updateInputField]
|
||||||
|
var ret []map[string]interface{}
|
||||||
|
if input != nil {
|
||||||
|
ret, _ = input.([]map[string]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
type changesetTranslator struct {
|
||||||
|
inputMap map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t changesetTranslator) hasField(field string) bool {
|
||||||
|
if t.inputMap == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
_, found := t.inputMap[field]
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t changesetTranslator) nullString(value *string, field string) *sql.NullString {
|
||||||
|
if !t.hasField(field) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &sql.NullString{}
|
||||||
|
|
||||||
|
if value != nil {
|
||||||
|
ret.String = *value
|
||||||
|
ret.Valid = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t changesetTranslator) sqliteDate(value *string, field string) *models.SQLiteDate {
|
||||||
|
if !t.hasField(field) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &models.SQLiteDate{}
|
||||||
|
|
||||||
|
if value != nil {
|
||||||
|
ret.String = *value
|
||||||
|
ret.Valid = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t changesetTranslator) nullInt64(value *int, field string) *sql.NullInt64 {
|
||||||
|
if !t.hasField(field) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &sql.NullInt64{}
|
||||||
|
|
||||||
|
if value != nil {
|
||||||
|
ret.Int64 = int64(*value)
|
||||||
|
ret.Valid = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t changesetTranslator) nullInt64FromString(value *string, field string) *sql.NullInt64 {
|
||||||
|
if !t.hasField(field) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &sql.NullInt64{}
|
||||||
|
|
||||||
|
if value != nil {
|
||||||
|
ret.Int64, _ = strconv.ParseInt(*value, 10, 64)
|
||||||
|
ret.Valid = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t changesetTranslator) nullBool(value *bool, field string) *sql.NullBool {
|
||||||
|
if !t.hasField(field) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &sql.NullBool{}
|
||||||
|
|
||||||
|
if value != nil {
|
||||||
|
ret.Bool = *value
|
||||||
|
ret.Valid = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
@@ -119,7 +119,10 @@ func (r *mutationResolver) GalleryUpdate(ctx context.Context, input models.Galle
|
|||||||
// Start the transaction and save the gallery
|
// Start the transaction and save the gallery
|
||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
|
|
||||||
ret, err := r.galleryUpdate(input, tx)
|
translator := changesetTranslator{
|
||||||
|
inputMap: getUpdateInputMap(ctx),
|
||||||
|
}
|
||||||
|
ret, err := r.galleryUpdate(input, translator, tx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
@@ -137,11 +140,16 @@ func (r *mutationResolver) GalleryUpdate(ctx context.Context, input models.Galle
|
|||||||
func (r *mutationResolver) GalleriesUpdate(ctx context.Context, input []*models.GalleryUpdateInput) ([]*models.Gallery, error) {
|
func (r *mutationResolver) GalleriesUpdate(ctx context.Context, input []*models.GalleryUpdateInput) ([]*models.Gallery, error) {
|
||||||
// Start the transaction and save the gallery
|
// Start the transaction and save the gallery
|
||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
|
inputMaps := getUpdateInputMaps(ctx)
|
||||||
|
|
||||||
var ret []*models.Gallery
|
var ret []*models.Gallery
|
||||||
|
|
||||||
for _, gallery := range input {
|
for i, gallery := range input {
|
||||||
thisGallery, err := r.galleryUpdate(*gallery, tx)
|
translator := changesetTranslator{
|
||||||
|
inputMap: inputMaps[i],
|
||||||
|
}
|
||||||
|
|
||||||
|
thisGallery, err := r.galleryUpdate(*gallery, translator, tx)
|
||||||
ret = append(ret, thisGallery)
|
ret = append(ret, thisGallery)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -158,7 +166,7 @@ func (r *mutationResolver) GalleriesUpdate(ctx context.Context, input []*models.
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) galleryUpdate(input models.GalleryUpdateInput, tx *sqlx.Tx) (*models.Gallery, error) {
|
func (r *mutationResolver) galleryUpdate(input models.GalleryUpdateInput, translator changesetTranslator, tx *sqlx.Tx) (*models.Gallery, error) {
|
||||||
qb := models.NewGalleryQueryBuilder()
|
qb := models.NewGalleryQueryBuilder()
|
||||||
// Populate gallery from the input
|
// Populate gallery from the input
|
||||||
galleryID, _ := strconv.Atoi(input.ID)
|
galleryID, _ := strconv.Atoi(input.ID)
|
||||||
@@ -176,6 +184,7 @@ func (r *mutationResolver) galleryUpdate(input models.GalleryUpdateInput, tx *sq
|
|||||||
ID: galleryID,
|
ID: galleryID,
|
||||||
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.Title != nil {
|
if input.Title != nil {
|
||||||
// ensure title is not empty
|
// ensure title is not empty
|
||||||
if *input.Title == "" {
|
if *input.Title == "" {
|
||||||
@@ -190,30 +199,12 @@ func (r *mutationResolver) galleryUpdate(input models.GalleryUpdateInput, tx *sq
|
|||||||
|
|
||||||
updatedGallery.Title = &sql.NullString{String: *input.Title, Valid: true}
|
updatedGallery.Title = &sql.NullString{String: *input.Title, Valid: true}
|
||||||
}
|
}
|
||||||
if input.Details != nil {
|
|
||||||
updatedGallery.Details = &sql.NullString{String: *input.Details, Valid: true}
|
|
||||||
}
|
|
||||||
if input.URL != nil {
|
|
||||||
updatedGallery.URL = &sql.NullString{String: *input.URL, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Date != nil {
|
|
||||||
updatedGallery.Date = &models.SQLiteDate{String: *input.Date, Valid: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.Rating != nil {
|
updatedGallery.Details = translator.nullString(input.Details, "details")
|
||||||
updatedGallery.Rating = &sql.NullInt64{Int64: int64(*input.Rating), Valid: true}
|
updatedGallery.URL = translator.nullString(input.URL, "url")
|
||||||
} else {
|
updatedGallery.Date = translator.sqliteDate(input.Date, "date")
|
||||||
// rating must be nullable
|
updatedGallery.Rating = translator.nullInt64(input.Rating, "rating")
|
||||||
updatedGallery.Rating = &sql.NullInt64{Valid: false}
|
updatedGallery.StudioID = translator.nullInt64FromString(input.StudioID, "studio_id")
|
||||||
}
|
|
||||||
|
|
||||||
if input.StudioID != nil {
|
|
||||||
studioID, _ := strconv.ParseInt(*input.StudioID, 10, 64)
|
|
||||||
updatedGallery.StudioID = &sql.NullInt64{Int64: studioID, Valid: true}
|
|
||||||
} else {
|
|
||||||
// studio must be nullable
|
|
||||||
updatedGallery.StudioID = &sql.NullInt64{Valid: false}
|
|
||||||
}
|
|
||||||
|
|
||||||
// gallery scene is set from the scene only
|
// gallery scene is set from the scene only
|
||||||
|
|
||||||
@@ -224,6 +215,7 @@ func (r *mutationResolver) galleryUpdate(input models.GalleryUpdateInput, tx *sq
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the performers
|
// Save the performers
|
||||||
|
if translator.hasField("performer_ids") {
|
||||||
var performerJoins []models.PerformersGalleries
|
var performerJoins []models.PerformersGalleries
|
||||||
for _, pid := range input.PerformerIds {
|
for _, pid := range input.PerformerIds {
|
||||||
performerID, _ := strconv.Atoi(pid)
|
performerID, _ := strconv.Atoi(pid)
|
||||||
@@ -236,8 +228,10 @@ func (r *mutationResolver) galleryUpdate(input models.GalleryUpdateInput, tx *sq
|
|||||||
if err := jqb.UpdatePerformersGalleries(galleryID, performerJoins, tx); err != nil {
|
if err := jqb.UpdatePerformersGalleries(galleryID, performerJoins, tx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Save the tags
|
// Save the tags
|
||||||
|
if translator.hasField("tag_ids") {
|
||||||
var tagJoins []models.GalleriesTags
|
var tagJoins []models.GalleriesTags
|
||||||
for _, tid := range input.TagIds {
|
for _, tid := range input.TagIds {
|
||||||
tagID, _ := strconv.Atoi(tid)
|
tagID, _ := strconv.Atoi(tid)
|
||||||
@@ -250,6 +244,7 @@ func (r *mutationResolver) galleryUpdate(input models.GalleryUpdateInput, tx *sq
|
|||||||
if err := jqb.UpdateGalleriesTags(galleryID, tagJoins, tx); err != nil {
|
if err := jqb.UpdateGalleriesTags(galleryID, tagJoins, tx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return gallery, nil
|
return gallery, nil
|
||||||
}
|
}
|
||||||
@@ -263,44 +258,20 @@ func (r *mutationResolver) BulkGalleryUpdate(ctx context.Context, input models.B
|
|||||||
qb := models.NewGalleryQueryBuilder()
|
qb := models.NewGalleryQueryBuilder()
|
||||||
jqb := models.NewJoinsQueryBuilder()
|
jqb := models.NewJoinsQueryBuilder()
|
||||||
|
|
||||||
|
translator := changesetTranslator{
|
||||||
|
inputMap: getUpdateInputMap(ctx),
|
||||||
|
}
|
||||||
|
|
||||||
updatedGallery := models.GalleryPartial{
|
updatedGallery := models.GalleryPartial{
|
||||||
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
||||||
}
|
}
|
||||||
if input.Details != nil {
|
|
||||||
updatedGallery.Details = &sql.NullString{String: *input.Details, Valid: true}
|
updatedGallery.Details = translator.nullString(input.Details, "details")
|
||||||
}
|
updatedGallery.URL = translator.nullString(input.URL, "url")
|
||||||
if input.URL != nil {
|
updatedGallery.Date = translator.sqliteDate(input.Date, "date")
|
||||||
updatedGallery.URL = &sql.NullString{String: *input.URL, Valid: true}
|
updatedGallery.Rating = translator.nullInt64(input.Rating, "rating")
|
||||||
}
|
updatedGallery.StudioID = translator.nullInt64FromString(input.StudioID, "studio_id")
|
||||||
if input.Date != nil {
|
updatedGallery.SceneID = translator.nullInt64FromString(input.SceneID, "scene_id")
|
||||||
updatedGallery.Date = &models.SQLiteDate{String: *input.Date, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Rating != nil {
|
|
||||||
// a rating of 0 means unset the rating
|
|
||||||
if *input.Rating == 0 {
|
|
||||||
updatedGallery.Rating = &sql.NullInt64{Int64: 0, Valid: false}
|
|
||||||
} else {
|
|
||||||
updatedGallery.Rating = &sql.NullInt64{Int64: int64(*input.Rating), Valid: true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if input.StudioID != nil {
|
|
||||||
// empty string means unset the studio
|
|
||||||
if *input.StudioID == "" {
|
|
||||||
updatedGallery.StudioID = &sql.NullInt64{Int64: 0, Valid: false}
|
|
||||||
} else {
|
|
||||||
studioID, _ := strconv.ParseInt(*input.StudioID, 10, 64)
|
|
||||||
updatedGallery.StudioID = &sql.NullInt64{Int64: studioID, Valid: true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if input.SceneID != nil {
|
|
||||||
// empty string means unset the studio
|
|
||||||
if *input.SceneID == "" {
|
|
||||||
updatedGallery.SceneID = &sql.NullInt64{Int64: 0, Valid: false}
|
|
||||||
} else {
|
|
||||||
sceneID, _ := strconv.ParseInt(*input.SceneID, 10, 64)
|
|
||||||
updatedGallery.SceneID = &sql.NullInt64{Int64: sceneID, Valid: true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := []*models.Gallery{}
|
ret := []*models.Gallery{}
|
||||||
|
|
||||||
@@ -317,7 +288,7 @@ func (r *mutationResolver) BulkGalleryUpdate(ctx context.Context, input models.B
|
|||||||
ret = append(ret, gallery)
|
ret = append(ret, gallery)
|
||||||
|
|
||||||
// Save the performers
|
// Save the performers
|
||||||
if wasFieldIncluded(ctx, "performer_ids") {
|
if translator.hasField("performer_ids") {
|
||||||
performerIDs, err := adjustGalleryPerformerIDs(tx, galleryID, *input.PerformerIds)
|
performerIDs, err := adjustGalleryPerformerIDs(tx, galleryID, *input.PerformerIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
@@ -339,7 +310,7 @@ func (r *mutationResolver) BulkGalleryUpdate(ctx context.Context, input models.B
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the tags
|
// Save the tags
|
||||||
if wasFieldIncluded(ctx, "tag_ids") {
|
if translator.hasField("tag_ids") {
|
||||||
tagIDs, err := adjustGalleryTagIDs(tx, galleryID, *input.TagIds)
|
tagIDs, err := adjustGalleryTagIDs(tx, galleryID, *input.TagIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -17,7 +16,11 @@ func (r *mutationResolver) ImageUpdate(ctx context.Context, input models.ImageUp
|
|||||||
// Start the transaction and save the image
|
// Start the transaction and save the image
|
||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
|
|
||||||
ret, err := r.imageUpdate(input, tx)
|
translator := changesetTranslator{
|
||||||
|
inputMap: getUpdateInputMap(ctx),
|
||||||
|
}
|
||||||
|
|
||||||
|
ret, err := r.imageUpdate(input, translator, tx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
@@ -35,11 +38,16 @@ func (r *mutationResolver) ImageUpdate(ctx context.Context, input models.ImageUp
|
|||||||
func (r *mutationResolver) ImagesUpdate(ctx context.Context, input []*models.ImageUpdateInput) ([]*models.Image, error) {
|
func (r *mutationResolver) ImagesUpdate(ctx context.Context, input []*models.ImageUpdateInput) ([]*models.Image, error) {
|
||||||
// Start the transaction and save the image
|
// Start the transaction and save the image
|
||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
|
inputMaps := getUpdateInputMaps(ctx)
|
||||||
|
|
||||||
var ret []*models.Image
|
var ret []*models.Image
|
||||||
|
|
||||||
for _, image := range input {
|
for i, image := range input {
|
||||||
thisImage, err := r.imageUpdate(*image, tx)
|
translator := changesetTranslator{
|
||||||
|
inputMap: inputMaps[i],
|
||||||
|
}
|
||||||
|
|
||||||
|
thisImage, err := r.imageUpdate(*image, translator, tx)
|
||||||
ret = append(ret, thisImage)
|
ret = append(ret, thisImage)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -56,7 +64,7 @@ func (r *mutationResolver) ImagesUpdate(ctx context.Context, input []*models.Ima
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) imageUpdate(input models.ImageUpdateInput, tx *sqlx.Tx) (*models.Image, error) {
|
func (r *mutationResolver) imageUpdate(input models.ImageUpdateInput, translator changesetTranslator, tx *sqlx.Tx) (*models.Image, error) {
|
||||||
// Populate image from the input
|
// Populate image from the input
|
||||||
imageID, _ := strconv.Atoi(input.ID)
|
imageID, _ := strconv.Atoi(input.ID)
|
||||||
|
|
||||||
@@ -65,24 +73,10 @@ func (r *mutationResolver) imageUpdate(input models.ImageUpdateInput, tx *sqlx.T
|
|||||||
ID: imageID,
|
ID: imageID,
|
||||||
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
||||||
}
|
}
|
||||||
if input.Title != nil {
|
|
||||||
updatedImage.Title = &sql.NullString{String: *input.Title, Valid: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.Rating != nil {
|
updatedImage.Title = translator.nullString(input.Title, "title")
|
||||||
updatedImage.Rating = &sql.NullInt64{Int64: int64(*input.Rating), Valid: true}
|
updatedImage.Rating = translator.nullInt64(input.Rating, "rating")
|
||||||
} else {
|
updatedImage.StudioID = translator.nullInt64FromString(input.StudioID, "studio_id")
|
||||||
// rating must be nullable
|
|
||||||
updatedImage.Rating = &sql.NullInt64{Valid: false}
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.StudioID != nil {
|
|
||||||
studioID, _ := strconv.ParseInt(*input.StudioID, 10, 64)
|
|
||||||
updatedImage.StudioID = &sql.NullInt64{Int64: studioID, Valid: true}
|
|
||||||
} else {
|
|
||||||
// studio must be nullable
|
|
||||||
updatedImage.StudioID = &sql.NullInt64{Valid: false}
|
|
||||||
}
|
|
||||||
|
|
||||||
qb := models.NewImageQueryBuilder()
|
qb := models.NewImageQueryBuilder()
|
||||||
jqb := models.NewJoinsQueryBuilder()
|
jqb := models.NewJoinsQueryBuilder()
|
||||||
@@ -94,6 +88,7 @@ func (r *mutationResolver) imageUpdate(input models.ImageUpdateInput, tx *sqlx.T
|
|||||||
// don't set the galleries directly. Use add/remove gallery images interface instead
|
// don't set the galleries directly. Use add/remove gallery images interface instead
|
||||||
|
|
||||||
// Save the performers
|
// Save the performers
|
||||||
|
if translator.hasField("performer_ids") {
|
||||||
var performerJoins []models.PerformersImages
|
var performerJoins []models.PerformersImages
|
||||||
for _, pid := range input.PerformerIds {
|
for _, pid := range input.PerformerIds {
|
||||||
performerID, _ := strconv.Atoi(pid)
|
performerID, _ := strconv.Atoi(pid)
|
||||||
@@ -106,8 +101,10 @@ func (r *mutationResolver) imageUpdate(input models.ImageUpdateInput, tx *sqlx.T
|
|||||||
if err := jqb.UpdatePerformersImages(imageID, performerJoins, tx); err != nil {
|
if err := jqb.UpdatePerformersImages(imageID, performerJoins, tx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Save the tags
|
// Save the tags
|
||||||
|
if translator.hasField("tag_ids") {
|
||||||
var tagJoins []models.ImagesTags
|
var tagJoins []models.ImagesTags
|
||||||
for _, tid := range input.TagIds {
|
for _, tid := range input.TagIds {
|
||||||
tagID, _ := strconv.Atoi(tid)
|
tagID, _ := strconv.Atoi(tid)
|
||||||
@@ -120,6 +117,7 @@ func (r *mutationResolver) imageUpdate(input models.ImageUpdateInput, tx *sqlx.T
|
|||||||
if err := jqb.UpdateImagesTags(imageID, tagJoins, tx); err != nil {
|
if err := jqb.UpdateImagesTags(imageID, tagJoins, tx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return image, nil
|
return image, nil
|
||||||
}
|
}
|
||||||
@@ -136,27 +134,15 @@ func (r *mutationResolver) BulkImageUpdate(ctx context.Context, input models.Bul
|
|||||||
updatedImage := models.ImagePartial{
|
updatedImage := models.ImagePartial{
|
||||||
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
||||||
}
|
}
|
||||||
if input.Title != nil {
|
|
||||||
updatedImage.Title = &sql.NullString{String: *input.Title, Valid: true}
|
translator := changesetTranslator{
|
||||||
}
|
inputMap: getUpdateInputMap(ctx),
|
||||||
if input.Rating != nil {
|
|
||||||
// a rating of 0 means unset the rating
|
|
||||||
if *input.Rating == 0 {
|
|
||||||
updatedImage.Rating = &sql.NullInt64{Int64: 0, Valid: false}
|
|
||||||
} else {
|
|
||||||
updatedImage.Rating = &sql.NullInt64{Int64: int64(*input.Rating), Valid: true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if input.StudioID != nil {
|
|
||||||
// empty string means unset the studio
|
|
||||||
if *input.StudioID == "" {
|
|
||||||
updatedImage.StudioID = &sql.NullInt64{Int64: 0, Valid: false}
|
|
||||||
} else {
|
|
||||||
studioID, _ := strconv.ParseInt(*input.StudioID, 10, 64)
|
|
||||||
updatedImage.StudioID = &sql.NullInt64{Int64: studioID, Valid: true}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updatedImage.Title = translator.nullString(input.Title, "title")
|
||||||
|
updatedImage.Rating = translator.nullInt64(input.Rating, "rating")
|
||||||
|
updatedImage.StudioID = translator.nullInt64FromString(input.StudioID, "studio_id")
|
||||||
|
|
||||||
ret := []*models.Image{}
|
ret := []*models.Image{}
|
||||||
|
|
||||||
for _, imageIDStr := range input.Ids {
|
for _, imageIDStr := range input.Ids {
|
||||||
@@ -172,7 +158,7 @@ func (r *mutationResolver) BulkImageUpdate(ctx context.Context, input models.Bul
|
|||||||
ret = append(ret, image)
|
ret = append(ret, image)
|
||||||
|
|
||||||
// Save the galleries
|
// Save the galleries
|
||||||
if wasFieldIncluded(ctx, "gallery_ids") {
|
if translator.hasField("gallery_ids") {
|
||||||
galleryIDs, err := adjustImageGalleryIDs(tx, imageID, *input.GalleryIds)
|
galleryIDs, err := adjustImageGalleryIDs(tx, imageID, *input.GalleryIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
@@ -193,7 +179,7 @@ func (r *mutationResolver) BulkImageUpdate(ctx context.Context, input models.Bul
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the performers
|
// Save the performers
|
||||||
if wasFieldIncluded(ctx, "performer_ids") {
|
if translator.hasField("performer_ids") {
|
||||||
performerIDs, err := adjustImagePerformerIDs(tx, imageID, *input.PerformerIds)
|
performerIDs, err := adjustImagePerformerIDs(tx, imageID, *input.PerformerIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
@@ -215,7 +201,7 @@ func (r *mutationResolver) BulkImageUpdate(ctx context.Context, input models.Bul
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the tags
|
// Save the tags
|
||||||
if wasFieldIncluded(ctx, "tag_ids") {
|
if translator.hasField("tag_ids") {
|
||||||
tagIDs, err := adjustImageTagIDs(tx, imageID, *input.TagIds)
|
tagIDs, err := adjustImageTagIDs(tx, imageID, *input.TagIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
|
|||||||
@@ -117,16 +117,21 @@ func (r *mutationResolver) MovieUpdate(ctx context.Context, input models.MovieUp
|
|||||||
ID: movieID,
|
ID: movieID,
|
||||||
UpdatedAt: &models.SQLiteTimestamp{Timestamp: time.Now()},
|
UpdatedAt: &models.SQLiteTimestamp{Timestamp: time.Now()},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
translator := changesetTranslator{
|
||||||
|
inputMap: getUpdateInputMap(ctx),
|
||||||
|
}
|
||||||
|
|
||||||
var frontimageData []byte
|
var frontimageData []byte
|
||||||
var err error
|
var err error
|
||||||
frontImageIncluded := wasFieldIncluded(ctx, "front_image")
|
frontImageIncluded := translator.hasField("front_image")
|
||||||
if input.FrontImage != nil {
|
if input.FrontImage != nil {
|
||||||
_, frontimageData, err = utils.ProcessBase64Image(*input.FrontImage)
|
_, frontimageData, err = utils.ProcessBase64Image(*input.FrontImage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
backImageIncluded := wasFieldIncluded(ctx, "back_image")
|
backImageIncluded := translator.hasField("back_image")
|
||||||
var backimageData []byte
|
var backimageData []byte
|
||||||
if input.BackImage != nil {
|
if input.BackImage != nil {
|
||||||
_, backimageData, err = utils.ProcessBase64Image(*input.BackImage)
|
_, backimageData, err = utils.ProcessBase64Image(*input.BackImage)
|
||||||
@@ -142,45 +147,14 @@ func (r *mutationResolver) MovieUpdate(ctx context.Context, input models.MovieUp
|
|||||||
updatedMovie.Checksum = &checksum
|
updatedMovie.Checksum = &checksum
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.Aliases != nil {
|
updatedMovie.Aliases = translator.nullString(input.Aliases, "aliases")
|
||||||
updatedMovie.Aliases = &sql.NullString{String: *input.Aliases, Valid: true}
|
updatedMovie.Duration = translator.nullInt64(input.Duration, "duration")
|
||||||
}
|
updatedMovie.Date = translator.sqliteDate(input.Date, "date")
|
||||||
if input.Duration != nil {
|
updatedMovie.Rating = translator.nullInt64(input.Rating, "rating")
|
||||||
duration := int64(*input.Duration)
|
updatedMovie.StudioID = translator.nullInt64FromString(input.StudioID, "studio_id")
|
||||||
updatedMovie.Duration = &sql.NullInt64{Int64: duration, Valid: true}
|
updatedMovie.Director = translator.nullString(input.Director, "director")
|
||||||
}
|
updatedMovie.Synopsis = translator.nullString(input.Synopsis, "synopsis")
|
||||||
|
updatedMovie.URL = translator.nullString(input.URL, "url")
|
||||||
if input.Date != nil {
|
|
||||||
updatedMovie.Date = &models.SQLiteDate{String: *input.Date, Valid: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.Rating != nil {
|
|
||||||
rating := int64(*input.Rating)
|
|
||||||
updatedMovie.Rating = &sql.NullInt64{Int64: rating, Valid: true}
|
|
||||||
} else {
|
|
||||||
// rating must be nullable
|
|
||||||
updatedMovie.Rating = &sql.NullInt64{Valid: false}
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.StudioID != nil {
|
|
||||||
studioID, _ := strconv.ParseInt(*input.StudioID, 10, 64)
|
|
||||||
updatedMovie.StudioID = &sql.NullInt64{Int64: studioID, Valid: true}
|
|
||||||
} else {
|
|
||||||
// studio must be nullable
|
|
||||||
updatedMovie.StudioID = &sql.NullInt64{Valid: false}
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.Director != nil {
|
|
||||||
updatedMovie.Director = &sql.NullString{String: *input.Director, Valid: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.Synopsis != nil {
|
|
||||||
updatedMovie.Synopsis = &sql.NullString{String: *input.Synopsis, Valid: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.URL != nil {
|
|
||||||
updatedMovie.URL = &sql.NullString{String: *input.URL, Valid: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the transaction and save the movie
|
// Start the transaction and save the movie
|
||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
|
|||||||
@@ -130,76 +130,57 @@ func (r *mutationResolver) PerformerCreate(ctx context.Context, input models.Per
|
|||||||
func (r *mutationResolver) PerformerUpdate(ctx context.Context, input models.PerformerUpdateInput) (*models.Performer, error) {
|
func (r *mutationResolver) PerformerUpdate(ctx context.Context, input models.PerformerUpdateInput) (*models.Performer, error) {
|
||||||
// Populate performer from the input
|
// Populate performer from the input
|
||||||
performerID, _ := strconv.Atoi(input.ID)
|
performerID, _ := strconv.Atoi(input.ID)
|
||||||
updatedPerformer := models.Performer{
|
updatedPerformer := models.PerformerPartial{
|
||||||
ID: performerID,
|
ID: performerID,
|
||||||
UpdatedAt: models.SQLiteTimestamp{Timestamp: time.Now()},
|
UpdatedAt: &models.SQLiteTimestamp{Timestamp: time.Now()},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
translator := changesetTranslator{
|
||||||
|
inputMap: getUpdateInputMap(ctx),
|
||||||
|
}
|
||||||
|
|
||||||
var imageData []byte
|
var imageData []byte
|
||||||
var err error
|
var err error
|
||||||
imageIncluded := wasFieldIncluded(ctx, "image")
|
imageIncluded := translator.hasField("image")
|
||||||
if input.Image != nil {
|
if input.Image != nil {
|
||||||
_, imageData, err = utils.ProcessBase64Image(*input.Image)
|
_, imageData, err = utils.ProcessBase64Image(*input.Image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.Name != nil {
|
if input.Name != nil {
|
||||||
// generate checksum from performer name rather than image
|
// generate checksum from performer name rather than image
|
||||||
checksum := utils.MD5FromString(*input.Name)
|
checksum := utils.MD5FromString(*input.Name)
|
||||||
|
|
||||||
updatedPerformer.Name = sql.NullString{String: *input.Name, Valid: true}
|
updatedPerformer.Name = &sql.NullString{String: *input.Name, Valid: true}
|
||||||
updatedPerformer.Checksum = checksum
|
updatedPerformer.Checksum = &checksum
|
||||||
}
|
|
||||||
if input.URL != nil {
|
|
||||||
updatedPerformer.URL = sql.NullString{String: *input.URL, Valid: true}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updatedPerformer.URL = translator.nullString(input.URL, "url")
|
||||||
|
|
||||||
|
if translator.hasField("gender") {
|
||||||
if input.Gender != nil {
|
if input.Gender != nil {
|
||||||
updatedPerformer.Gender = sql.NullString{String: input.Gender.String(), Valid: true}
|
updatedPerformer.Gender = &sql.NullString{String: input.Gender.String(), Valid: true}
|
||||||
}
|
|
||||||
if input.Birthdate != nil {
|
|
||||||
updatedPerformer.Birthdate = models.SQLiteDate{String: *input.Birthdate, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Ethnicity != nil {
|
|
||||||
updatedPerformer.Ethnicity = sql.NullString{String: *input.Ethnicity, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Country != nil {
|
|
||||||
updatedPerformer.Country = sql.NullString{String: *input.Country, Valid: true}
|
|
||||||
}
|
|
||||||
if input.EyeColor != nil {
|
|
||||||
updatedPerformer.EyeColor = sql.NullString{String: *input.EyeColor, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Height != nil {
|
|
||||||
updatedPerformer.Height = sql.NullString{String: *input.Height, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Measurements != nil {
|
|
||||||
updatedPerformer.Measurements = sql.NullString{String: *input.Measurements, Valid: true}
|
|
||||||
}
|
|
||||||
if input.FakeTits != nil {
|
|
||||||
updatedPerformer.FakeTits = sql.NullString{String: *input.FakeTits, Valid: true}
|
|
||||||
}
|
|
||||||
if input.CareerLength != nil {
|
|
||||||
updatedPerformer.CareerLength = sql.NullString{String: *input.CareerLength, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Tattoos != nil {
|
|
||||||
updatedPerformer.Tattoos = sql.NullString{String: *input.Tattoos, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Piercings != nil {
|
|
||||||
updatedPerformer.Piercings = sql.NullString{String: *input.Piercings, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Aliases != nil {
|
|
||||||
updatedPerformer.Aliases = sql.NullString{String: *input.Aliases, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Twitter != nil {
|
|
||||||
updatedPerformer.Twitter = sql.NullString{String: *input.Twitter, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Instagram != nil {
|
|
||||||
updatedPerformer.Instagram = sql.NullString{String: *input.Instagram, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Favorite != nil {
|
|
||||||
updatedPerformer.Favorite = sql.NullBool{Bool: *input.Favorite, Valid: true}
|
|
||||||
} else {
|
} else {
|
||||||
updatedPerformer.Favorite = sql.NullBool{Bool: false, Valid: true}
|
updatedPerformer.Gender = &sql.NullString{String: "", Valid: false}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedPerformer.Birthdate = translator.sqliteDate(input.Birthdate, "birthdate")
|
||||||
|
updatedPerformer.Country = translator.nullString(input.Country, "country")
|
||||||
|
updatedPerformer.EyeColor = translator.nullString(input.EyeColor, "eye_color")
|
||||||
|
updatedPerformer.Measurements = translator.nullString(input.Measurements, "measurements")
|
||||||
|
updatedPerformer.Height = translator.nullString(input.Height, "height")
|
||||||
|
updatedPerformer.Ethnicity = translator.nullString(input.Ethnicity, "ethnicity")
|
||||||
|
updatedPerformer.FakeTits = translator.nullString(input.FakeTits, "fake_tits")
|
||||||
|
updatedPerformer.CareerLength = translator.nullString(input.CareerLength, "career_length")
|
||||||
|
updatedPerformer.Tattoos = translator.nullString(input.Tattoos, "tattoos")
|
||||||
|
updatedPerformer.Piercings = translator.nullString(input.Piercings, "piercings")
|
||||||
|
updatedPerformer.Aliases = translator.nullString(input.Aliases, "aliases")
|
||||||
|
updatedPerformer.Twitter = translator.nullString(input.Twitter, "twitter")
|
||||||
|
updatedPerformer.Instagram = translator.nullString(input.Instagram, "instagram")
|
||||||
|
updatedPerformer.Favorite = translator.nullBool(input.Favorite, "favorite")
|
||||||
|
|
||||||
// Start the transaction and save the performer
|
// Start the transaction and save the performer
|
||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
@@ -227,7 +208,7 @@ func (r *mutationResolver) PerformerUpdate(ctx context.Context, input models.Per
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the stash_ids
|
// Save the stash_ids
|
||||||
if input.StashIds != nil {
|
if translator.hasField("stash_ids") {
|
||||||
var stashIDJoins []models.StashID
|
var stashIDJoins []models.StashID
|
||||||
for _, stashID := range input.StashIds {
|
for _, stashID := range input.StashIds {
|
||||||
newJoin := models.StashID{
|
newJoin := models.StashID{
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ func (r *mutationResolver) SceneUpdate(ctx context.Context, input models.SceneUp
|
|||||||
// Start the transaction and save the scene
|
// Start the transaction and save the scene
|
||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
|
|
||||||
ret, err := r.sceneUpdate(input, tx)
|
translator := changesetTranslator{
|
||||||
|
inputMap: getUpdateInputMap(ctx),
|
||||||
|
}
|
||||||
|
ret, err := r.sceneUpdate(input, translator, tx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
@@ -40,8 +43,14 @@ func (r *mutationResolver) ScenesUpdate(ctx context.Context, input []*models.Sce
|
|||||||
|
|
||||||
var ret []*models.Scene
|
var ret []*models.Scene
|
||||||
|
|
||||||
for _, scene := range input {
|
inputMaps := getUpdateInputMaps(ctx)
|
||||||
thisScene, err := r.sceneUpdate(*scene, tx)
|
|
||||||
|
for i, scene := range input {
|
||||||
|
translator := changesetTranslator{
|
||||||
|
inputMap: inputMaps[i],
|
||||||
|
}
|
||||||
|
|
||||||
|
thisScene, err := r.sceneUpdate(*scene, translator, tx)
|
||||||
ret = append(ret, thisScene)
|
ret = append(ret, thisScene)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -58,7 +67,7 @@ func (r *mutationResolver) ScenesUpdate(ctx context.Context, input []*models.Sce
|
|||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mutationResolver) sceneUpdate(input models.SceneUpdateInput, tx *sqlx.Tx) (*models.Scene, error) {
|
func (r *mutationResolver) sceneUpdate(input models.SceneUpdateInput, translator changesetTranslator, tx *sqlx.Tx) (*models.Scene, error) {
|
||||||
// Populate scene from the input
|
// Populate scene from the input
|
||||||
sceneID, _ := strconv.Atoi(input.ID)
|
sceneID, _ := strconv.Atoi(input.ID)
|
||||||
|
|
||||||
@@ -69,18 +78,13 @@ func (r *mutationResolver) sceneUpdate(input models.SceneUpdateInput, tx *sqlx.T
|
|||||||
ID: sceneID,
|
ID: sceneID,
|
||||||
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
||||||
}
|
}
|
||||||
if input.Title != nil {
|
|
||||||
updatedScene.Title = &sql.NullString{String: *input.Title, Valid: true}
|
updatedScene.Title = translator.nullString(input.Title, "title")
|
||||||
}
|
updatedScene.Details = translator.nullString(input.Details, "details")
|
||||||
if input.Details != nil {
|
updatedScene.URL = translator.nullString(input.URL, "url")
|
||||||
updatedScene.Details = &sql.NullString{String: *input.Details, Valid: true}
|
updatedScene.Date = translator.sqliteDate(input.Date, "date")
|
||||||
}
|
updatedScene.Rating = translator.nullInt64(input.Rating, "rating")
|
||||||
if input.URL != nil {
|
updatedScene.StudioID = translator.nullInt64FromString(input.StudioID, "studio_id")
|
||||||
updatedScene.URL = &sql.NullString{String: *input.URL, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Date != nil {
|
|
||||||
updatedScene.Date = &models.SQLiteDate{String: *input.Date, Valid: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.CoverImage != nil && *input.CoverImage != "" {
|
if input.CoverImage != nil && *input.CoverImage != "" {
|
||||||
var err error
|
var err error
|
||||||
@@ -92,21 +96,6 @@ func (r *mutationResolver) sceneUpdate(input models.SceneUpdateInput, tx *sqlx.T
|
|||||||
// update the cover after updating the scene
|
// update the cover after updating the scene
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.Rating != nil {
|
|
||||||
updatedScene.Rating = &sql.NullInt64{Int64: int64(*input.Rating), Valid: true}
|
|
||||||
} else {
|
|
||||||
// rating must be nullable
|
|
||||||
updatedScene.Rating = &sql.NullInt64{Valid: false}
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.StudioID != nil {
|
|
||||||
studioID, _ := strconv.ParseInt(*input.StudioID, 10, 64)
|
|
||||||
updatedScene.StudioID = &sql.NullInt64{Int64: studioID, Valid: true}
|
|
||||||
} else {
|
|
||||||
// studio must be nullable
|
|
||||||
updatedScene.StudioID = &sql.NullInt64{Valid: false}
|
|
||||||
}
|
|
||||||
|
|
||||||
qb := models.NewSceneQueryBuilder()
|
qb := models.NewSceneQueryBuilder()
|
||||||
jqb := models.NewJoinsQueryBuilder()
|
jqb := models.NewJoinsQueryBuilder()
|
||||||
scene, err := qb.Update(updatedScene, tx)
|
scene, err := qb.Update(updatedScene, tx)
|
||||||
@@ -122,6 +111,7 @@ func (r *mutationResolver) sceneUpdate(input models.SceneUpdateInput, tx *sqlx.T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear the existing gallery value
|
// Clear the existing gallery value
|
||||||
|
if translator.hasField("gallery_id") {
|
||||||
gqb := models.NewGalleryQueryBuilder()
|
gqb := models.NewGalleryQueryBuilder()
|
||||||
err = gqb.ClearGalleryId(sceneID, tx)
|
err = gqb.ClearGalleryId(sceneID, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -142,8 +132,10 @@ func (r *mutationResolver) sceneUpdate(input models.SceneUpdateInput, tx *sqlx.T
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Save the performers
|
// Save the performers
|
||||||
|
if translator.hasField("performer_ids") {
|
||||||
var performerJoins []models.PerformersScenes
|
var performerJoins []models.PerformersScenes
|
||||||
for _, pid := range input.PerformerIds {
|
for _, pid := range input.PerformerIds {
|
||||||
performerID, _ := strconv.Atoi(pid)
|
performerID, _ := strconv.Atoi(pid)
|
||||||
@@ -156,8 +148,10 @@ func (r *mutationResolver) sceneUpdate(input models.SceneUpdateInput, tx *sqlx.T
|
|||||||
if err := jqb.UpdatePerformersScenes(sceneID, performerJoins, tx); err != nil {
|
if err := jqb.UpdatePerformersScenes(sceneID, performerJoins, tx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Save the movies
|
// Save the movies
|
||||||
|
if translator.hasField("movies") {
|
||||||
var movieJoins []models.MoviesScenes
|
var movieJoins []models.MoviesScenes
|
||||||
|
|
||||||
for _, movie := range input.Movies {
|
for _, movie := range input.Movies {
|
||||||
@@ -181,8 +175,10 @@ func (r *mutationResolver) sceneUpdate(input models.SceneUpdateInput, tx *sqlx.T
|
|||||||
if err := jqb.UpdateMoviesScenes(sceneID, movieJoins, tx); err != nil {
|
if err := jqb.UpdateMoviesScenes(sceneID, movieJoins, tx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Save the tags
|
// Save the tags
|
||||||
|
if translator.hasField("tag_ids") {
|
||||||
var tagJoins []models.ScenesTags
|
var tagJoins []models.ScenesTags
|
||||||
for _, tid := range input.TagIds {
|
for _, tid := range input.TagIds {
|
||||||
tagID, _ := strconv.Atoi(tid)
|
tagID, _ := strconv.Atoi(tid)
|
||||||
@@ -195,6 +191,7 @@ func (r *mutationResolver) sceneUpdate(input models.SceneUpdateInput, tx *sqlx.T
|
|||||||
if err := jqb.UpdateScenesTags(sceneID, tagJoins, tx); err != nil {
|
if err := jqb.UpdateScenesTags(sceneID, tagJoins, tx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// only update the cover image if provided and everything else was successful
|
// only update the cover image if provided and everything else was successful
|
||||||
if coverImageData != nil {
|
if coverImageData != nil {
|
||||||
@@ -205,7 +202,7 @@ func (r *mutationResolver) sceneUpdate(input models.SceneUpdateInput, tx *sqlx.T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the stash_ids
|
// Save the stash_ids
|
||||||
if input.StashIds != nil {
|
if translator.hasField("stash_ids") {
|
||||||
var stashIDJoins []models.StashID
|
var stashIDJoins []models.StashID
|
||||||
for _, stashID := range input.StashIds {
|
for _, stashID := range input.StashIds {
|
||||||
newJoin := models.StashID{
|
newJoin := models.StashID{
|
||||||
@@ -226,6 +223,10 @@ func (r *mutationResolver) BulkSceneUpdate(ctx context.Context, input models.Bul
|
|||||||
// Populate scene from the input
|
// Populate scene from the input
|
||||||
updatedTime := time.Now()
|
updatedTime := time.Now()
|
||||||
|
|
||||||
|
translator := changesetTranslator{
|
||||||
|
inputMap: getUpdateInputMap(ctx),
|
||||||
|
}
|
||||||
|
|
||||||
// Start the transaction and save the scene marker
|
// Start the transaction and save the scene marker
|
||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
qb := models.NewSceneQueryBuilder()
|
qb := models.NewSceneQueryBuilder()
|
||||||
@@ -234,35 +235,13 @@ func (r *mutationResolver) BulkSceneUpdate(ctx context.Context, input models.Bul
|
|||||||
updatedScene := models.ScenePartial{
|
updatedScene := models.ScenePartial{
|
||||||
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
UpdatedAt: &models.SQLiteTimestamp{Timestamp: updatedTime},
|
||||||
}
|
}
|
||||||
if input.Title != nil {
|
|
||||||
updatedScene.Title = &sql.NullString{String: *input.Title, Valid: true}
|
updatedScene.Title = translator.nullString(input.Title, "title")
|
||||||
}
|
updatedScene.Details = translator.nullString(input.Details, "details")
|
||||||
if input.Details != nil {
|
updatedScene.URL = translator.nullString(input.URL, "url")
|
||||||
updatedScene.Details = &sql.NullString{String: *input.Details, Valid: true}
|
updatedScene.Date = translator.sqliteDate(input.Date, "date")
|
||||||
}
|
updatedScene.Rating = translator.nullInt64(input.Rating, "rating")
|
||||||
if input.URL != nil {
|
updatedScene.StudioID = translator.nullInt64FromString(input.StudioID, "studio_id")
|
||||||
updatedScene.URL = &sql.NullString{String: *input.URL, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Date != nil {
|
|
||||||
updatedScene.Date = &models.SQLiteDate{String: *input.Date, Valid: true}
|
|
||||||
}
|
|
||||||
if input.Rating != nil {
|
|
||||||
// a rating of 0 means unset the rating
|
|
||||||
if *input.Rating == 0 {
|
|
||||||
updatedScene.Rating = &sql.NullInt64{Int64: 0, Valid: false}
|
|
||||||
} else {
|
|
||||||
updatedScene.Rating = &sql.NullInt64{Int64: int64(*input.Rating), Valid: true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if input.StudioID != nil {
|
|
||||||
// empty string means unset the studio
|
|
||||||
if *input.StudioID == "" {
|
|
||||||
updatedScene.StudioID = &sql.NullInt64{Int64: 0, Valid: false}
|
|
||||||
} else {
|
|
||||||
studioID, _ := strconv.ParseInt(*input.StudioID, 10, 64)
|
|
||||||
updatedScene.StudioID = &sql.NullInt64{Int64: studioID, Valid: true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := []*models.Scene{}
|
ret := []*models.Scene{}
|
||||||
|
|
||||||
@@ -278,9 +257,12 @@ func (r *mutationResolver) BulkSceneUpdate(ctx context.Context, input models.Bul
|
|||||||
|
|
||||||
ret = append(ret, scene)
|
ret = append(ret, scene)
|
||||||
|
|
||||||
if input.GalleryID != nil {
|
if translator.hasField("gallery_id") {
|
||||||
// Save the gallery
|
// Save the gallery
|
||||||
galleryID, _ := strconv.Atoi(*input.GalleryID)
|
var galleryID int
|
||||||
|
if input.GalleryID != nil {
|
||||||
|
galleryID, _ = strconv.Atoi(*input.GalleryID)
|
||||||
|
}
|
||||||
updatedGallery := models.Gallery{
|
updatedGallery := models.Gallery{
|
||||||
ID: galleryID,
|
ID: galleryID,
|
||||||
SceneID: sql.NullInt64{Int64: int64(sceneID), Valid: true},
|
SceneID: sql.NullInt64{Int64: int64(sceneID), Valid: true},
|
||||||
@@ -295,7 +277,7 @@ func (r *mutationResolver) BulkSceneUpdate(ctx context.Context, input models.Bul
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the performers
|
// Save the performers
|
||||||
if wasFieldIncluded(ctx, "performer_ids") {
|
if translator.hasField("performer_ids") {
|
||||||
performerIDs, err := adjustScenePerformerIDs(tx, sceneID, *input.PerformerIds)
|
performerIDs, err := adjustScenePerformerIDs(tx, sceneID, *input.PerformerIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
@@ -317,7 +299,7 @@ func (r *mutationResolver) BulkSceneUpdate(ctx context.Context, input models.Bul
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the tags
|
// Save the tags
|
||||||
if wasFieldIncluded(ctx, "tag_ids") {
|
if translator.hasField("tag_ids") {
|
||||||
tagIDs, err := adjustSceneTagIDs(tx, sceneID, *input.TagIds)
|
tagIDs, err := adjustSceneTagIDs(tx, sceneID, *input.TagIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = tx.Rollback()
|
_ = tx.Rollback()
|
||||||
|
|||||||
@@ -89,13 +89,17 @@ func (r *mutationResolver) StudioUpdate(ctx context.Context, input models.Studio
|
|||||||
// Populate studio from the input
|
// Populate studio from the input
|
||||||
studioID, _ := strconv.Atoi(input.ID)
|
studioID, _ := strconv.Atoi(input.ID)
|
||||||
|
|
||||||
|
translator := changesetTranslator{
|
||||||
|
inputMap: getUpdateInputMap(ctx),
|
||||||
|
}
|
||||||
|
|
||||||
updatedStudio := models.StudioPartial{
|
updatedStudio := models.StudioPartial{
|
||||||
ID: studioID,
|
ID: studioID,
|
||||||
UpdatedAt: &models.SQLiteTimestamp{Timestamp: time.Now()},
|
UpdatedAt: &models.SQLiteTimestamp{Timestamp: time.Now()},
|
||||||
}
|
}
|
||||||
|
|
||||||
var imageData []byte
|
var imageData []byte
|
||||||
imageIncluded := wasFieldIncluded(ctx, "image")
|
imageIncluded := translator.hasField("image")
|
||||||
if input.Image != nil {
|
if input.Image != nil {
|
||||||
var err error
|
var err error
|
||||||
_, imageData, err = utils.ProcessBase64Image(*input.Image)
|
_, imageData, err = utils.ProcessBase64Image(*input.Image)
|
||||||
@@ -109,17 +113,9 @@ func (r *mutationResolver) StudioUpdate(ctx context.Context, input models.Studio
|
|||||||
updatedStudio.Name = &sql.NullString{String: *input.Name, Valid: true}
|
updatedStudio.Name = &sql.NullString{String: *input.Name, Valid: true}
|
||||||
updatedStudio.Checksum = &checksum
|
updatedStudio.Checksum = &checksum
|
||||||
}
|
}
|
||||||
if input.URL != nil {
|
|
||||||
updatedStudio.URL = &sql.NullString{String: *input.URL, Valid: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.ParentID != nil {
|
updatedStudio.URL = translator.nullString(input.URL, "url")
|
||||||
parentID, _ := strconv.ParseInt(*input.ParentID, 10, 64)
|
updatedStudio.ParentID = translator.nullInt64FromString(input.ParentID, "parent_id")
|
||||||
updatedStudio.ParentID = &sql.NullInt64{Int64: parentID, Valid: true}
|
|
||||||
} else {
|
|
||||||
// parent studio must be nullable
|
|
||||||
updatedStudio.ParentID = &sql.NullInt64{Valid: false}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the transaction and save the studio
|
// Start the transaction and save the studio
|
||||||
tx := database.DB.MustBeginTx(ctx, nil)
|
tx := database.DB.MustBeginTx(ctx, nil)
|
||||||
@@ -152,7 +148,7 @@ func (r *mutationResolver) StudioUpdate(ctx context.Context, input models.Studio
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the stash_ids
|
// Save the stash_ids
|
||||||
if input.StashIds != nil {
|
if translator.hasField("stash_ids") {
|
||||||
var stashIDJoins []models.StashID
|
var stashIDJoins []models.StashID
|
||||||
for _, stashID := range input.StashIds {
|
for _, stashID := range input.StashIds {
|
||||||
newJoin := models.StashID{
|
newJoin := models.StashID{
|
||||||
|
|||||||
@@ -76,7 +76,11 @@ func (r *mutationResolver) TagUpdate(ctx context.Context, input models.TagUpdate
|
|||||||
var imageData []byte
|
var imageData []byte
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
imageIncluded := wasFieldIncluded(ctx, "image")
|
translator := changesetTranslator{
|
||||||
|
inputMap: getUpdateInputMap(ctx),
|
||||||
|
}
|
||||||
|
|
||||||
|
imageIncluded := translator.hasField("image")
|
||||||
if input.Image != nil {
|
if input.Image != nil {
|
||||||
_, imageData, err = utils.ProcessBase64Image(*input.Image)
|
_, imageData, err = utils.ProcessBase64Image(*input.Image)
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,30 @@ func (_m *PerformerReaderWriter) GetPerformerImage(performerID int) ([]byte, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update provides a mock function with given fields: updatedPerformer
|
// Update provides a mock function with given fields: updatedPerformer
|
||||||
func (_m *PerformerReaderWriter) Update(updatedPerformer models.Performer) (*models.Performer, error) {
|
func (_m *PerformerReaderWriter) Update(updatedPerformer models.PerformerPartial) (*models.Performer, error) {
|
||||||
|
ret := _m.Called(updatedPerformer)
|
||||||
|
|
||||||
|
var r0 *models.Performer
|
||||||
|
if rf, ok := ret.Get(0).(func(models.PerformerPartial) *models.Performer); ok {
|
||||||
|
r0 = rf(updatedPerformer)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*models.Performer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(models.PerformerPartial) error); ok {
|
||||||
|
r1 = rf(updatedPerformer)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateFull provides a mock function with given fields: updatedPerformer
|
||||||
|
func (_m *PerformerReaderWriter) UpdateFull(updatedPerformer models.Performer) (*models.Performer, error) {
|
||||||
ret := _m.Called(updatedPerformer)
|
ret := _m.Called(updatedPerformer)
|
||||||
|
|
||||||
var r0 *models.Performer
|
var r0 *models.Performer
|
||||||
|
|||||||
@@ -31,6 +31,30 @@ type Performer struct {
|
|||||||
UpdatedAt SQLiteTimestamp `db:"updated_at" json:"updated_at"`
|
UpdatedAt SQLiteTimestamp `db:"updated_at" json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PerformerPartial struct {
|
||||||
|
ID int `db:"id" json:"id"`
|
||||||
|
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"`
|
||||||
|
Birthdate *SQLiteDate `db:"birthdate" json:"birthdate"`
|
||||||
|
Ethnicity *sql.NullString `db:"ethnicity" json:"ethnicity"`
|
||||||
|
Country *sql.NullString `db:"country" json:"country"`
|
||||||
|
EyeColor *sql.NullString `db:"eye_color" json:"eye_color"`
|
||||||
|
Height *sql.NullString `db:"height" json:"height"`
|
||||||
|
Measurements *sql.NullString `db:"measurements" json:"measurements"`
|
||||||
|
FakeTits *sql.NullString `db:"fake_tits" json:"fake_tits"`
|
||||||
|
CareerLength *sql.NullString `db:"career_length" json:"career_length"`
|
||||||
|
Tattoos *sql.NullString `db:"tattoos" json:"tattoos"`
|
||||||
|
Piercings *sql.NullString `db:"piercings" json:"piercings"`
|
||||||
|
Aliases *sql.NullString `db:"aliases" json:"aliases"`
|
||||||
|
Favorite *sql.NullBool `db:"favorite" json:"favorite"`
|
||||||
|
CreatedAt *SQLiteTimestamp `db:"created_at" json:"created_at"`
|
||||||
|
UpdatedAt *SQLiteTimestamp `db:"updated_at" json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
func NewPerformer(name string) *Performer {
|
func NewPerformer(name string) *Performer {
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
return &Performer{
|
return &Performer{
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ type PerformerReader interface {
|
|||||||
|
|
||||||
type PerformerWriter interface {
|
type PerformerWriter interface {
|
||||||
Create(newPerformer Performer) (*Performer, error)
|
Create(newPerformer Performer) (*Performer, error)
|
||||||
Update(updatedPerformer Performer) (*Performer, error)
|
Update(updatedPerformer PerformerPartial) (*Performer, error)
|
||||||
|
UpdateFull(updatedPerformer Performer) (*Performer, error)
|
||||||
// Destroy(id string) error
|
// Destroy(id string) error
|
||||||
UpdatePerformerImage(performerID int, image []byte) error
|
UpdatePerformerImage(performerID int, image []byte) error
|
||||||
// DestroyPerformerImage(performerID int) error
|
// DestroyPerformerImage(performerID int) error
|
||||||
@@ -80,10 +81,14 @@ func (t *performerReaderWriter) Create(newPerformer Performer) (*Performer, erro
|
|||||||
return t.qb.Create(newPerformer, t.tx)
|
return t.qb.Create(newPerformer, t.tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *performerReaderWriter) Update(updatedPerformer Performer) (*Performer, error) {
|
func (t *performerReaderWriter) Update(updatedPerformer PerformerPartial) (*Performer, error) {
|
||||||
return t.qb.Update(updatedPerformer, t.tx)
|
return t.qb.Update(updatedPerformer, t.tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *performerReaderWriter) UpdateFull(updatedPerformer Performer) (*Performer, error) {
|
||||||
|
return t.qb.UpdateFull(updatedPerformer, t.tx)
|
||||||
|
}
|
||||||
|
|
||||||
func (t *performerReaderWriter) UpdatePerformerImage(performerID int, image []byte) error {
|
func (t *performerReaderWriter) UpdatePerformerImage(performerID int, image []byte) error {
|
||||||
return t.qb.UpdatePerformerImage(performerID, image, t.tx)
|
return t.qb.UpdatePerformerImage(performerID, image, t.tx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,24 @@ func (qb *PerformerQueryBuilder) Create(newPerformer Performer, tx *sqlx.Tx) (*P
|
|||||||
return &newPerformer, nil
|
return &newPerformer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (qb *PerformerQueryBuilder) Update(updatedPerformer Performer, tx *sqlx.Tx) (*Performer, error) {
|
func (qb *PerformerQueryBuilder) Update(updatedPerformer PerformerPartial, tx *sqlx.Tx) (*Performer, error) {
|
||||||
|
ensureTx(tx)
|
||||||
|
_, err := tx.NamedExec(
|
||||||
|
`UPDATE performers SET `+SQLGenKeysPartial(updatedPerformer)+` WHERE performers.id = :id`,
|
||||||
|
updatedPerformer,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret Performer
|
||||||
|
if err := tx.Get(&ret, `SELECT * FROM performers WHERE id = ? LIMIT 1`, updatedPerformer.ID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (qb *PerformerQueryBuilder) UpdateFull(updatedPerformer Performer, tx *sqlx.Tx) (*Performer, error) {
|
||||||
ensureTx(tx)
|
ensureTx(tx)
|
||||||
_, err := tx.NamedExec(
|
_, err := tx.NamedExec(
|
||||||
`UPDATE performers SET `+SQLGenKeys(updatedPerformer)+` WHERE performers.id = :id`,
|
`UPDATE performers SET `+SQLGenKeys(updatedPerformer)+` WHERE performers.id = :id`,
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ func (i *Importer) Create() (*int, error) {
|
|||||||
func (i *Importer) Update(id int) error {
|
func (i *Importer) Update(id int) error {
|
||||||
performer := i.performer
|
performer := i.performer
|
||||||
performer.ID = id
|
performer.ID = id
|
||||||
_, err := i.ReaderWriter.Update(performer)
|
_, err := i.ReaderWriter.UpdateFull(performer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error updating existing performer: %s", err.Error())
|
return fmt.Errorf("error updating existing performer: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ func TestUpdate(t *testing.T) {
|
|||||||
|
|
||||||
// id needs to be set for the mock input
|
// id needs to be set for the mock input
|
||||||
performer.ID = performerID
|
performer.ID = performerID
|
||||||
readerWriter.On("Update", performer).Return(nil, nil).Once()
|
readerWriter.On("UpdateFull", performer).Return(nil, nil).Once()
|
||||||
|
|
||||||
err := i.Update(performerID)
|
err := i.Update(performerID)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
@@ -175,7 +175,7 @@ func TestUpdate(t *testing.T) {
|
|||||||
|
|
||||||
// need to set id separately
|
// need to set id separately
|
||||||
performerErr.ID = errImageID
|
performerErr.ID = errImageID
|
||||||
readerWriter.On("Update", performerErr).Return(nil, errUpdate).Once()
|
readerWriter.On("UpdateFull", performerErr).Return(nil, errUpdate).Once()
|
||||||
|
|
||||||
err = i.Update(errImageID)
|
err = i.Update(errImageID)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export const EditGalleriesDialog: React.FC<IListOperationProps> = (
|
|||||||
);
|
);
|
||||||
const [tagIds, setTagIds] = useState<string[]>();
|
const [tagIds, setTagIds] = useState<string[]>();
|
||||||
|
|
||||||
const [updateGalleries] = useBulkGalleryUpdate(getGalleryInput());
|
const [updateGalleries] = useBulkGalleryUpdate();
|
||||||
|
|
||||||
// Network state
|
// Network state
|
||||||
const [isUpdating, setIsUpdating] = useState(false);
|
const [isUpdating, setIsUpdating] = useState(false);
|
||||||
@@ -61,8 +61,8 @@ export const EditGalleriesDialog: React.FC<IListOperationProps> = (
|
|||||||
if (rating === undefined) {
|
if (rating === undefined) {
|
||||||
// and all galleries have the same rating, then we are unsetting the rating.
|
// and all galleries have the same rating, then we are unsetting the rating.
|
||||||
if (aggregateRating) {
|
if (aggregateRating) {
|
||||||
// an undefined rating is ignored in the server, so set it to 0 instead
|
// null to unset rating
|
||||||
galleryInput.rating = 0;
|
galleryInput.rating = null;
|
||||||
}
|
}
|
||||||
// otherwise not setting the rating
|
// otherwise not setting the rating
|
||||||
} else {
|
} else {
|
||||||
@@ -75,8 +75,8 @@ export const EditGalleriesDialog: React.FC<IListOperationProps> = (
|
|||||||
// and all galleries have the same studioId,
|
// and all galleries have the same studioId,
|
||||||
// then unset the studioId, otherwise ignoring studioId
|
// then unset the studioId, otherwise ignoring studioId
|
||||||
if (aggregateStudioId) {
|
if (aggregateStudioId) {
|
||||||
// an undefined studio_id is ignored in the server, so set it to empty string instead
|
// null to unset studio_id
|
||||||
galleryInput.studio_id = "";
|
galleryInput.studio_id = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if studioId is set, then we are setting it
|
// if studioId is set, then we are setting it
|
||||||
@@ -125,7 +125,11 @@ export const EditGalleriesDialog: React.FC<IListOperationProps> = (
|
|||||||
async function onSave() {
|
async function onSave() {
|
||||||
setIsUpdating(true);
|
setIsUpdating(true);
|
||||||
try {
|
try {
|
||||||
await updateGalleries();
|
await updateGalleries({
|
||||||
|
variables: {
|
||||||
|
input: getGalleryInput(),
|
||||||
|
},
|
||||||
|
});
|
||||||
Toast.success({ content: "Updated galleries" });
|
Toast.success({ content: "Updated galleries" });
|
||||||
props.onClose(true);
|
props.onClose(true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -63,9 +63,7 @@ export const GalleryEditPanel: React.FC<
|
|||||||
const [createGallery] = useGalleryCreate(
|
const [createGallery] = useGalleryCreate(
|
||||||
getGalleryInput() as GQL.GalleryCreateInput
|
getGalleryInput() as GQL.GalleryCreateInput
|
||||||
);
|
);
|
||||||
const [updateGallery] = useGalleryUpdate(
|
const [updateGallery] = useGalleryUpdate();
|
||||||
getGalleryInput() as GQL.GalleryUpdateInput
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.isVisible) {
|
if (props.isVisible) {
|
||||||
@@ -135,8 +133,8 @@ export const GalleryEditPanel: React.FC<
|
|||||||
details,
|
details,
|
||||||
url,
|
url,
|
||||||
date,
|
date,
|
||||||
rating,
|
rating: rating ?? null,
|
||||||
studio_id: studioId,
|
studio_id: studioId ?? null,
|
||||||
performer_ids: performerIds,
|
performer_ids: performerIds,
|
||||||
tag_ids: tagIds,
|
tag_ids: tagIds,
|
||||||
};
|
};
|
||||||
@@ -152,7 +150,11 @@ export const GalleryEditPanel: React.FC<
|
|||||||
Toast.success({ content: "Created gallery" });
|
Toast.success({ content: "Created gallery" });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const result = await updateGallery();
|
const result = await updateGallery({
|
||||||
|
variables: {
|
||||||
|
input: getGalleryInput() as GQL.GalleryUpdateInput,
|
||||||
|
},
|
||||||
|
});
|
||||||
if (result.data?.galleryUpdate) {
|
if (result.data?.galleryUpdate) {
|
||||||
Toast.success({ content: "Updated gallery" });
|
Toast.success({ content: "Updated gallery" });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export const EditImagesDialog: React.FC<IListOperationProps> = (
|
|||||||
);
|
);
|
||||||
const [tagIds, setTagIds] = useState<string[]>();
|
const [tagIds, setTagIds] = useState<string[]>();
|
||||||
|
|
||||||
const [updateImages] = useBulkImageUpdate(getImageInput());
|
const [updateImages] = useBulkImageUpdate();
|
||||||
|
|
||||||
// Network state
|
// Network state
|
||||||
const [isUpdating, setIsUpdating] = useState(false);
|
const [isUpdating, setIsUpdating] = useState(false);
|
||||||
@@ -61,8 +61,8 @@ export const EditImagesDialog: React.FC<IListOperationProps> = (
|
|||||||
if (rating === undefined) {
|
if (rating === undefined) {
|
||||||
// and all images have the same rating, then we are unsetting the rating.
|
// and all images have the same rating, then we are unsetting the rating.
|
||||||
if (aggregateRating) {
|
if (aggregateRating) {
|
||||||
// an undefined rating is ignored in the server, so set it to 0 instead
|
// null rating to unset it
|
||||||
imageInput.rating = 0;
|
imageInput.rating = null;
|
||||||
}
|
}
|
||||||
// otherwise not setting the rating
|
// otherwise not setting the rating
|
||||||
} else {
|
} else {
|
||||||
@@ -75,8 +75,8 @@ export const EditImagesDialog: React.FC<IListOperationProps> = (
|
|||||||
// and all images have the same studioId,
|
// and all images have the same studioId,
|
||||||
// then unset the studioId, otherwise ignoring studioId
|
// then unset the studioId, otherwise ignoring studioId
|
||||||
if (aggregateStudioId) {
|
if (aggregateStudioId) {
|
||||||
// an undefined studio_id is ignored in the server, so set it to empty string instead
|
// null studio_id to unset it
|
||||||
imageInput.studio_id = "";
|
imageInput.studio_id = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if studioId is set, then we are setting it
|
// if studioId is set, then we are setting it
|
||||||
@@ -125,7 +125,11 @@ export const EditImagesDialog: React.FC<IListOperationProps> = (
|
|||||||
async function onSave() {
|
async function onSave() {
|
||||||
setIsUpdating(true);
|
setIsUpdating(true);
|
||||||
try {
|
try {
|
||||||
await updateImages();
|
await updateImages({
|
||||||
|
variables: {
|
||||||
|
input: getImageInput(),
|
||||||
|
},
|
||||||
|
});
|
||||||
Toast.success({ content: "Updated images" });
|
Toast.success({ content: "Updated images" });
|
||||||
props.onClose(true);
|
props.onClose(true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const ImageEditPanel: React.FC<IProps> = (props: IProps) => {
|
|||||||
// Network state
|
// Network state
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
|
||||||
const [updateImage] = useImageUpdate(getImageInput());
|
const [updateImage] = useImageUpdate();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.isVisible) {
|
if (props.isVisible) {
|
||||||
@@ -95,8 +95,8 @@ export const ImageEditPanel: React.FC<IProps> = (props: IProps) => {
|
|||||||
return {
|
return {
|
||||||
id: props.image.id,
|
id: props.image.id,
|
||||||
title,
|
title,
|
||||||
rating,
|
rating: rating ?? null,
|
||||||
studio_id: studioId,
|
studio_id: studioId ?? null,
|
||||||
performer_ids: performerIds,
|
performer_ids: performerIds,
|
||||||
tag_ids: tagIds,
|
tag_ids: tagIds,
|
||||||
};
|
};
|
||||||
@@ -105,7 +105,11 @@ export const ImageEditPanel: React.FC<IProps> = (props: IProps) => {
|
|||||||
async function onSave() {
|
async function onSave() {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const result = await updateImage();
|
const result = await updateImage({
|
||||||
|
variables: {
|
||||||
|
input: getImageInput(),
|
||||||
|
},
|
||||||
|
});
|
||||||
if (result.data?.imageUpdate) {
|
if (result.data?.imageUpdate) {
|
||||||
Toast.success({ content: "Updated image" });
|
Toast.success({ content: "Updated image" });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export const Movie: React.FC = () => {
|
|||||||
// Network state
|
// Network state
|
||||||
const { data, error, loading } = useFindMovie(id);
|
const { data, error, loading } = useFindMovie(id);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [updateMovie] = useMovieUpdate(getMovieInput() as GQL.MovieUpdateInput);
|
const [updateMovie] = useMovieUpdate();
|
||||||
const [createMovie] = useMovieCreate(getMovieInput() as GQL.MovieCreateInput);
|
const [createMovie] = useMovieCreate(getMovieInput() as GQL.MovieCreateInput);
|
||||||
const [deleteMovie] = useMovieDestroy(
|
const [deleteMovie] = useMovieDestroy(
|
||||||
getMovieInput() as GQL.MovieDestroyInput
|
getMovieInput() as GQL.MovieDestroyInput
|
||||||
@@ -201,8 +201,8 @@ export const Movie: React.FC = () => {
|
|||||||
aliases,
|
aliases,
|
||||||
duration,
|
duration,
|
||||||
date,
|
date,
|
||||||
rating,
|
rating: rating ?? null,
|
||||||
studio_id: studioId,
|
studio_id: studioId ?? null,
|
||||||
director,
|
director,
|
||||||
synopsis,
|
synopsis,
|
||||||
url,
|
url,
|
||||||
@@ -219,7 +219,11 @@ export const Movie: React.FC = () => {
|
|||||||
async function onSave() {
|
async function onSave() {
|
||||||
try {
|
try {
|
||||||
if (!isNew) {
|
if (!isNew) {
|
||||||
const result = await updateMovie();
|
const result = await updateMovie({
|
||||||
|
variables: {
|
||||||
|
input: getMovieInput() as GQL.MovieUpdateInput,
|
||||||
|
},
|
||||||
|
});
|
||||||
if (result.data?.movieUpdate) {
|
if (result.data?.movieUpdate) {
|
||||||
updateMovieData(result.data.movieUpdate);
|
updateMovieData(result.data.movieUpdate);
|
||||||
setIsEditing(false);
|
setIsEditing(false);
|
||||||
|
|||||||
@@ -111,12 +111,14 @@ export const Performer: React.FC = () => {
|
|||||||
if (!isNew) {
|
if (!isNew) {
|
||||||
await updatePerformer({
|
await updatePerformer({
|
||||||
variables: {
|
variables: {
|
||||||
|
input: {
|
||||||
...performerInput,
|
...performerInput,
|
||||||
stash_ids: (performerInput?.stash_ids ?? []).map((s) => ({
|
stash_ids: performerInput?.stash_ids?.map((s) => ({
|
||||||
endpoint: s.endpoint,
|
endpoint: s.endpoint,
|
||||||
stash_id: s.stash_id,
|
stash_id: s.stash_id,
|
||||||
})),
|
})),
|
||||||
} as GQL.PerformerUpdateInput,
|
} as GQL.PerformerUpdateInput,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
if (performerInput.image) {
|
if (performerInput.image) {
|
||||||
// Refetch image to bust browser cache
|
// Refetch image to bust browser cache
|
||||||
@@ -215,7 +217,10 @@ export const Performer: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setFavorite(v: boolean) {
|
function setFavorite(v: boolean) {
|
||||||
onSave({ ...performer, favorite: v });
|
onSave({
|
||||||
|
id: performer.id,
|
||||||
|
favorite: v,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderIcons = () => (
|
const renderIcons = () => (
|
||||||
|
|||||||
@@ -61,8 +61,8 @@ export const EditScenesDialog: React.FC<IListOperationProps> = (
|
|||||||
if (rating === undefined) {
|
if (rating === undefined) {
|
||||||
// and all scenes have the same rating, then we are unsetting the rating.
|
// and all scenes have the same rating, then we are unsetting the rating.
|
||||||
if (aggregateRating) {
|
if (aggregateRating) {
|
||||||
// an undefined rating is ignored in the server, so set it to 0 instead
|
// null rating unsets it
|
||||||
sceneInput.rating = 0;
|
sceneInput.rating = null;
|
||||||
}
|
}
|
||||||
// otherwise not setting the rating
|
// otherwise not setting the rating
|
||||||
} else {
|
} else {
|
||||||
@@ -75,8 +75,8 @@ export const EditScenesDialog: React.FC<IListOperationProps> = (
|
|||||||
// and all scenes have the same studioId,
|
// and all scenes have the same studioId,
|
||||||
// then unset the studioId, otherwise ignoring studioId
|
// then unset the studioId, otherwise ignoring studioId
|
||||||
if (aggregateStudioId) {
|
if (aggregateStudioId) {
|
||||||
// an undefined studio_id is ignored in the server, so set it to empty string instead
|
// null studio_id unsets it
|
||||||
sceneInput.studio_id = "";
|
sceneInput.studio_id = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if studioId is set, then we are setting it
|
// if studioId is set, then we are setting it
|
||||||
|
|||||||
@@ -194,9 +194,9 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
|||||||
details,
|
details,
|
||||||
url,
|
url,
|
||||||
date,
|
date,
|
||||||
rating,
|
rating: rating ?? null,
|
||||||
gallery_id: galleryId,
|
gallery_id: galleryId ?? null,
|
||||||
studio_id: studioId,
|
studio_id: studioId ?? null,
|
||||||
performer_ids: performerIds,
|
performer_ids: performerIds,
|
||||||
movies: makeMovieInputs(),
|
movies: makeMovieInputs(),
|
||||||
tag_ids: tagIds,
|
tag_ids: tagIds,
|
||||||
|
|||||||
@@ -51,9 +51,7 @@ export const Studio: React.FC = () => {
|
|||||||
const [imagePreview, setImagePreview] = useState<string | null>();
|
const [imagePreview, setImagePreview] = useState<string | null>();
|
||||||
|
|
||||||
const { data, error, loading } = useFindStudio(id);
|
const { data, error, loading } = useFindStudio(id);
|
||||||
const [updateStudio] = useStudioUpdate(
|
const [updateStudio] = useStudioUpdate();
|
||||||
getStudioInput() as GQL.StudioUpdateInput
|
|
||||||
);
|
|
||||||
const [createStudio] = useStudioCreate(
|
const [createStudio] = useStudioCreate(
|
||||||
getStudioInput() as GQL.StudioCreateInput
|
getStudioInput() as GQL.StudioCreateInput
|
||||||
);
|
);
|
||||||
@@ -118,8 +116,8 @@ export const Studio: React.FC = () => {
|
|||||||
const input: Partial<GQL.StudioCreateInput | GQL.StudioUpdateInput> = {
|
const input: Partial<GQL.StudioCreateInput | GQL.StudioUpdateInput> = {
|
||||||
name,
|
name,
|
||||||
url,
|
url,
|
||||||
parent_id: parentStudioId,
|
parent_id: parentStudioId ?? null,
|
||||||
image,
|
image: image ?? null,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!isNew) {
|
if (!isNew) {
|
||||||
@@ -131,7 +129,11 @@ export const Studio: React.FC = () => {
|
|||||||
async function onSave() {
|
async function onSave() {
|
||||||
try {
|
try {
|
||||||
if (!isNew) {
|
if (!isNew) {
|
||||||
const result = await updateStudio();
|
const result = await updateStudio({
|
||||||
|
variables: {
|
||||||
|
input: getStudioInput() as GQL.StudioUpdateInput,
|
||||||
|
},
|
||||||
|
});
|
||||||
if (result.data?.studioUpdate) {
|
if (result.data?.studioUpdate) {
|
||||||
updateStudioData(result.data.studioUpdate);
|
updateStudioData(result.data.studioUpdate);
|
||||||
setIsEditing(false);
|
setIsEditing(false);
|
||||||
|
|||||||
@@ -279,20 +279,18 @@ const StashSearchResult: React.FC<IStashSearchResultProps> = ({
|
|||||||
|
|
||||||
const sceneUpdateResult = await updateScene({
|
const sceneUpdateResult = await updateScene({
|
||||||
variables: {
|
variables: {
|
||||||
|
input: {
|
||||||
id: stashScene.id ?? "",
|
id: stashScene.id ?? "",
|
||||||
title: scene.title,
|
title: scene.title,
|
||||||
details: scene.details,
|
details: scene.details,
|
||||||
date: scene.date,
|
date: scene.date,
|
||||||
performer_ids: performerIDs.filter((id) => id !== "Skip") as string[],
|
performer_ids: performerIDs.filter(
|
||||||
|
(id) => id !== "Skip"
|
||||||
|
) as string[],
|
||||||
studio_id: studioID,
|
studio_id: studioID,
|
||||||
cover_image: imgData,
|
cover_image: imgData,
|
||||||
url: scene.url,
|
url: scene.url,
|
||||||
tag_ids: updatedTags,
|
tag_ids: updatedTags,
|
||||||
rating: stashScene.rating,
|
|
||||||
movies: stashScene.movies.map((m) => ({
|
|
||||||
movie_id: m.movie.id,
|
|
||||||
scene_index: m.scene_index,
|
|
||||||
})),
|
|
||||||
stash_ids: [
|
stash_ids: [
|
||||||
...(stashScene?.stash_ids ?? []),
|
...(stashScene?.stash_ids ?? []),
|
||||||
{
|
{
|
||||||
@@ -301,6 +299,7 @@ const StashSearchResult: React.FC<IStashSearchResultProps> = ({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!sceneUpdateResult?.data?.sceneUpdate) {
|
if (!sceneUpdateResult?.data?.sceneUpdate) {
|
||||||
|
|||||||
@@ -12,12 +12,14 @@ export const useUpdatePerformerStashID = () => {
|
|||||||
) =>
|
) =>
|
||||||
updatePerformer({
|
updatePerformer({
|
||||||
variables: {
|
variables: {
|
||||||
|
input: {
|
||||||
id: performerID,
|
id: performerID,
|
||||||
stash_ids: stashIDs.map((s) => ({
|
stash_ids: stashIDs.map((s) => ({
|
||||||
stash_id: s.stash_id,
|
stash_id: s.stash_id,
|
||||||
endpoint: s.endpoint,
|
endpoint: s.endpoint,
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
|
},
|
||||||
update: (store, updatedPerformer) => {
|
update: (store, updatedPerformer) => {
|
||||||
if (!updatedPerformer.data?.performerUpdate) return;
|
if (!updatedPerformer.data?.performerUpdate) return;
|
||||||
const newStashID = stashIDs[stashIDs.length - 1].stash_id;
|
const newStashID = stashIDs[stashIDs.length - 1].stash_id;
|
||||||
@@ -117,13 +119,14 @@ export const useUpdateStudioStashID = () => {
|
|||||||
) =>
|
) =>
|
||||||
updateStudio({
|
updateStudio({
|
||||||
variables: {
|
variables: {
|
||||||
|
input: {
|
||||||
id: studio.id,
|
id: studio.id,
|
||||||
parent_id: studio.parent_studio?.id,
|
|
||||||
stash_ids: stashIDs.map((s) => ({
|
stash_ids: stashIDs.map((s) => ({
|
||||||
stash_id: s.stash_id,
|
stash_id: s.stash_id,
|
||||||
endpoint: s.endpoint,
|
endpoint: s.endpoint,
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
|
},
|
||||||
update: (store, result) => {
|
update: (store, result) => {
|
||||||
if (!result.data?.studioUpdate) return;
|
if (!result.data?.studioUpdate) return;
|
||||||
const newStashID = stashIDs[stashIDs.length - 1].stash_id;
|
const newStashID = stashIDs[stashIDs.length - 1].stash_id;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export const Tag: React.FC = () => {
|
|||||||
const [imagePreview, setImagePreview] = useState<string>();
|
const [imagePreview, setImagePreview] = useState<string>();
|
||||||
|
|
||||||
const { data, error, loading } = useFindTag(id);
|
const { data, error, loading } = useFindTag(id);
|
||||||
const [updateTag] = useTagUpdate(getTagInput() as GQL.TagUpdateInput);
|
const [updateTag] = useTagUpdate();
|
||||||
const [createTag] = useTagCreate(getTagInput() as GQL.TagUpdateInput);
|
const [createTag] = useTagCreate(getTagInput() as GQL.TagUpdateInput);
|
||||||
const [deleteTag] = useTagDestroy(getTagInput() as GQL.TagUpdateInput);
|
const [deleteTag] = useTagDestroy(getTagInput() as GQL.TagUpdateInput);
|
||||||
|
|
||||||
@@ -127,7 +127,11 @@ export const Tag: React.FC = () => {
|
|||||||
async function onSave() {
|
async function onSave() {
|
||||||
try {
|
try {
|
||||||
if (!isNew) {
|
if (!isNew) {
|
||||||
const result = await updateTag();
|
const result = await updateTag({
|
||||||
|
variables: {
|
||||||
|
input: getTagInput() as GQL.TagUpdateInput,
|
||||||
|
},
|
||||||
|
});
|
||||||
if (result.data?.tagUpdate) {
|
if (result.data?.tagUpdate) {
|
||||||
updateTagData(result.data.tagUpdate);
|
updateTagData(result.data.tagUpdate);
|
||||||
setIsEditing(false);
|
setIsEditing(false);
|
||||||
|
|||||||
@@ -325,13 +325,17 @@ const sceneMutationImpactedQueries = [
|
|||||||
|
|
||||||
export const useSceneUpdate = (input: GQL.SceneUpdateInput) =>
|
export const useSceneUpdate = (input: GQL.SceneUpdateInput) =>
|
||||||
GQL.useSceneUpdateMutation({
|
GQL.useSceneUpdateMutation({
|
||||||
variables: input,
|
variables: {
|
||||||
|
input,
|
||||||
|
},
|
||||||
update: deleteCache(sceneMutationImpactedQueries),
|
update: deleteCache(sceneMutationImpactedQueries),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const useBulkSceneUpdate = (input: GQL.BulkSceneUpdateInput) =>
|
export const useBulkSceneUpdate = (input: GQL.BulkSceneUpdateInput) =>
|
||||||
GQL.useBulkSceneUpdateMutation({
|
GQL.useBulkSceneUpdateMutation({
|
||||||
variables: input,
|
variables: {
|
||||||
|
input,
|
||||||
|
},
|
||||||
update: deleteCache(sceneMutationImpactedQueries),
|
update: deleteCache(sceneMutationImpactedQueries),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -419,15 +423,13 @@ const imageMutationImpactedQueries = [
|
|||||||
GQL.FindGalleriesDocument,
|
GQL.FindGalleriesDocument,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const useImageUpdate = (input: GQL.ImageUpdateInput) =>
|
export const useImageUpdate = () =>
|
||||||
GQL.useImageUpdateMutation({
|
GQL.useImageUpdateMutation({
|
||||||
variables: input,
|
|
||||||
update: deleteCache(imageMutationImpactedQueries),
|
update: deleteCache(imageMutationImpactedQueries),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const useBulkImageUpdate = (input: GQL.BulkImageUpdateInput) =>
|
export const useBulkImageUpdate = () =>
|
||||||
GQL.useBulkImageUpdateMutation({
|
GQL.useBulkImageUpdateMutation({
|
||||||
variables: input,
|
|
||||||
update: deleteCache(imageMutationImpactedQueries),
|
update: deleteCache(imageMutationImpactedQueries),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -506,15 +508,13 @@ export const useGalleryCreate = (input: GQL.GalleryCreateInput) =>
|
|||||||
update: deleteCache(galleryMutationImpactedQueries),
|
update: deleteCache(galleryMutationImpactedQueries),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const useGalleryUpdate = (input: GQL.GalleryUpdateInput) =>
|
export const useGalleryUpdate = () =>
|
||||||
GQL.useGalleryUpdateMutation({
|
GQL.useGalleryUpdateMutation({
|
||||||
variables: input,
|
|
||||||
update: deleteCache(galleryMutationImpactedQueries),
|
update: deleteCache(galleryMutationImpactedQueries),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const useBulkGalleryUpdate = (input: GQL.BulkGalleryUpdateInput) =>
|
export const useBulkGalleryUpdate = () =>
|
||||||
GQL.useBulkGalleryUpdateMutation({
|
GQL.useBulkGalleryUpdateMutation({
|
||||||
variables: input,
|
|
||||||
update: deleteCache(galleryMutationImpactedQueries),
|
update: deleteCache(galleryMutationImpactedQueries),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -555,9 +555,8 @@ export const useStudioCreate = (input: GQL.StudioCreateInput) =>
|
|||||||
]),
|
]),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const useStudioUpdate = (input: GQL.StudioUpdateInput) =>
|
export const useStudioUpdate = () =>
|
||||||
GQL.useStudioUpdateMutation({
|
GQL.useStudioUpdateMutation({
|
||||||
variables: input,
|
|
||||||
update: deleteCache(studioMutationImpactedQueries),
|
update: deleteCache(studioMutationImpactedQueries),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -583,9 +582,8 @@ export const useMovieCreate = (input: GQL.MovieCreateInput) =>
|
|||||||
]),
|
]),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const useMovieUpdate = (input: GQL.MovieUpdateInput) =>
|
export const useMovieUpdate = () =>
|
||||||
GQL.useMovieUpdateMutation({
|
GQL.useMovieUpdateMutation({
|
||||||
variables: input,
|
|
||||||
update: deleteCache(movieMutationImpactedQueries),
|
update: deleteCache(movieMutationImpactedQueries),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -618,9 +616,8 @@ export const useTagCreate = (input: GQL.TagCreateInput) =>
|
|||||||
GQL.AllTagsForFilterDocument,
|
GQL.AllTagsForFilterDocument,
|
||||||
]),
|
]),
|
||||||
});
|
});
|
||||||
export const useTagUpdate = (input: GQL.TagUpdateInput) =>
|
export const useTagUpdate = () =>
|
||||||
GQL.useTagUpdateMutation({
|
GQL.useTagUpdateMutation({
|
||||||
variables: input,
|
|
||||||
update: deleteCache(tagMutationImpactedQueries),
|
update: deleteCache(tagMutationImpactedQueries),
|
||||||
});
|
});
|
||||||
export const useTagDestroy = (input: GQL.TagDestroyInput) =>
|
export const useTagDestroy = (input: GQL.TagDestroyInput) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user