SQLite model refactoring (#3791)

* Remove ID from PerformerPartial
* Separate studio model from sqlite model
* Separate movie model from sqlite model
* Separate tag model from sqlite model
* Separate saved filter model from sqlite model
* Separate scene marker model from sqlite model
* Separate gallery chapter model from sqlite model
* Move ErrNoRows checks into sqlite, improve empty result error messages
* Move SQLiteDate and SQLiteTimestamp to sqlite
* Use changesetTranslator everywhere, refactor for consistency
* Make PerformerStore.DestroyImage private
* Fix rating on movie create
This commit is contained in:
DingDongSoLong4
2023-06-15 04:46:09 +02:00
committed by GitHub
parent 9180a68c45
commit 1c13c9e1b1
150 changed files with 3279 additions and 3129 deletions

View File

@@ -2,7 +2,7 @@ package api
import (
"context"
"database/sql"
"fmt"
"strconv"
"time"
@@ -28,69 +28,54 @@ func (r *mutationResolver) getStudio(ctx context.Context, id int) (ret *models.S
}
func (r *mutationResolver) StudioCreate(ctx context.Context, input StudioCreateInput) (*models.Studio, error) {
translator := changesetTranslator{
inputMap: getUpdateInputMap(ctx),
}
// generate checksum from studio name rather than image
checksum := md5.FromString(input.Name)
var imageData []byte
// Populate a new studio from the input
currentTime := time.Now()
newStudio := models.Studio{
Checksum: checksum,
Name: input.Name,
CreatedAt: currentTime,
UpdatedAt: currentTime,
URL: translator.string(input.URL, "url"),
Rating: translator.ratingConversionInt(input.Rating, input.Rating100),
Details: translator.string(input.Details, "details"),
IgnoreAutoTag: translator.bool(input.IgnoreAutoTag, "ignore_auto_tag"),
}
var err error
newStudio.ParentID, err = translator.intPtrFromString(input.ParentID, "parent_id")
if err != nil {
return nil, fmt.Errorf("converting parent id: %w", err)
}
// Process the base 64 encoded image string
if input.Image != nil {
var imageData []byte
if input.Image != nil && *input.Image != "" {
imageData, err = utils.ProcessImageInput(ctx, *input.Image)
if err != nil {
return nil, err
}
}
// Populate a new studio from the input
currentTime := time.Now()
newStudio := models.Studio{
Checksum: checksum,
Name: sql.NullString{String: input.Name, Valid: true},
CreatedAt: models.SQLiteTimestamp{Timestamp: currentTime},
UpdatedAt: models.SQLiteTimestamp{Timestamp: currentTime},
}
if input.URL != nil {
newStudio.URL = sql.NullString{String: *input.URL, Valid: true}
}
if input.ParentID != nil {
parentID, _ := strconv.ParseInt(*input.ParentID, 10, 64)
newStudio.ParentID = sql.NullInt64{Int64: parentID, Valid: true}
}
if input.Rating100 != nil {
newStudio.Rating = sql.NullInt64{
Int64: int64(*input.Rating100),
Valid: true,
}
} else if input.Rating != nil {
newStudio.Rating = sql.NullInt64{
Int64: int64(models.Rating5To100(*input.Rating)),
Valid: true,
}
}
if input.Details != nil {
newStudio.Details = sql.NullString{String: *input.Details, Valid: true}
}
if input.IgnoreAutoTag != nil {
newStudio.IgnoreAutoTag = *input.IgnoreAutoTag
}
// Start the transaction and save the studio
var s *models.Studio
if err := r.withTxn(ctx, func(ctx context.Context) error {
qb := r.repository.Studio
var err error
s, err = qb.Create(ctx, newStudio)
err = qb.Create(ctx, &newStudio)
if err != nil {
return err
}
// update image table
if len(imageData) > 0 {
if err := qb.UpdateImage(ctx, s.ID, imageData); err != nil {
if err := qb.UpdateImage(ctx, newStudio.ID, imageData); err != nil {
return err
}
}
@@ -98,17 +83,17 @@ func (r *mutationResolver) StudioCreate(ctx context.Context, input StudioCreateI
// Save the stash_ids
if input.StashIds != nil {
stashIDJoins := stashIDPtrSliceToSlice(input.StashIds)
if err := qb.UpdateStashIDs(ctx, s.ID, stashIDJoins); err != nil {
if err := qb.UpdateStashIDs(ctx, newStudio.ID, stashIDJoins); err != nil {
return err
}
}
if len(input.Aliases) > 0 {
if err := studio.EnsureAliasesUnique(ctx, s.ID, input.Aliases, qb); err != nil {
if err := studio.EnsureAliasesUnique(ctx, newStudio.ID, input.Aliases, qb); err != nil {
return err
}
if err := qb.UpdateAliases(ctx, s.ID, input.Aliases); err != nil {
if err := qb.UpdateAliases(ctx, newStudio.ID, input.Aliases); err != nil {
return err
}
}
@@ -118,12 +103,11 @@ func (r *mutationResolver) StudioCreate(ctx context.Context, input StudioCreateI
return nil, err
}
r.hookExecutor.ExecutePostHooks(ctx, s.ID, plugin.StudioCreatePost, input, nil)
return r.getStudio(ctx, s.ID)
r.hookExecutor.ExecutePostHooks(ctx, newStudio.ID, plugin.StudioCreatePost, input, nil)
return r.getStudio(ctx, newStudio.ID)
}
func (r *mutationResolver) StudioUpdate(ctx context.Context, input StudioUpdateInput) (*models.Studio, error) {
// Populate studio from the input
studioID, err := strconv.Atoi(input.ID)
if err != nil {
return nil, err
@@ -133,44 +117,45 @@ func (r *mutationResolver) StudioUpdate(ctx context.Context, input StudioUpdateI
inputMap: getUpdateInputMap(ctx),
}
updatedStudio := models.StudioPartial{
ID: studioID,
UpdatedAt: &models.SQLiteTimestamp{Timestamp: time.Now()},
// Populate studio from the input
updatedStudio := models.NewStudioPartial()
if input.Name != nil {
// generate checksum from studio name rather than image
checksum := md5.FromString(*input.Name)
updatedStudio.Name = models.NewOptionalString(*input.Name)
updatedStudio.Checksum = models.NewOptionalString(checksum)
}
updatedStudio.URL = translator.optionalString(input.URL, "url")
updatedStudio.Details = translator.optionalString(input.Details, "details")
updatedStudio.Rating = translator.ratingConversionOptional(input.Rating, input.Rating100)
updatedStudio.IgnoreAutoTag = translator.optionalBool(input.IgnoreAutoTag, "ignore_auto_tag")
updatedStudio.ParentID, err = translator.optionalIntFromString(input.ParentID, "parent_id")
if err != nil {
return nil, fmt.Errorf("converting parent id: %w", err)
}
var imageData []byte
imageIncluded := translator.hasField("image")
if input.Image != nil {
var err error
imageData, err = utils.ProcessImageInput(ctx, *input.Image)
if err != nil {
return nil, err
}
}
if input.Name != nil {
// generate checksum from studio name rather than image
checksum := md5.FromString(*input.Name)
updatedStudio.Name = &sql.NullString{String: *input.Name, Valid: true}
updatedStudio.Checksum = &checksum
}
updatedStudio.URL = translator.nullString(input.URL, "url")
updatedStudio.Details = translator.nullString(input.Details, "details")
updatedStudio.ParentID = translator.nullInt64FromString(input.ParentID, "parent_id")
updatedStudio.Rating = translator.ratingConversion(input.Rating, input.Rating100)
updatedStudio.IgnoreAutoTag = input.IgnoreAutoTag
// Start the transaction and save the studio
var s *models.Studio
if err := r.withTxn(ctx, func(ctx context.Context) error {
qb := r.repository.Studio
if err := manager.ValidateModifyStudio(ctx, updatedStudio, qb); err != nil {
if err := manager.ValidateModifyStudio(ctx, studioID, updatedStudio, qb); err != nil {
return err
}
var err error
s, err = qb.Update(ctx, updatedStudio)
s, err = qb.UpdatePartial(ctx, studioID, updatedStudio)
if err != nil {
return err
}