Optimize allData queries (#3452)

* Add specific fields to allData queries
* Add additional allData endpoints
This commit is contained in:
DingDongSoLong4
2023-02-20 00:24:47 +02:00
committed by GitHub
parent b3c23950e2
commit 51469cfc7f
17 changed files with 161 additions and 56 deletions

View File

@@ -8,18 +8,25 @@ query MarkerStrings($q: String, $sort: String) {
query AllPerformersForFilter { query AllPerformersForFilter {
allPerformers { allPerformers {
...SlimPerformerData id
name
disambiguation
alias_list
} }
} }
query AllStudiosForFilter { query AllStudiosForFilter {
allStudios { allStudios {
...SlimStudioData id
name
aliases
} }
} }
query AllMoviesForFilter { query AllMoviesForFilter {
allMovies { allMovies {
...SlimMovieData id
name
} }
} }

View File

@@ -144,6 +144,10 @@ type Query {
# Get everything # Get everything
allScenes: [Scene!]!
allSceneMarkers: [SceneMarker!]!
allImages: [Image!]!
allGalleries: [Gallery!]!
allPerformers: [Performer!]! allPerformers: [Performer!]!
allStudios: [Studio!]! allStudios: [Studio!]!
allMovies: [Movie!]! allMovies: [Movie!]!

View File

@@ -43,3 +43,14 @@ func (r *queryResolver) FindGalleries(ctx context.Context, galleryFilter *models
return ret, nil return ret, nil
} }
func (r *queryResolver) AllGalleries(ctx context.Context) (ret []*models.Gallery, err error) {
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
ret, err = r.repository.Gallery.All(ctx)
return err
}); err != nil {
return nil, err
}
return ret, nil
}

View File

@@ -86,3 +86,14 @@ func (r *queryResolver) FindImages(ctx context.Context, imageFilter *models.Imag
return ret, nil return ret, nil
} }
func (r *queryResolver) AllImages(ctx context.Context) (ret []*models.Image, err error) {
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
ret, err = r.repository.Image.All(ctx)
return err
}); err != nil {
return nil, err
}
return ret, nil
}

View File

@@ -234,3 +234,14 @@ func (r *queryResolver) FindDuplicateScenes(ctx context.Context, distance *int)
return ret, nil return ret, nil
} }
func (r *queryResolver) AllScenes(ctx context.Context) (ret []*models.Scene, err error) {
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
ret, err = r.repository.Scene.All(ctx)
return err
}); err != nil {
return nil, err
}
return ret, nil
}

View File

@@ -24,3 +24,14 @@ func (r *queryResolver) FindSceneMarkers(ctx context.Context, sceneMarkerFilter
return ret, nil return ret, nil
} }
func (r *queryResolver) AllSceneMarkers(ctx context.Context) (ret []*models.SceneMarker, err error) {
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
ret, err = r.repository.SceneMarker.All(ctx)
return err
}); err != nil {
return nil, err
}
return ret, nil
}

View File

