mirror of https://github.com/stashapp/stash.git
604 lines
19 KiB
Go
604 lines
19 KiB
Go
package sqlite
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/stashapp/stash/pkg/models"
|
|
)
|
|
|
|
const galleryTable = "galleries"
|
|
|
|
const performersGalleriesTable = "performers_galleries"
|
|
const galleriesTagsTable = "galleries_tags"
|
|
const galleriesImagesTable = "galleries_images"
|
|
const galleriesScenesTable = "scenes_galleries"
|
|
const galleryIDColumn = "gallery_id"
|
|
|
|
type galleryQueryBuilder struct {
|
|
repository
|
|
}
|
|
|
|
func NewGalleryReaderWriter(tx dbi) *galleryQueryBuilder {
|
|
return &galleryQueryBuilder{
|
|
repository{
|
|
tx: tx,
|
|
tableName: galleryTable,
|
|
idColumn: idColumn,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) Create(newObject models.Gallery) (*models.Gallery, error) {
|
|
var ret models.Gallery
|
|
if err := qb.insertObject(newObject, &ret); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &ret, nil
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) Update(updatedObject models.Gallery) (*models.Gallery, error) {
|
|
const partial = false
|
|
if err := qb.update(updatedObject.ID, updatedObject, partial); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return qb.Find(updatedObject.ID)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) UpdatePartial(updatedObject models.GalleryPartial) (*models.Gallery, error) {
|
|
const partial = true
|
|
if err := qb.update(updatedObject.ID, updatedObject, partial); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return qb.Find(updatedObject.ID)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) UpdateChecksum(id int, checksum string) error {
|
|
return qb.updateMap(id, map[string]interface{}{
|
|
"checksum": checksum,
|
|
})
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) UpdateFileModTime(id int, modTime models.NullSQLiteTimestamp) error {
|
|
return qb.updateMap(id, map[string]interface{}{
|
|
"file_mod_time": modTime,
|
|
})
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) Destroy(id int) error {
|
|
return qb.destroyExisting([]int{id})
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) Find(id int) (*models.Gallery, error) {
|
|
var ret models.Gallery
|
|
if err := qb.get(id, &ret); err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
return &ret, nil
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) FindMany(ids []int) ([]*models.Gallery, error) {
|
|
var galleries []*models.Gallery
|
|
for _, id := range ids {
|
|
gallery, err := qb.Find(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if gallery == nil {
|
|
return nil, fmt.Errorf("gallery with id %d not found", id)
|
|
}
|
|
|
|
galleries = append(galleries, gallery)
|
|
}
|
|
|
|
return galleries, nil
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) FindByChecksum(checksum string) (*models.Gallery, error) {
|
|
query := "SELECT * FROM galleries WHERE checksum = ? LIMIT 1"
|
|
args := []interface{}{checksum}
|
|
return qb.queryGallery(query, args)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) FindByChecksums(checksums []string) ([]*models.Gallery, error) {
|
|
query := "SELECT * FROM galleries WHERE checksum IN " + getInBinding(len(checksums))
|
|
var args []interface{}
|
|
for _, checksum := range checksums {
|
|
args = append(args, checksum)
|
|
}
|
|
return qb.queryGalleries(query, args)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) FindByPath(path string) (*models.Gallery, error) {
|
|
query := "SELECT * FROM galleries WHERE path = ? LIMIT 1"
|
|
args := []interface{}{path}
|
|
return qb.queryGallery(query, args)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) FindBySceneID(sceneID int) ([]*models.Gallery, error) {
|
|
query := selectAll(galleryTable) + `
|
|
LEFT JOIN scenes_galleries as scenes_join on scenes_join.gallery_id = galleries.id
|
|
WHERE scenes_join.scene_id = ?
|
|
GROUP BY galleries.id
|
|
`
|
|
args := []interface{}{sceneID}
|
|
return qb.queryGalleries(query, args)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) FindByImageID(imageID int) ([]*models.Gallery, error) {
|
|
query := selectAll(galleryTable) + `
|
|
INNER JOIN galleries_images as images_join on images_join.gallery_id = galleries.id
|
|
WHERE images_join.image_id = ?
|
|
GROUP BY galleries.id
|
|
`
|
|
args := []interface{}{imageID}
|
|
return qb.queryGalleries(query, args)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) CountByImageID(imageID int) (int, error) {
|
|
query := `SELECT image_id FROM galleries_images
|
|
WHERE image_id = ?
|
|
GROUP BY gallery_id`
|
|
args := []interface{}{imageID}
|
|
return qb.runCountQuery(qb.buildCountQuery(query), args)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) Count() (int, error) {
|
|
return qb.runCountQuery(qb.buildCountQuery("SELECT galleries.id FROM galleries"), nil)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) All() ([]*models.Gallery, error) {
|
|
return qb.queryGalleries(selectAll("galleries")+qb.getGallerySort(nil), nil)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) validateFilter(galleryFilter *models.GalleryFilterType) error {
|
|
const and = "AND"
|
|
const or = "OR"
|
|
const not = "NOT"
|
|
|
|
if galleryFilter.And != nil {
|
|
if galleryFilter.Or != nil {
|
|
return illegalFilterCombination(and, or)
|
|
}
|
|
if galleryFilter.Not != nil {
|
|
return illegalFilterCombination(and, not)
|
|
}
|
|
|
|
return qb.validateFilter(galleryFilter.And)
|
|
}
|
|
|
|
if galleryFilter.Or != nil {
|
|
if galleryFilter.Not != nil {
|
|
return illegalFilterCombination(or, not)
|
|
}
|
|
|
|
return qb.validateFilter(galleryFilter.Or)
|
|
}
|
|
|
|
if galleryFilter.Not != nil {
|
|
return qb.validateFilter(galleryFilter.Not)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) makeFilter(galleryFilter *models.GalleryFilterType) *filterBuilder {
|
|
query := &filterBuilder{}
|
|
|
|
if galleryFilter.And != nil {
|
|
query.and(qb.makeFilter(galleryFilter.And))
|
|
}
|
|
if galleryFilter.Or != nil {
|
|
query.or(qb.makeFilter(galleryFilter.Or))
|
|
}
|
|
if galleryFilter.Not != nil {
|
|
query.not(qb.makeFilter(galleryFilter.Not))
|
|
}
|
|
|
|
query.handleCriterion(stringCriterionHandler(galleryFilter.Title, "galleries.title"))
|
|
query.handleCriterion(stringCriterionHandler(galleryFilter.Details, "galleries.details"))
|
|
query.handleCriterion(stringCriterionHandler(galleryFilter.Checksum, "galleries.checksum"))
|
|
query.handleCriterion(boolCriterionHandler(galleryFilter.IsZip, "galleries.zip"))
|
|
query.handleCriterion(stringCriterionHandler(galleryFilter.Path, "galleries.path"))
|
|
query.handleCriterion(intCriterionHandler(galleryFilter.Rating, "galleries.rating"))
|
|
query.handleCriterion(stringCriterionHandler(galleryFilter.URL, "galleries.url"))
|
|
query.handleCriterion(boolCriterionHandler(galleryFilter.Organized, "galleries.organized"))
|
|
query.handleCriterion(galleryIsMissingCriterionHandler(qb, galleryFilter.IsMissing))
|
|
query.handleCriterion(galleryTagsCriterionHandler(qb, galleryFilter.Tags))
|
|
query.handleCriterion(galleryTagCountCriterionHandler(qb, galleryFilter.TagCount))
|
|
query.handleCriterion(galleryPerformersCriterionHandler(qb, galleryFilter.Performers))
|
|
query.handleCriterion(galleryPerformerCountCriterionHandler(qb, galleryFilter.PerformerCount))
|
|
query.handleCriterion(galleryStudioCriterionHandler(qb, galleryFilter.Studios))
|
|
query.handleCriterion(galleryPerformerTagsCriterionHandler(qb, galleryFilter.PerformerTags))
|
|
query.handleCriterion(galleryAverageResolutionCriterionHandler(qb, galleryFilter.AverageResolution))
|
|
query.handleCriterion(galleryImageCountCriterionHandler(qb, galleryFilter.ImageCount))
|
|
query.handleCriterion(galleryPerformerFavoriteCriterionHandler(galleryFilter.PerformerFavorite))
|
|
query.handleCriterion(galleryPerformerAgeCriterionHandler(galleryFilter.PerformerAge))
|
|
|
|
return query
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) makeQuery(galleryFilter *models.GalleryFilterType, findFilter *models.FindFilterType) (*queryBuilder, error) {
|
|
if galleryFilter == nil {
|
|
galleryFilter = &models.GalleryFilterType{}
|
|
}
|
|
if findFilter == nil {
|
|
findFilter = &models.FindFilterType{}
|
|
}
|
|
|
|
query := qb.newQuery()
|
|
distinctIDs(&query, galleryTable)
|
|
|
|
if q := findFilter.Q; q != nil && *q != "" {
|
|
searchColumns := []string{"galleries.title", "galleries.path", "galleries.checksum"}
|
|
query.parseQueryString(searchColumns, *q)
|
|
}
|
|
|
|
if err := qb.validateFilter(galleryFilter); err != nil {
|
|
return nil, err
|
|
}
|
|
filter := qb.makeFilter(galleryFilter)
|
|
|
|
query.addFilter(filter)
|
|
|
|
query.sortAndPagination = qb.getGallerySort(findFilter) + getPagination(findFilter)
|
|
|
|
return &query, nil
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) Query(galleryFilter *models.GalleryFilterType, findFilter *models.FindFilterType) ([]*models.Gallery, int, error) {
|
|
query, err := qb.makeQuery(galleryFilter, findFilter)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
idsResult, countResult, err := query.executeFind()
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
var galleries []*models.Gallery
|
|
for _, id := range idsResult {
|
|
gallery, err := qb.Find(id)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
galleries = append(galleries, gallery)
|
|
}
|
|
|
|
return galleries, countResult, nil
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) QueryCount(galleryFilter *models.GalleryFilterType, findFilter *models.FindFilterType) (int, error) {
|
|
query, err := qb.makeQuery(galleryFilter, findFilter)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return query.executeCount()
|
|
}
|
|
|
|
func galleryIsMissingCriterionHandler(qb *galleryQueryBuilder, isMissing *string) criterionHandlerFunc {
|
|
return func(f *filterBuilder) {
|
|
if isMissing != nil && *isMissing != "" {
|
|
switch *isMissing {
|
|
case "scenes":
|
|
f.addLeftJoin("scenes_galleries", "scenes_join", "scenes_join.gallery_id = galleries.id")
|
|
f.addWhere("scenes_join.gallery_id IS NULL")
|
|
case "studio":
|
|
f.addWhere("galleries.studio_id IS NULL")
|
|
case "performers":
|
|
qb.performersRepository().join(f, "performers_join", "galleries.id")
|
|
f.addWhere("performers_join.gallery_id IS NULL")
|
|
case "date":
|
|
f.addWhere("galleries.date IS NULL OR galleries.date IS \"\" OR galleries.date IS \"0001-01-01\"")
|
|
case "tags":
|
|
qb.tagsRepository().join(f, "tags_join", "galleries.id")
|
|
f.addWhere("tags_join.gallery_id IS NULL")
|
|
default:
|
|
f.addWhere("(galleries." + *isMissing + " IS NULL OR TRIM(galleries." + *isMissing + ") = '')")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func galleryTagsCriterionHandler(qb *galleryQueryBuilder, tags *models.HierarchicalMultiCriterionInput) criterionHandlerFunc {
|
|
h := joinedHierarchicalMultiCriterionHandlerBuilder{
|
|
tx: qb.tx,
|
|
|
|
primaryTable: galleryTable,
|
|
foreignTable: tagTable,
|
|
foreignFK: "tag_id",
|
|
|
|
relationsTable: "tags_relations",
|
|
joinAs: "image_tag",
|
|
joinTable: galleriesTagsTable,
|
|
primaryFK: galleryIDColumn,
|
|
}
|
|
|
|
return h.handler(tags)
|
|
}
|
|
|
|
func galleryTagCountCriterionHandler(qb *galleryQueryBuilder, tagCount *models.IntCriterionInput) criterionHandlerFunc {
|
|
h := countCriterionHandlerBuilder{
|
|
primaryTable: galleryTable,
|
|
joinTable: galleriesTagsTable,
|
|
primaryFK: galleryIDColumn,
|
|
}
|
|
|
|
return h.handler(tagCount)
|
|
}
|
|
|
|
func galleryPerformersCriterionHandler(qb *galleryQueryBuilder, performers *models.MultiCriterionInput) criterionHandlerFunc {
|
|
h := joinedMultiCriterionHandlerBuilder{
|
|
primaryTable: galleryTable,
|
|
joinTable: performersGalleriesTable,
|
|
joinAs: "performers_join",
|
|
primaryFK: galleryIDColumn,
|
|
foreignFK: performerIDColumn,
|
|
|
|
addJoinTable: func(f *filterBuilder) {
|
|
qb.performersRepository().join(f, "performers_join", "galleries.id")
|
|
},
|
|
}
|
|
|
|
return h.handler(performers)
|
|
}
|
|
|
|
func galleryPerformerCountCriterionHandler(qb *galleryQueryBuilder, performerCount *models.IntCriterionInput) criterionHandlerFunc {
|
|
h := countCriterionHandlerBuilder{
|
|
primaryTable: galleryTable,
|
|
joinTable: performersGalleriesTable,
|
|
primaryFK: galleryIDColumn,
|
|
}
|
|
|
|
return h.handler(performerCount)
|
|
}
|
|
|
|
func galleryImageCountCriterionHandler(qb *galleryQueryBuilder, imageCount *models.IntCriterionInput) criterionHandlerFunc {
|
|
h := countCriterionHandlerBuilder{
|
|
primaryTable: galleryTable,
|
|
joinTable: galleriesImagesTable,
|
|
primaryFK: galleryIDColumn,
|
|
}
|
|
|
|
return h.handler(imageCount)
|
|
}
|
|
|
|
func galleryStudioCriterionHandler(qb *galleryQueryBuilder, studios *models.HierarchicalMultiCriterionInput) criterionHandlerFunc {
|
|
h := hierarchicalMultiCriterionHandlerBuilder{
|
|
tx: qb.tx,
|
|
|
|
primaryTable: galleryTable,
|
|
foreignTable: studioTable,
|
|
foreignFK: studioIDColumn,
|
|
derivedTable: "studio",
|
|
parentFK: "parent_id",
|
|
}
|
|
|
|
return h.handler(studios)
|
|
}
|
|
|
|
func galleryPerformerTagsCriterionHandler(qb *galleryQueryBuilder, tags *models.HierarchicalMultiCriterionInput) criterionHandlerFunc {
|
|
return func(f *filterBuilder) {
|
|
if tags != nil {
|
|
if tags.Modifier == models.CriterionModifierIsNull || tags.Modifier == models.CriterionModifierNotNull {
|
|
var notClause string
|
|
if tags.Modifier == models.CriterionModifierNotNull {
|
|
notClause = "NOT"
|
|
}
|
|
|
|
f.addLeftJoin("performers_galleries", "", "galleries.id = performers_galleries.gallery_id")
|
|
f.addLeftJoin("performers_tags", "", "performers_galleries.performer_id = performers_tags.performer_id")
|
|
|
|
f.addWhere(fmt.Sprintf("performers_tags.tag_id IS %s NULL", notClause))
|
|
return
|
|
}
|
|
|
|
if len(tags.Value) == 0 {
|
|
return
|
|
}
|
|
|
|
valuesClause := getHierarchicalValues(qb.tx, tags.Value, tagTable, "tags_relations", "", tags.Depth)
|
|
|
|
f.addWith(`performer_tags AS (
|
|
SELECT pg.gallery_id, t.column1 AS root_tag_id FROM performers_galleries pg
|
|
INNER JOIN performers_tags pt ON pt.performer_id = pg.performer_id
|
|
INNER JOIN (` + valuesClause + `) t ON t.column2 = pt.tag_id
|
|
)`)
|
|
|
|
f.addLeftJoin("performer_tags", "", "performer_tags.gallery_id = galleries.id")
|
|
|
|
addHierarchicalConditionClauses(f, tags, "performer_tags", "root_tag_id")
|
|
}
|
|
}
|
|
}
|
|
|
|
func galleryPerformerFavoriteCriterionHandler(performerfavorite *bool) criterionHandlerFunc {
|
|
return func(f *filterBuilder) {
|
|
if performerfavorite != nil {
|
|
f.addLeftJoin("performers_galleries", "", "galleries.id = performers_galleries.gallery_id")
|
|
|
|
if *performerfavorite {
|
|
// contains at least one favorite
|
|
f.addLeftJoin("performers", "", "performers.id = performers_galleries.performer_id")
|
|
f.addWhere("performers.favorite = 1")
|
|
} else {
|
|
// contains zero favorites
|
|
f.addLeftJoin(`(SELECT performers_galleries.gallery_id as id FROM performers_galleries
|
|
JOIN performers ON performers.id = performers_galleries.performer_id
|
|
GROUP BY performers_galleries.gallery_id HAVING SUM(performers.favorite) = 0)`, "nofaves", "galleries.id = nofaves.id")
|
|
f.addWhere("performers_galleries.gallery_id IS NULL OR nofaves.id IS NOT NULL")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func galleryPerformerAgeCriterionHandler(performerAge *models.IntCriterionInput) criterionHandlerFunc {
|
|
return func(f *filterBuilder) {
|
|
if performerAge != nil {
|
|
f.addInnerJoin("performers_galleries", "", "galleries.id = performers_galleries.gallery_id")
|
|
f.addInnerJoin("performers", "", "performers_galleries.performer_id = performers.id")
|
|
|
|
f.addWhere("galleries.date != '' AND performers.birthdate != ''")
|
|
f.addWhere("galleries.date IS NOT NULL AND performers.birthdate IS NOT NULL")
|
|
f.addWhere("galleries.date != '0001-01-01' AND performers.birthdate != '0001-01-01'")
|
|
|
|
ageCalc := "cast(strftime('%Y.%m%d', galleries.date) - strftime('%Y.%m%d', performers.birthdate) as int)"
|
|
whereClause, args := getIntWhereClause(ageCalc, performerAge.Modifier, performerAge.Value, performerAge.Value2)
|
|
f.addWhere(whereClause, args...)
|
|
}
|
|
}
|
|
}
|
|
|
|
func galleryAverageResolutionCriterionHandler(qb *galleryQueryBuilder, resolution *models.ResolutionCriterionInput) criterionHandlerFunc {
|
|
return func(f *filterBuilder) {
|
|
if resolution != nil && resolution.Value.IsValid() {
|
|
qb.imagesRepository().join(f, "images_join", "galleries.id")
|
|
f.addLeftJoin("images", "", "images_join.image_id = images.id")
|
|
|
|
min := resolution.Value.GetMinResolution()
|
|
max := resolution.Value.GetMaxResolution()
|
|
|
|
const widthHeight = "avg(MIN(images.width, images.height))"
|
|
|
|
switch resolution.Modifier {
|
|
case models.CriterionModifierEquals:
|
|
f.addHaving(fmt.Sprintf("%s BETWEEN %d AND %d", widthHeight, min, max))
|
|
case models.CriterionModifierNotEquals:
|
|
f.addHaving(fmt.Sprintf("%s NOT BETWEEN %d AND %d", widthHeight, min, max))
|
|
case models.CriterionModifierLessThan:
|
|
f.addHaving(fmt.Sprintf("%s < %d", widthHeight, min))
|
|
case models.CriterionModifierGreaterThan:
|
|
f.addHaving(fmt.Sprintf("%s > %d", widthHeight, max))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) getGallerySort(findFilter *models.FindFilterType) string {
|
|
if findFilter == nil || findFilter.Sort == nil || *findFilter.Sort == "" {
|
|
return ""
|
|
}
|
|
|
|
sort := findFilter.GetSort("path")
|
|
direction := findFilter.GetDirection()
|
|
|
|
switch sort {
|
|
case "images_count":
|
|
return getCountSort(galleryTable, galleriesImagesTable, galleryIDColumn, direction)
|
|
case "tag_count":
|
|
return getCountSort(galleryTable, galleriesTagsTable, galleryIDColumn, direction)
|
|
case "performer_count":
|
|
return getCountSort(galleryTable, performersGalleriesTable, galleryIDColumn, direction)
|
|
default:
|
|
return getSort(sort, direction, "galleries")
|
|
}
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) queryGallery(query string, args []interface{}) (*models.Gallery, error) {
|
|
results, err := qb.queryGalleries(query, args)
|
|
if err != nil || len(results) < 1 {
|
|
return nil, err
|
|
}
|
|
return results[0], nil
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) queryGalleries(query string, args []interface{}) ([]*models.Gallery, error) {
|
|
var ret models.Galleries
|
|
if err := qb.query(query, args, &ret); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return []*models.Gallery(ret), nil
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) performersRepository() *joinRepository {
|
|
return &joinRepository{
|
|
repository: repository{
|
|
tx: qb.tx,
|
|
tableName: performersGalleriesTable,
|
|
idColumn: galleryIDColumn,
|
|
},
|
|
fkColumn: "performer_id",
|
|
}
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) GetPerformerIDs(galleryID int) ([]int, error) {
|
|
return qb.performersRepository().getIDs(galleryID)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) UpdatePerformers(galleryID int, performerIDs []int) error {
|
|
// Delete the existing joins and then create new ones
|
|
return qb.performersRepository().replace(galleryID, performerIDs)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) tagsRepository() *joinRepository {
|
|
return &joinRepository{
|
|
repository: repository{
|
|
tx: qb.tx,
|
|
tableName: galleriesTagsTable,
|
|
idColumn: galleryIDColumn,
|
|
},
|
|
fkColumn: "tag_id",
|
|
}
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) GetTagIDs(galleryID int) ([]int, error) {
|
|
return qb.tagsRepository().getIDs(galleryID)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) UpdateTags(galleryID int, tagIDs []int) error {
|
|
// Delete the existing joins and then create new ones
|
|
return qb.tagsRepository().replace(galleryID, tagIDs)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) imagesRepository() *joinRepository {
|
|
return &joinRepository{
|
|
repository: repository{
|
|
tx: qb.tx,
|
|
tableName: galleriesImagesTable,
|
|
idColumn: galleryIDColumn,
|
|
},
|
|
fkColumn: "image_id",
|
|
}
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) GetImageIDs(galleryID int) ([]int, error) {
|
|
return qb.imagesRepository().getIDs(galleryID)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) UpdateImages(galleryID int, imageIDs []int) error {
|
|
// Delete the existing joins and then create new ones
|
|
return qb.imagesRepository().replace(galleryID, imageIDs)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) scenesRepository() *joinRepository {
|
|
return &joinRepository{
|
|
repository: repository{
|
|
tx: qb.tx,
|
|
tableName: galleriesScenesTable,
|
|
idColumn: galleryIDColumn,
|
|
},
|
|
fkColumn: sceneIDColumn,
|
|
}
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) GetSceneIDs(galleryID int) ([]int, error) {
|
|
return qb.scenesRepository().getIDs(galleryID)
|
|
}
|
|
|
|
func (qb *galleryQueryBuilder) UpdateScenes(galleryID int, sceneIDs []int) error {
|
|
// Delete the existing joins and then create new ones
|
|
return qb.scenesRepository().replace(galleryID, sceneIDs)
|
|
}
|