@@ -14,6 +14,50 @@ type SceneMarkerReaderWriter struct {
mock.Mock mock.Mock
} }
// All provides a mock function with given fields: ctx
func (_m *SceneMarkerReaderWriter) All(ctx context.Context) ([]*models.SceneMarker, error) {
ret := _m.Called(ctx)
var r0 []*models.SceneMarker
if rf, ok := ret.Get(0).(func(context.Context) []*models.SceneMarker); ok {
r0 = rf(ctx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*models.SceneMarker)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Count provides a mock function with given fields: ctx
func (_m *SceneMarkerReaderWriter) Count(ctx context.Context) (int, error) {
ret := _m.Called(ctx)
var r0 int
if rf, ok := ret.Get(0).(func(context.Context) int); ok {
r0 = rf(ctx)
} else {
r0 = ret.Get(0).(int)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CountByTagID provides a mock function with given fields: ctx, tagID // CountByTagID provides a mock function with given fields: ctx, tagID
func (_m *SceneMarkerReaderWriter) CountByTagID(ctx context.Context, tagID int) (int, error) { func (_m *SceneMarkerReaderWriter) CountByTagID(ctx context.Context, tagID int) (int, error) {
ret := _m.Called(ctx, tagID) ret := _m.Called(ctx, tagID)

View File

@@ -638,29 +638,8 @@ func (_m *SceneReaderWriter) GetTagIDs(ctx context.Context, relatedID int) ([]in
return r0, r1 return r0, r1
} }
// SaveActivity provides a mock function with given fields: ctx, id, resumeTime, playDuration // IncrementOCounter provides a mock function with given fields: ctx, id
func (_m *SceneReaderWriter) SaveActivity(ctx context.Context, id int, resumeTime *float64, playDuration *float64) (bool, error) { func (_m *SceneReaderWriter) IncrementOCounter(ctx context.Context, id int) (int, error) {
ret := _m.Called(ctx, id, resumeTime, playDuration)
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context, int, *float64, *float64) bool); ok {
r0 = rf(ctx, id, resumeTime, playDuration)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int, *float64, *float64) error); ok {
r1 = rf(ctx, id, resumeTime, playDuration)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// IncrementWatchCount provides a mock function with given fields: ctx, id
func (_m *SceneReaderWriter) IncrementWatchCount(ctx context.Context, id int) (int, error) {
ret := _m.Called(ctx, id) ret := _m.Called(ctx, id)
var r0 int var r0 int
@@ -680,8 +659,8 @@ func (_m *SceneReaderWriter) IncrementWatchCount(ctx context.Context, id int) (i
return r0, r1 return r0, r1
} }
// IncrementOCounter provides a mock function with given fields: ctx, id // IncrementWatchCount provides a mock function with given fields: ctx, id
func (_m *SceneReaderWriter) IncrementOCounter(ctx context.Context, id int) (int, error) { func (_m *SceneReaderWriter) IncrementWatchCount(ctx context.Context, id int) (int, error) {
ret := _m.Called(ctx, id) ret := _m.Called(ctx, id)
var r0 int var r0 int
@@ -745,6 +724,27 @@ func (_m *SceneReaderWriter) ResetOCounter(ctx context.Context, id int) (int, er
return r0, r1 return r0, r1
} }
// SaveActivity provides a mock function with given fields: ctx, id, resumeTime, playDuration
func (_m *SceneReaderWriter) SaveActivity(ctx context.Context, id int, resumeTime *float64, playDuration *float64) (bool, error) {
ret := _m.Called(ctx, id, resumeTime, playDuration)
var r0 bool
if rf, ok := ret.Get(0).(func(context.Context, int, *float64, *float64) bool); ok {
r0 = rf(ctx, id, resumeTime, playDuration)
} else {
r0 = ret.Get(0).(bool)
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, int, *float64, *float64) error); ok {
r1 = rf(ctx, id, resumeTime, playDuration)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Size provides a mock function with given fields: ctx // Size provides a mock function with given fields: ctx
func (_m *SceneReaderWriter) Size(ctx context.Context) (float64, error) { func (_m *SceneReaderWriter) Size(ctx context.Context) (float64, error) {
ret := _m.Called(ctx) ret := _m.Called(ctx)

View File

@@ -36,6 +36,8 @@ type SceneMarkerReader interface {
CountByTagID(ctx context.Context, tagID int) (int, error) CountByTagID(ctx context.Context, tagID int) (int, error)
GetMarkerStrings(ctx context.Context, q *string, sort *string) ([]*MarkerStringsResultType, error) GetMarkerStrings(ctx context.Context, q *string, sort *string) ([]*MarkerStringsResultType, error)
Wall(ctx context.Context, q *string) ([]*SceneMarker, error) Wall(ctx context.Context, q *string) ([]*SceneMarker, error)
Count(ctx context.Context) (int, error)
All(ctx context.Context) ([]*SceneMarker, error)
Query(ctx context.Context, sceneMarkerFilter *SceneMarkerFilterType, findFilter *FindFilterType) ([]*SceneMarker, int, error) Query(ctx context.Context, sceneMarkerFilter *SceneMarkerFilterType, findFilter *FindFilterType) ([]*SceneMarker, int, error)
GetTagIDs(ctx context.Context, imageID int) ([]int, error) GetTagIDs(ctx context.Context, imageID int) ([]int, error)
} }

View File

@@ -346,3 +346,11 @@ func (qb *sceneMarkerQueryBuilder) UpdateTags(ctx context.Context, id int, tagID
// Delete the existing joins and then create new ones // Delete the existing joins and then create new ones
return qb.tagsRepository().replace(ctx, id, tagIDs) return qb.tagsRepository().replace(ctx, id, tagIDs)
} }
func (qb *sceneMarkerQueryBuilder) Count(ctx context.Context) (int, error) {
return qb.runCountQuery(ctx, qb.buildCountQuery("SELECT scene_markers.id FROM scene_markers"), nil)
}
func (qb *sceneMarkerQueryBuilder) All(ctx context.Context) ([]*models.SceneMarker, error) {
return qb.querySceneMarkers(ctx, selectAll("scene_markers")+qb.getSceneMarkerSort(nil, nil), nil)
}

View File

@@ -222,4 +222,6 @@ func queryMarkers(ctx context.Context, t *testing.T, sqb models.SceneMarkerReade
// TODO Find // TODO Find
// TODO GetMarkerStrings // TODO GetMarkerStrings
// TODO Wall // TODO Wall
// TODO Count
// TODO All
// TODO Query // TODO Query

View File

@@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import { Form } from "react-bootstrap"; import { Form } from "react-bootstrap";
import { defineMessages, MessageDescriptor, useIntl } from "react-intl"; import { defineMessages, MessageDescriptor, useIntl } from "react-intl";
import { FilterSelect, ValidTypes } from "src/components/Shared/Select"; import { FilterSelect, SelectObject } from "src/components/Shared/Select";
import { Criterion } from "src/models/list-filter/criteria/criterion"; import { Criterion } from "src/models/list-filter/criteria/criterion";
import { IHierarchicalLabelValue } from "src/models/list-filter/types"; import { IHierarchicalLabelValue } from "src/models/list-filter/types";
@@ -35,11 +35,11 @@ export const HierarchicalLabelValueFilter: React.FC<
}, },
}); });
function onSelectionChanged(items: ValidTypes[]) { function onSelectionChanged(items: SelectObject[]) {
const { value } = criterion; const { value } = criterion;
value.items = items.map((i) => ({ value.items = items.map((i) => ({
id: i.id, id: i.id,
label: i.name!, label: i.name ?? i.title ?? "",
})); }));
onValueChanged(value); onValueChanged(value);
} }

View File

@@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import { Form } from "react-bootstrap"; import { Form } from "react-bootstrap";
import { FilterSelect, ValidTypes } from "src/components/Shared/Select"; import { FilterSelect, SelectObject } from "src/components/Shared/Select";
import { Criterion } from "src/models/list-filter/criteria/criterion"; import { Criterion } from "src/models/list-filter/criteria/criterion";
import { ILabeledId } from "src/models/list-filter/types"; import { ILabeledId } from "src/models/list-filter/types";
@@ -26,11 +26,11 @@ export const LabeledIdFilter: React.FC<ILabeledIdFilterProps> = ({
) )
return null; return null;
function onSelectionChanged(items: ValidTypes[]) { function onSelectionChanged(items: SelectObject[]) {
onValueChanged( onValueChanged(
items.map((i) => ({ items.map((i) => ({
id: i.id, id: i.id,
label: i.name!, label: i.name ?? i.title ?? "",
})) }))
); );
} }

View File

@@ -3,13 +3,7 @@ import { useIntl } from "react-intl";
import * as GQL from "src/core/generated-graphql"; import * as GQL from "src/core/generated-graphql";
import { Button, ButtonGroup } from "react-bootstrap"; import { Button, ButtonGroup } from "react-bootstrap";
import { FilterSelect } from "./Select"; import { FilterSelect, SelectObject } from "./Select";
type ValidTypes =
| GQL.SlimPerformerDataFragment
| GQL.SlimTagDataFragment
| GQL.SlimStudioDataFragment
| GQL.SlimMovieDataFragment;
interface IMultiSetProps { interface IMultiSetProps {
type: "performers" | "studios" | "tags" | "movies"; type: "performers" | "studios" | "tags" | "movies";
@@ -29,7 +23,7 @@ export const MultiSet: React.FC<IMultiSetProps> = (props) => {
GQL.BulkUpdateIdMode.Remove, GQL.BulkUpdateIdMode.Remove,
]; ];
function onUpdate(items: ValidTypes[]) { function onUpdate(items: SelectObject[]) {
props.onUpdate(items.map((i) => i.id)); props.onUpdate(items.map((i) => i.id));
} }

View File

@@ -31,11 +31,11 @@ import { objectTitle } from "src/core/files";
import { galleryTitle } from "src/core/galleries"; import { galleryTitle } from "src/core/galleries";
import { TagPopover } from "../Tags/TagPopover"; import { TagPopover } from "../Tags/TagPopover";
export type ValidTypes = export type SelectObject = {
| GQL.SlimPerformerDataFragment id: string;
| GQL.SlimTagDataFragment name?: string | null;
| GQL.SlimStudioDataFragment title?: string | null;
| GQL.SlimMovieDataFragment; };
type Option = { value: string; label: string }; type Option = { value: string; label: string };
interface ITypeProps { interface ITypeProps {
@@ -53,7 +53,7 @@ interface ITypeProps {
interface IFilterProps { interface IFilterProps {
ids?: string[]; ids?: string[];
initialIds?: string[]; initialIds?: string[];
onSelect?: (item: ValidTypes[]) => void; onSelect?: (item: SelectObject[]) => void;
noSelectionString?: string; noSelectionString?: string;
className?: string; className?: string;
isMulti?: boolean; isMulti?: boolean;
@@ -90,9 +90,9 @@ interface ISelectProps<T extends boolean> {
noOptionsMessage?: string | null; noOptionsMessage?: string | null;
} }
interface IFilterComponentProps extends IFilterProps { interface IFilterComponentProps extends IFilterProps {
items: Array<ValidTypes>; items: SelectObject[];
toOption?: (item: ValidTypes) => Option; toOption?: (item: SelectObject) => Option;
onCreate?: (name: string) => Promise<{ item: ValidTypes; message: string }>; onCreate?: (name: string) => Promise<{ item: SelectObject; message: string }>;
} }
interface IFilterSelectProps<T extends boolean> interface IFilterSelectProps<T extends boolean>
extends Pick< extends Pick<
@@ -284,7 +284,7 @@ const FilterSelectComponent = <T extends boolean>(
} }
return { return {
value: i.id, value: i.id,
label: i.name ?? "", label: i.name ?? i.title ?? "",
}; };
}); });

View File

@@ -6,7 +6,7 @@ import cx from "classnames";
import * as GQL from "src/core/generated-graphql"; import * as GQL from "src/core/generated-graphql";
import { Icon } from "src/components/Shared/Icon"; import { Icon } from "src/components/Shared/Icon";
import { OperationButton } from "src/components/Shared/OperationButton"; import { OperationButton } from "src/components/Shared/OperationButton";
import { PerformerSelect, ValidTypes } from "src/components/Shared/Select"; import { PerformerSelect, SelectObject } from "src/components/Shared/Select";
import { OptionalField } from "../IncludeButton"; import { OptionalField } from "../IncludeButton";
import { faSave } from "@fortawesome/free-solid-svg-icons"; import { faSave } from "@fortawesome/free-solid-svg-icons";
@@ -38,7 +38,7 @@ const PerformerResult: React.FC<IPerformerResultProps> = ({
(stashID) => stashID.endpoint === endpoint && stashID.stash_id (stashID) => stashID.endpoint === endpoint && stashID.stash_id
); );
const handlePerformerSelect = (performers: ValidTypes[]) => { const handlePerformerSelect = (performers: SelectObject[]) => {
if (performers.length) { if (performers.length) {
setSelectedID(performers[0].id); setSelectedID(performers[0].id);
} else { } else {

View File

@@ -5,7 +5,7 @@ import cx from "classnames";
import { Icon } from "src/components/Shared/Icon"; import { Icon } from "src/components/Shared/Icon";
import { OperationButton } from "src/components/Shared/OperationButton"; import { OperationButton } from "src/components/Shared/OperationButton";
import { StudioSelect, ValidTypes } from "src/components/Shared/Select"; import { StudioSelect, SelectObject } from "src/components/Shared/Select";
import * as GQL from "src/core/generated-graphql"; import * as GQL from "src/core/generated-graphql";
import { OptionalField } from "../IncludeButton"; import { OptionalField } from "../IncludeButton";
@@ -38,7 +38,7 @@ const StudioResult: React.FC<IStudioResultProps> = ({
(stashID) => stashID.endpoint === endpoint && stashID.stash_id (stashID) => stashID.endpoint === endpoint && stashID.stash_id
); );
const handleSelect = (studios: ValidTypes[]) => { const handleSelect = (studios: SelectObject[]) => {
if (studios.length) { if (studios.length) {
setSelectedID(studios[0].id); setSelectedID(studios[0].id);
} else { } else {