From 962121342400e37c4341b0ac257882d0466c984c Mon Sep 17 00:00:00 2001 From: DingDongSoLong4 <99329275+DingDongSoLong4@users.noreply.github.com> Date: Wed, 1 Nov 2023 23:58:32 +0200 Subject: [PATCH] Genericise sliceutil functions (#4253) * Genericise sliceutil.SliceSame * Genericise intslice functions * Genericise stringutil functions --- internal/api/resolver_mutation_image.go | 4 +- internal/api/resolver_mutation_plugin.go | 4 +- internal/api/resolver_mutation_scene.go | 6 +- internal/api/resolver_query_find_image.go | 8 +- internal/api/resolver_query_find_scene.go | 14 +- internal/api/resolver_query_scraper.go | 3 +- internal/autotag/gallery.go | 6 +- internal/autotag/image.go | 6 +- internal/autotag/performer.go | 8 +- internal/autotag/scene.go | 6 +- internal/autotag/tag.go | 8 +- internal/dlna/cds.go | 4 +- internal/dlna/whitelist.go | 4 +- internal/identify/identify.go | 2 +- internal/identify/identify_test.go | 4 +- internal/identify/scene.go | 5 +- internal/manager/task_export.go | 34 ++-- pkg/gallery/import.go | 10 +- pkg/gallery/validation.go | 4 +- pkg/image/import.go | 10 +- pkg/image/scan.go | 4 +- pkg/match/path.go | 4 +- pkg/models/update.go | 6 +- pkg/performer/import.go | 6 +- pkg/plugin/plugins.go | 10 +- pkg/scene/export.go | 8 +- pkg/scene/import.go | 10 +- pkg/scene/merge.go | 6 +- pkg/scraper/mapped.go | 6 +- pkg/session/session.go | 4 +- pkg/sliceutil/collections.go | 152 ++++++++++++------ pkg/sliceutil/collections_test.go | 42 ++--- pkg/sliceutil/intslice/int_collections.go | 81 ---------- .../stringslice/string_collections.go | 91 ----------- pkg/sqlite/gallery.go | 4 +- pkg/sqlite/gallery_chapter.go | 4 +- pkg/sqlite/image.go | 4 +- pkg/sqlite/migrations/42_postmigrate.go | 4 +- pkg/sqlite/movies.go | 4 +- pkg/sqlite/performer.go | 4 +- pkg/sqlite/saved_filter.go | 4 +- pkg/sqlite/scene.go | 6 +- pkg/sqlite/scene_marker.go | 4 +- pkg/sqlite/scene_marker_test.go | 4 +- pkg/sqlite/scene_test.go | 6 +- pkg/sqlite/setup_test.go | 4 +- pkg/sqlite/studio.go | 4 +- pkg/sqlite/table.go | 8 +- pkg/sqlite/tag.go | 4 +- pkg/utils/phash.go | 4 +- scripts/test_db_generator/makeTestDB.go | 16 +- 51 files changed, 259 insertions(+), 409 deletions(-) diff --git a/internal/api/resolver_mutation_image.go b/internal/api/resolver_mutation_image.go index d2ff61cf8..e465da33f 100644 --- a/internal/api/resolver_mutation_image.go +++ b/internal/api/resolver_mutation_image.go @@ -10,7 +10,7 @@ import ( "github.com/stashapp/stash/pkg/image" "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/plugin" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/sliceutil/stringslice" "github.com/stashapp/stash/pkg/utils" ) @@ -256,7 +256,7 @@ func (r *mutationResolver) BulkImageUpdate(ctx context.Context, input BulkImageU } thisUpdatedGalleryIDs := updatedImage.GalleryIDs.ImpactedIDs(i.GalleryIDs.List()) - updatedGalleryIDs = intslice.IntAppendUniques(updatedGalleryIDs, thisUpdatedGalleryIDs) + updatedGalleryIDs = sliceutil.AppendUniques(updatedGalleryIDs, thisUpdatedGalleryIDs) } image, err := qb.UpdatePartial(ctx, imageID, updatedImage) diff --git a/internal/api/resolver_mutation_plugin.go b/internal/api/resolver_mutation_plugin.go index 8b3d554f8..dae12e0e6 100644 --- a/internal/api/resolver_mutation_plugin.go +++ b/internal/api/resolver_mutation_plugin.go @@ -7,7 +7,7 @@ import ( "github.com/stashapp/stash/internal/manager/config" "github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/plugin" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" ) func (r *mutationResolver) RunPluginTask(ctx context.Context, pluginID string, taskName string, args []*plugin.PluginArgInput) (string, error) { @@ -41,7 +41,7 @@ func (r *mutationResolver) SetPluginsEnabled(ctx context.Context, enabledMap map // add plugins that are newly disabled for pluginID, enabled := range enabledMap { if !enabled { - newDisabled = stringslice.StrAppendUnique(newDisabled, pluginID) + newDisabled = sliceutil.AppendUnique(newDisabled, pluginID) } } diff --git a/internal/api/resolver_mutation_scene.go b/internal/api/resolver_mutation_scene.go index ad495454c..67f72262b 100644 --- a/internal/api/resolver_mutation_scene.go +++ b/internal/api/resolver_mutation_scene.go @@ -11,7 +11,7 @@ import ( "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/plugin" "github.com/stashapp/stash/pkg/scene" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/sliceutil/stringslice" "github.com/stashapp/stash/pkg/utils" ) @@ -627,7 +627,7 @@ func (r *mutationResolver) SceneMarkerCreate(ctx context.Context, input SceneMar // Save the marker tags // If this tag is the primary tag, then let's not add it. - tagIDs = intslice.IntExclude(tagIDs, []int{newMarker.PrimaryTagID}) + tagIDs = sliceutil.Exclude(tagIDs, []int{newMarker.PrimaryTagID}) return qb.UpdateTags(ctx, newMarker.ID, tagIDs) }); err != nil { return nil, err @@ -716,7 +716,7 @@ func (r *mutationResolver) SceneMarkerUpdate(ctx context.Context, input SceneMar if tagIdsIncluded { // Save the marker tags // If this tag is the primary tag, then let's not add it. - tagIDs = intslice.IntExclude(tagIDs, []int{newMarker.PrimaryTagID}) + tagIDs = sliceutil.Exclude(tagIDs, []int{newMarker.PrimaryTagID}) if err := qb.UpdateTags(ctx, markerID, tagIDs); err != nil { return err } diff --git a/internal/api/resolver_query_find_image.go b/internal/api/resolver_query_find_image.go index 6d33e8820..dde193a5f 100644 --- a/internal/api/resolver_query_find_image.go +++ b/internal/api/resolver_query_find_image.go @@ -6,7 +6,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" ) func (r *queryResolver) FindImage(ctx context.Context, id *string, checksum *string) (*models.Image, error) { @@ -55,11 +55,11 @@ func (r *queryResolver) FindImages(ctx context.Context, imageFilter *models.Imag result, err := qb.Query(ctx, models.ImageQueryOptions{ QueryOptions: models.QueryOptions{ FindFilter: filter, - Count: stringslice.StrInclude(fields, "count"), + Count: sliceutil.Contains(fields, "count"), }, ImageFilter: imageFilter, - Megapixels: stringslice.StrInclude(fields, "megapixels"), - TotalSize: stringslice.StrInclude(fields, "filesize"), + Megapixels: sliceutil.Contains(fields, "megapixels"), + TotalSize: sliceutil.Contains(fields, "filesize"), }) if err != nil { return err diff --git a/internal/api/resolver_query_find_scene.go b/internal/api/resolver_query_find_scene.go index c6492680e..bd6fc6ffe 100644 --- a/internal/api/resolver_query_find_scene.go +++ b/internal/api/resolver_query_find_scene.go @@ -8,7 +8,7 @@ import ( "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/scene" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" ) func (r *queryResolver) FindScene(ctx context.Context, id *string, checksum *string) (*models.Scene, error) { @@ -105,11 +105,11 @@ func (r *queryResolver) FindScenes(ctx context.Context, sceneFilter *models.Scen result, err = r.repository.Scene.Query(ctx, models.SceneQueryOptions{ QueryOptions: models.QueryOptions{ FindFilter: filter, - Count: stringslice.StrInclude(fields, "count"), + Count: sliceutil.Contains(fields, "count"), }, SceneFilter: sceneFilter, - TotalDuration: stringslice.StrInclude(fields, "duration"), - TotalSize: stringslice.StrInclude(fields, "filesize"), + TotalDuration: sliceutil.Contains(fields, "duration"), + TotalSize: sliceutil.Contains(fields, "filesize"), }) if err == nil { scenes, err = result.Resolve(ctx) @@ -160,11 +160,11 @@ func (r *queryResolver) FindScenesByPathRegex(ctx context.Context, filter *model result, err := r.repository.Scene.Query(ctx, models.SceneQueryOptions{ QueryOptions: models.QueryOptions{ FindFilter: queryFilter, - Count: stringslice.StrInclude(fields, "count"), + Count: sliceutil.Contains(fields, "count"), }, SceneFilter: sceneFilter, - TotalDuration: stringslice.StrInclude(fields, "duration"), - TotalSize: stringslice.StrInclude(fields, "filesize"), + TotalDuration: sliceutil.Contains(fields, "duration"), + TotalSize: sliceutil.Contains(fields, "filesize"), }) if err != nil { return err diff --git a/internal/api/resolver_query_scraper.go b/internal/api/resolver_query_scraper.go index 5c9f20042..a2974d0d8 100644 --- a/internal/api/resolver_query_scraper.go +++ b/internal/api/resolver_query_scraper.go @@ -14,6 +14,7 @@ import ( "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/scraper" "github.com/stashapp/stash/pkg/scraper/stashbox" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/sliceutil/stringslice" ) @@ -80,7 +81,7 @@ func filterSceneTags(scenes []*scraper.ScrapedScene) { for _, reg := range excludeRegexps { if reg.MatchString(strings.ToLower(t.Name)) { ignore = true - ignoredTags = stringslice.StrAppendUnique(ignoredTags, t.Name) + ignoredTags = sliceutil.AppendUnique(ignoredTags, t.Name) break } } diff --git a/internal/autotag/gallery.go b/internal/autotag/gallery.go index f768a31dd..cbf5ebf09 100644 --- a/internal/autotag/gallery.go +++ b/internal/autotag/gallery.go @@ -6,7 +6,7 @@ import ( "github.com/stashapp/stash/pkg/gallery" "github.com/stashapp/stash/pkg/match" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" ) type GalleryFinderUpdater interface { @@ -53,7 +53,7 @@ func GalleryPerformers(ctx context.Context, s *models.Gallery, rw GalleryPerform } existing := s.PerformerIDs.List() - if intslice.IntInclude(existing, otherID) { + if sliceutil.Contains(existing, otherID) { return false, nil } @@ -91,7 +91,7 @@ func GalleryTags(ctx context.Context, s *models.Gallery, rw GalleryTagUpdater, t } existing := s.TagIDs.List() - if intslice.IntInclude(existing, otherID) { + if sliceutil.Contains(existing, otherID) { return false, nil } diff --git a/internal/autotag/image.go b/internal/autotag/image.go index d28960f3c..63544123a 100644 --- a/internal/autotag/image.go +++ b/internal/autotag/image.go @@ -6,7 +6,7 @@ import ( "github.com/stashapp/stash/pkg/image" "github.com/stashapp/stash/pkg/match" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" ) type ImageFinderUpdater interface { @@ -44,7 +44,7 @@ func ImagePerformers(ctx context.Context, s *models.Image, rw ImagePerformerUpda } existing := s.PerformerIDs.List() - if intslice.IntInclude(existing, otherID) { + if sliceutil.Contains(existing, otherID) { return false, nil } @@ -82,7 +82,7 @@ func ImageTags(ctx context.Context, s *models.Image, rw ImageTagUpdater, tagRead } existing := s.TagIDs.List() - if intslice.IntInclude(existing, otherID) { + if sliceutil.Contains(existing, otherID) { return false, nil } diff --git a/internal/autotag/performer.go b/internal/autotag/performer.go index cc839f361..12dac0e93 100644 --- a/internal/autotag/performer.go +++ b/internal/autotag/performer.go @@ -8,7 +8,7 @@ import ( "github.com/stashapp/stash/pkg/match" "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/scene" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/txn" ) @@ -63,7 +63,7 @@ func (tagger *Tagger) PerformerScenes(ctx context.Context, p *models.Performer, } existing := o.PerformerIDs.List() - if intslice.IntInclude(existing, p.ID) { + if sliceutil.Contains(existing, p.ID) { return false, nil } @@ -92,7 +92,7 @@ func (tagger *Tagger) PerformerImages(ctx context.Context, p *models.Performer, } existing := o.PerformerIDs.List() - if intslice.IntInclude(existing, p.ID) { + if sliceutil.Contains(existing, p.ID) { return false, nil } @@ -121,7 +121,7 @@ func (tagger *Tagger) PerformerGalleries(ctx context.Context, p *models.Performe } existing := o.PerformerIDs.List() - if intslice.IntInclude(existing, p.ID) { + if sliceutil.Contains(existing, p.ID) { return false, nil } diff --git a/internal/autotag/scene.go b/internal/autotag/scene.go index 6095905e8..751d0ed62 100644 --- a/internal/autotag/scene.go +++ b/internal/autotag/scene.go @@ -6,7 +6,7 @@ import ( "github.com/stashapp/stash/pkg/match" "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/scene" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" ) type SceneFinderUpdater interface { @@ -44,7 +44,7 @@ func ScenePerformers(ctx context.Context, s *models.Scene, rw ScenePerformerUpda } existing := s.PerformerIDs.List() - if intslice.IntInclude(existing, otherID) { + if sliceutil.Contains(existing, otherID) { return false, nil } @@ -82,7 +82,7 @@ func SceneTags(ctx context.Context, s *models.Scene, rw SceneTagUpdater, tagRead } existing := s.TagIDs.List() - if intslice.IntInclude(existing, otherID) { + if sliceutil.Contains(existing, otherID) { return false, nil } diff --git a/internal/autotag/tag.go b/internal/autotag/tag.go index 8c404f62f..5b1b5c319 100644 --- a/internal/autotag/tag.go +++ b/internal/autotag/tag.go @@ -8,7 +8,7 @@ import ( "github.com/stashapp/stash/pkg/match" "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/scene" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/txn" ) @@ -61,7 +61,7 @@ func (tagger *Tagger) TagScenes(ctx context.Context, p *models.Tag, paths []stri } existing := o.TagIDs.List() - if intslice.IntInclude(existing, p.ID) { + if sliceutil.Contains(existing, p.ID) { return false, nil } @@ -90,7 +90,7 @@ func (tagger *Tagger) TagImages(ctx context.Context, p *models.Tag, paths []stri } existing := o.TagIDs.List() - if intslice.IntInclude(existing, p.ID) { + if sliceutil.Contains(existing, p.ID) { return false, nil } @@ -119,7 +119,7 @@ func (tagger *Tagger) TagGalleries(ctx context.Context, p *models.Tag, paths []s } existing := o.TagIDs.List() - if intslice.IntInclude(existing, p.ID) { + if sliceutil.Contains(existing, p.ID) { return false, nil } diff --git a/internal/dlna/cds.go b/internal/dlna/cds.go index 2067af19d..91e67185f 100644 --- a/internal/dlna/cds.go +++ b/internal/dlna/cds.go @@ -40,7 +40,7 @@ import ( "github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/scene" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" ) var pageSize = 100 @@ -522,7 +522,7 @@ func (me *contentDirectoryService) getPageVideos(sceneFilter *models.SceneFilter } func getPageFromID(paths []string) *int { - i := stringslice.StrIndex(paths, "page") + i := sliceutil.Index(paths, "page") if i == -1 || i+1 >= len(paths) { return nil } diff --git a/internal/dlna/whitelist.go b/internal/dlna/whitelist.go index 4bf14b20e..609ecd38f 100644 --- a/internal/dlna/whitelist.go +++ b/internal/dlna/whitelist.go @@ -4,7 +4,7 @@ import ( "sync" "time" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" ) // only keep the 10 most recent IP addresses @@ -30,7 +30,7 @@ func (m *ipWhitelistManager) addRecent(addr string) bool { m.mutex.Lock() defer m.mutex.Unlock() - i := stringslice.StrIndex(m.recentIPAddresses, addr) + i := sliceutil.Index(m.recentIPAddresses, addr) if i != -1 { if i == 0 { // don't do anything if it's already at the start diff --git a/internal/identify/identify.go b/internal/identify/identify.go index 3a8ca98ea..204d03129 100644 --- a/internal/identify/identify.go +++ b/internal/identify/identify.go @@ -329,7 +329,7 @@ func (t *SceneIdentifier) addTagToScene(ctx context.Context, s *models.Scene, ta } existing := s.TagIDs.List() - if sliceutil.Include(existing, tagID) { + if sliceutil.Contains(existing, tagID) { // skip if the scene was already tagged return nil } diff --git a/internal/identify/identify_test.go b/internal/identify/identify_test.go index 2c3232091..5dc339eac 100644 --- a/internal/identify/identify_test.go +++ b/internal/identify/identify_test.go @@ -10,7 +10,7 @@ import ( "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/models/mocks" "github.com/stashapp/stash/pkg/scraper" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -23,7 +23,7 @@ type mockSceneScraper struct { } func (s mockSceneScraper) ScrapeScenes(ctx context.Context, sceneID int) ([]*scraper.ScrapedScene, error) { - if intslice.IntInclude(s.errIDs, sceneID) { + if sliceutil.Contains(s.errIDs, sceneID) { return nil, errors.New("scrape scene error") } return s.results[sceneID], nil diff --git a/internal/identify/scene.go b/internal/identify/scene.go index eec8ce6ed..05f1ba900 100644 --- a/internal/identify/scene.go +++ b/internal/identify/scene.go @@ -11,7 +11,6 @@ import ( "github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/sliceutil" - "github.com/stashapp/stash/pkg/sliceutil/intslice" "github.com/stashapp/stash/pkg/utils" ) @@ -111,7 +110,7 @@ func (g sceneRelationships) performers(ctx context.Context, ignoreMale bool) ([] } if performerID != nil { - performerIDs = intslice.IntAppendUnique(performerIDs, *performerID) + performerIDs = sliceutil.AppendUnique(performerIDs, *performerID) } } @@ -161,7 +160,7 @@ func (g sceneRelationships) tags(ctx context.Context) ([]int, error) { return nil, fmt.Errorf("error converting tag ID %s: %w", *t.StoredID, err) } - tagIDs = intslice.IntAppendUnique(tagIDs, int(tagID)) + tagIDs = sliceutil.AppendUnique(tagIDs, int(tagID)) } else if createMissing { newTag := models.NewTag() newTag.Name = t.Name diff --git a/internal/manager/task_export.go b/internal/manager/task_export.go index c268a3eec..8ff93774a 100644 --- a/internal/manager/task_export.go +++ b/internal/manager/task_export.go @@ -24,7 +24,7 @@ import ( "github.com/stashapp/stash/pkg/movie" "github.com/stashapp/stash/pkg/performer" "github.com/stashapp/stash/pkg/scene" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/sliceutil/stringslice" "github.com/stashapp/stash/pkg/studio" "github.com/stashapp/stash/pkg/tag" @@ -301,7 +301,7 @@ func (t *ExportTask) populateMovieScenes(ctx context.Context) { } for _, s := range scenes { - t.scenes.IDs = intslice.IntAppendUnique(t.scenes.IDs, s.ID) + t.scenes.IDs = sliceutil.AppendUnique(t.scenes.IDs, s.ID) } } } @@ -337,7 +337,7 @@ func (t *ExportTask) populateGalleryImages(ctx context.Context) { } for _, i := range images { - t.images.IDs = intslice.IntAppendUnique(t.images.IDs, i.ID) + t.images.IDs = sliceutil.AppendUnique(t.images.IDs, i.ID) } } } @@ -558,26 +558,26 @@ func (t *ExportTask) exportScene(ctx context.Context, wg *sync.WaitGroup, jobCha if t.includeDependencies { if s.StudioID != nil { - t.studios.IDs = intslice.IntAppendUnique(t.studios.IDs, *s.StudioID) + t.studios.IDs = sliceutil.AppendUnique(t.studios.IDs, *s.StudioID) } - t.galleries.IDs = intslice.IntAppendUniques(t.galleries.IDs, gallery.GetIDs(galleries)) + t.galleries.IDs = sliceutil.AppendUniques(t.galleries.IDs, gallery.GetIDs(galleries)) tagIDs, err := scene.GetDependentTagIDs(ctx, tagReader, sceneMarkerReader, s) if err != nil { logger.Errorf("[scenes] <%s> error getting scene tags: %s", sceneHash, err.Error()) continue } - t.tags.IDs = intslice.IntAppendUniques(t.tags.IDs, tagIDs) + t.tags.IDs = sliceutil.AppendUniques(t.tags.IDs, tagIDs) movieIDs, err := scene.GetDependentMovieIDs(ctx, s) if err != nil { logger.Errorf("[scenes] <%s> error getting scene movies: %s", sceneHash, err.Error()) continue } - t.movies.IDs = intslice.IntAppendUniques(t.movies.IDs, movieIDs) + t.movies.IDs = sliceutil.AppendUniques(t.movies.IDs, movieIDs) - t.performers.IDs = intslice.IntAppendUniques(t.performers.IDs, performer.GetIDs(performers)) + t.performers.IDs = sliceutil.AppendUniques(t.performers.IDs, performer.GetIDs(performers)) } basename := filepath.Base(s.Path) @@ -704,12 +704,12 @@ func (t *ExportTask) exportImage(ctx context.Context, wg *sync.WaitGroup, jobCha if t.includeDependencies { if s.StudioID != nil { - t.studios.IDs = intslice.IntAppendUnique(t.studios.IDs, *s.StudioID) + t.studios.IDs = sliceutil.AppendUnique(t.studios.IDs, *s.StudioID) } - t.galleries.IDs = intslice.IntAppendUniques(t.galleries.IDs, gallery.GetIDs(imageGalleries)) - t.tags.IDs = intslice.IntAppendUniques(t.tags.IDs, tag.GetIDs(tags)) - t.performers.IDs = intslice.IntAppendUniques(t.performers.IDs, performer.GetIDs(performers)) + t.galleries.IDs = sliceutil.AppendUniques(t.galleries.IDs, gallery.GetIDs(imageGalleries)) + t.tags.IDs = sliceutil.AppendUniques(t.tags.IDs, tag.GetIDs(tags)) + t.performers.IDs = sliceutil.AppendUniques(t.performers.IDs, performer.GetIDs(performers)) } fn := newImageJSON.Filename(filepath.Base(s.Path), s.Checksum) @@ -838,11 +838,11 @@ func (t *ExportTask) exportGallery(ctx context.Context, wg *sync.WaitGroup, jobC if t.includeDependencies { if g.StudioID != nil { - t.studios.IDs = intslice.IntAppendUnique(t.studios.IDs, *g.StudioID) + t.studios.IDs = sliceutil.AppendUnique(t.studios.IDs, *g.StudioID) } - t.tags.IDs = intslice.IntAppendUniques(t.tags.IDs, tag.GetIDs(tags)) - t.performers.IDs = intslice.IntAppendUniques(t.performers.IDs, performer.GetIDs(performers)) + t.tags.IDs = sliceutil.AppendUniques(t.tags.IDs, tag.GetIDs(tags)) + t.performers.IDs = sliceutil.AppendUniques(t.performers.IDs, performer.GetIDs(performers)) } basename := "" @@ -926,7 +926,7 @@ func (t *ExportTask) exportPerformer(ctx context.Context, wg *sync.WaitGroup, jo newPerformerJSON.Tags = tag.GetNames(tags) if t.includeDependencies { - t.tags.IDs = intslice.IntAppendUniques(t.tags.IDs, tag.GetIDs(tags)) + t.tags.IDs = sliceutil.AppendUniques(t.tags.IDs, tag.GetIDs(tags)) } fn := newPerformerJSON.Filename() @@ -1116,7 +1116,7 @@ func (t *ExportTask) exportMovie(ctx context.Context, wg *sync.WaitGroup, jobCha if t.includeDependencies { if m.StudioID != nil { - t.studios.IDs = intslice.IntAppendUnique(t.studios.IDs, *m.StudioID) + t.studios.IDs = sliceutil.AppendUnique(t.studios.IDs, *m.StudioID) } } diff --git a/pkg/gallery/import.go b/pkg/gallery/import.go index 780b1e63b..fbfd58b94 100644 --- a/pkg/gallery/import.go +++ b/pkg/gallery/import.go @@ -7,7 +7,7 @@ import ( "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/models/jsonschema" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" ) type ImporterReaderWriter interface { @@ -146,8 +146,8 @@ func (i *Importer) populatePerformers(ctx context.Context) error { pluckedNames = append(pluckedNames, performer.Name) } - missingPerformers := stringslice.StrFilter(names, func(name string) bool { - return !stringslice.StrInclude(pluckedNames, name) + missingPerformers := sliceutil.Filter(names, func(name string) bool { + return !sliceutil.Contains(pluckedNames, name) }) if len(missingPerformers) > 0 { @@ -205,8 +205,8 @@ func (i *Importer) populateTags(ctx context.Context) error { pluckedNames = append(pluckedNames, tag.Name) } - missingTags := stringslice.StrFilter(names, func(name string) bool { - return !stringslice.StrInclude(pluckedNames, name) + missingTags := sliceutil.Filter(names, func(name string) bool { + return !sliceutil.Contains(pluckedNames, name) }) if len(missingTags) > 0 { diff --git a/pkg/gallery/validation.go b/pkg/gallery/validation.go index 2f46a5220..e39cf2e15 100644 --- a/pkg/gallery/validation.go +++ b/pkg/gallery/validation.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" ) type ContentsChangedError struct { @@ -42,7 +42,7 @@ func (s *Service) ValidateImageGalleryChange(ctx context.Context, i *models.Imag changedIDs = updateIDs.IDs case models.RelationshipUpdateModeSet: // get the difference between the two lists - changedIDs = intslice.IntNotIntersect(i.GalleryIDs.List(), updateIDs.IDs) + changedIDs = sliceutil.NotIntersect(i.GalleryIDs.List(), updateIDs.IDs) } galleries, err := s.Repository.FindMany(ctx, changedIDs) diff --git a/pkg/image/import.go b/pkg/image/import.go index 8b90fa8a7..8a68c49c7 100644 --- a/pkg/image/import.go +++ b/pkg/image/import.go @@ -7,7 +7,7 @@ import ( "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/models/jsonschema" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" ) type GalleryFinder interface { @@ -229,8 +229,8 @@ func (i *Importer) populatePerformers(ctx context.Context) error { pluckedNames = append(pluckedNames, performer.Name) } - missingPerformers := stringslice.StrFilter(names, func(name string) bool { - return !stringslice.StrInclude(pluckedNames, name) + missingPerformers := sliceutil.Filter(names, func(name string) bool { + return !sliceutil.Contains(pluckedNames, name) }) if len(missingPerformers) > 0 { @@ -365,8 +365,8 @@ func importTags(ctx context.Context, tagWriter models.TagFinderCreator, names [] pluckedNames = append(pluckedNames, tag.Name) } - missingTags := stringslice.StrFilter(names, func(name string) bool { - return !stringslice.StrInclude(pluckedNames, name) + missingTags := sliceutil.Filter(names, func(name string) bool { + return !sliceutil.Contains(pluckedNames, name) }) if len(missingTags) > 0 { diff --git a/pkg/image/scan.go b/pkg/image/scan.go index 9f4aa0d57..2311ccc94 100644 --- a/pkg/image/scan.go +++ b/pkg/image/scan.go @@ -11,7 +11,7 @@ import ( "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/models/paths" "github.com/stashapp/stash/pkg/plugin" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/txn" ) @@ -355,7 +355,7 @@ func (h *ScanHandler) getGalleryToAssociate(ctx context.Context, newImage *model return nil, err } - if g != nil && !intslice.IntInclude(newImage.GalleryIDs.List(), g.ID) { + if g != nil && !sliceutil.Contains(newImage.GalleryIDs.List(), g.ID) { return g, nil } diff --git a/pkg/match/path.go b/pkg/match/path.go index 0b5aaa6ba..171d9a530 100644 --- a/pkg/match/path.go +++ b/pkg/match/path.go @@ -13,7 +13,7 @@ import ( "github.com/stashapp/stash/pkg/image" "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/scene" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" ) const ( @@ -67,7 +67,7 @@ func getPathWords(path string, trimExt bool) []string { // just use the first two characters // #2293 - need to convert to unicode runes for the substring, otherwise // the resulting string is corrupted. - ret = stringslice.StrAppendUnique(ret, string([]rune(w)[0:2])) + ret = sliceutil.AppendUnique(ret, string([]rune(w)[0:2])) } } diff --git a/pkg/models/update.go b/pkg/models/update.go index a2e248804..c841cbc8a 100644 --- a/pkg/models/update.go +++ b/pkg/models/update.go @@ -78,12 +78,12 @@ func (u *UpdateIDs) ImpactedIDs(existing []int) []int { switch u.Mode { case RelationshipUpdateModeAdd: - return intslice.IntExclude(u.IDs, existing) + return sliceutil.Exclude(u.IDs, existing) case RelationshipUpdateModeRemove: - return intslice.IntIntercect(existing, u.IDs) + return sliceutil.Intersect(existing, u.IDs) case RelationshipUpdateModeSet: // get the difference between the two lists - return intslice.IntNotIntersect(existing, u.IDs) + return sliceutil.NotIntersect(existing, u.IDs) } return nil diff --git a/pkg/performer/import.go b/pkg/performer/import.go index 9f57d97fe..afa6cd4bc 100644 --- a/pkg/performer/import.go +++ b/pkg/performer/import.go @@ -9,7 +9,7 @@ import ( "github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/models/jsonschema" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/utils" ) @@ -74,8 +74,8 @@ func importTags(ctx context.Context, tagWriter models.TagFinderCreator, names [] pluckedNames = append(pluckedNames, tag.Name) } - missingTags := stringslice.StrFilter(names, func(name string) bool { - return !stringslice.StrInclude(pluckedNames, name) + missingTags := sliceutil.Filter(names, func(name string) bool { + return !sliceutil.Contains(pluckedNames, name) }) if len(missingTags) > 0 { diff --git a/pkg/plugin/plugins.go b/pkg/plugin/plugins.go index 2f9c60dc7..8aef1b14b 100644 --- a/pkg/plugin/plugins.go +++ b/pkg/plugin/plugins.go @@ -19,7 +19,7 @@ import ( "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/plugin/common" "github.com/stashapp/stash/pkg/session" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/txn" ) @@ -140,7 +140,7 @@ func (c Cache) enabledPlugins() []Config { var ret []Config for _, p := range c.plugins { - disabled := stringslice.StrInclude(disabledPlugins, p.id) + disabled := sliceutil.Contains(disabledPlugins, p.id) if !disabled { ret = append(ret, p) @@ -153,7 +153,7 @@ func (c Cache) enabledPlugins() []Config { func (c Cache) pluginDisabled(id string) bool { disabledPlugins := c.config.GetDisabledPlugins() - return stringslice.StrInclude(disabledPlugins, id) + return sliceutil.Contains(disabledPlugins, id) } // ListPlugins returns plugin details for all of the loaded plugins. @@ -164,7 +164,7 @@ func (c Cache) ListPlugins() []*Plugin { for _, s := range c.plugins { p := s.toPlugin() - disabled := stringslice.StrInclude(disabledPlugins, p.ID) + disabled := sliceutil.Contains(disabledPlugins, p.ID) p.Enabled = !disabled ret = append(ret, p) @@ -276,7 +276,7 @@ func (c Cache) executePostHooks(ctx context.Context, hookType HookTriggerEnum, h hooks := p.getHooks(hookType) // don't revisit a plugin we've already visited // only log if there's hooks that we're skipping - if len(hooks) > 0 && stringslice.StrInclude(visitedPlugins, p.id) { + if len(hooks) > 0 && sliceutil.Contains(visitedPlugins, p.id) { logger.Debugf("plugin ID '%s' already triggered, not re-triggering", p.id) continue } diff --git a/pkg/scene/export.go b/pkg/scene/export.go index 90419e2c4..22ebd99c4 100644 --- a/pkg/scene/export.go +++ b/pkg/scene/export.go @@ -10,7 +10,7 @@ import ( "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/models/json" "github.com/stashapp/stash/pkg/models/jsonschema" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/utils" ) @@ -125,7 +125,7 @@ func GetDependentTagIDs(ctx context.Context, tags TagFinder, markerReader models } for _, tt := range t { - ret = intslice.IntAppendUnique(ret, tt.ID) + ret = sliceutil.AppendUnique(ret, tt.ID) } sm, err := markerReader.FindBySceneID(ctx, scene.ID) @@ -134,14 +134,14 @@ func GetDependentTagIDs(ctx context.Context, tags TagFinder, markerReader models } for _, smm := range sm { - ret = intslice.IntAppendUnique(ret, smm.PrimaryTagID) + ret = sliceutil.AppendUnique(ret, smm.PrimaryTagID) smmt, err := tags.FindBySceneMarkerID(ctx, smm.ID) if err != nil { return nil, fmt.Errorf("invalid tags for scene marker: %v", err) } for _, smmtt := range smmt { - ret = intslice.IntAppendUnique(ret, smmtt.ID) + ret = sliceutil.AppendUnique(ret, smmtt.ID) } } diff --git a/pkg/scene/import.go b/pkg/scene/import.go index 8c67cecdf..bc61fba59 100644 --- a/pkg/scene/import.go +++ b/pkg/scene/import.go @@ -7,7 +7,7 @@ import ( "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/models/jsonschema" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/utils" ) @@ -246,8 +246,8 @@ func (i *Importer) populatePerformers(ctx context.Context) error { pluckedNames = append(pluckedNames, performer.Name) } - missingPerformers := stringslice.StrFilter(names, func(name string) bool { - return !stringslice.StrInclude(pluckedNames, name) + missingPerformers := sliceutil.Filter(names, func(name string) bool { + return !sliceutil.Contains(pluckedNames, name) }) if len(missingPerformers) > 0 { @@ -442,8 +442,8 @@ func importTags(ctx context.Context, tagWriter models.TagFinderCreator, names [] pluckedNames = append(pluckedNames, tag.Name) } - missingTags := stringslice.StrFilter(names, func(name string) bool { - return !stringslice.StrInclude(pluckedNames, name) + missingTags := sliceutil.Filter(names, func(name string) bool { + return !sliceutil.Contains(pluckedNames, name) }) if len(missingTags) > 0 { diff --git a/pkg/scene/merge.go b/pkg/scene/merge.go index 8934f5515..4d5a68c25 100644 --- a/pkg/scene/merge.go +++ b/pkg/scene/merge.go @@ -9,16 +9,16 @@ import ( "github.com/stashapp/stash/pkg/fsutil" "github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/txn" ) func (s *Service) Merge(ctx context.Context, sourceIDs []int, destinationID int, scenePartial models.ScenePartial) error { // ensure source ids are unique - sourceIDs = intslice.IntAppendUniques(nil, sourceIDs) + sourceIDs = sliceutil.AppendUniques(nil, sourceIDs) // ensure destination is not in source list - if intslice.IntInclude(sourceIDs, destinationID) { + if sliceutil.Contains(sourceIDs, destinationID) { return errors.New("destination scene cannot be in source list") } diff --git a/pkg/scraper/mapped.go b/pkg/scraper/mapped.go index 99c8d5b31..2a44e30d6 100644 --- a/pkg/scraper/mapped.go +++ b/pkg/scraper/mapped.go @@ -16,7 +16,7 @@ import ( "github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" ) type mappedQuery interface { @@ -730,8 +730,8 @@ func (c mappedScraperAttrConfig) concatenateResults(nodes []string) string { } func (c mappedScraperAttrConfig) cleanResults(nodes []string) []string { - cleaned := stringslice.StrUnique(nodes) // remove duplicate values - cleaned = stringslice.StrDelete(cleaned, "") // remove empty values + cleaned := sliceutil.Unique(nodes) // remove duplicate values + cleaned = sliceutil.Delete(cleaned, "") // remove empty values return cleaned } diff --git a/pkg/session/session.go b/pkg/session/session.go index 9fcb87549..d5218155f 100644 --- a/pkg/session/session.go +++ b/pkg/session/session.go @@ -8,7 +8,7 @@ import ( "github.com/gorilla/securecookie" "github.com/gorilla/sessions" "github.com/stashapp/stash/pkg/logger" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" ) type key int @@ -179,7 +179,7 @@ func GetVisitedPlugins(ctx context.Context) []string { func AddVisitedPlugin(ctx context.Context, pluginID string) context.Context { curVal := GetVisitedPlugins(ctx) - curVal = stringslice.StrAppendUnique(curVal, pluginID) + curVal = sliceutil.AppendUnique(curVal, pluginID) return setVisitedPlugins(ctx, curVal) } diff --git a/pkg/sliceutil/collections.go b/pkg/sliceutil/collections.go index 454038e17..87b2c5939 100644 --- a/pkg/sliceutil/collections.go +++ b/pkg/sliceutil/collections.go @@ -1,20 +1,7 @@ package sliceutil -import "reflect" - -// Exclude removes all instances of any value in toExclude from the vs -// slice. It returns the new or unchanged slice. -func Exclude[T comparable](vs []T, toExclude []T) []T { - var ret []T - for _, v := range vs { - if !Include(toExclude, v) { - ret = append(ret, v) - } - } - - return ret -} - +// Index returns the first index of the provided value in the provided +// slice. It returns -1 if it is not found. func Index[T comparable](vs []T, t T) int { for i, v := range vs { if v == t { @@ -24,23 +11,24 @@ func Index[T comparable](vs []T, t T) int { return -1 } -func Include[T comparable](vs []T, t T) bool { +// Contains returns whether the vs slice contains t. +func Contains[T comparable](vs []T, t T) bool { return Index(vs, t) >= 0 } -// IntAppendUnique appends toAdd to the vs int slice if toAdd does not already -// exist in the slice. It returns the new or unchanged int slice. +// AppendUnique appends toAdd to the vs slice if toAdd does not already +// exist in the slice. It returns the new or unchanged slice. func AppendUnique[T comparable](vs []T, toAdd T) []T { - if Include(vs, toAdd) { + if Contains(vs, toAdd) { return vs } return append(vs, toAdd) } -// IntAppendUniques appends a slice of values to the vs slice. It only -// appends values that do not already exist in the slice. It returns the new or -// unchanged slice. +// AppendUniques appends a slice of values to the vs slice. It only +// appends values that do not already exist in the slice. +// It returns the new or unchanged slice. func AppendUniques[T comparable](vs []T, toAdd []T) []T { for _, v := range toAdd { vs = AppendUnique(vs, v) @@ -49,51 +37,90 @@ func AppendUniques[T comparable](vs []T, toAdd []T) []T { return vs } -// SliceSame returns true if the two provided lists have the same elements, -// regardless of order. Panics if either parameter is not a slice. -func SliceSame(a, b interface{}) bool { - v1 := reflect.ValueOf(a) - v2 := reflect.ValueOf(b) - - if (v1.IsValid() && v1.Kind() != reflect.Slice) || (v2.IsValid() && v2.Kind() != reflect.Slice) { - panic("not a slice") +// Exclude returns a copy of the vs slice, excluding all values +// that are also present in the toExclude slice. +func Exclude[T comparable](vs []T, toExclude []T) []T { + var ret []T + for _, v := range vs { + if !Contains(toExclude, v) { + ret = append(ret, v) + } } - v1Len := 0 - v2Len := 0 + return ret +} - v1Valid := v1.IsValid() - v2Valid := v2.IsValid() - - if v1Valid { - v1Len = v1.Len() +// Unique returns a copy of the vs slice, with non-unique values removed. +func Unique[T comparable](vs []T) []T { + distinctValues := make(map[T]struct{}) + var ret []T + for _, v := range vs { + if _, exists := distinctValues[v]; !exists { + distinctValues[v] = struct{}{} + ret = append(ret, v) + } } - if v2Valid { - v2Len = v2.Len() + return ret +} + +// Delete returns a copy of the vs slice with toDel values removed. +func Delete[T comparable](vs []T, toDel T) []T { + var ret []T + for _, v := range vs { + if v != toDel { + ret = append(ret, v) + } + } + return ret +} + +// Intersect returns a slice containing values that exist in both provided slices. +func Intersect[T comparable](a []T, b []T) []T { + var ret []T + for _, v := range a { + if Contains(b, v) { + ret = append(ret, v) + } } - if !v1Valid || !v2Valid { - return v1Len == v2Len + return ret +} + +// NotIntersect returns a slice containing values that do not exist in both provided slices. +func NotIntersect[T comparable](a []T, b []T) []T { + var ret []T + for _, v := range a { + if !Contains(b, v) { + ret = append(ret, v) + } } - if v1Len != v2Len { + for _, v := range b { + if !Contains(a, v) { + ret = append(ret, v) + } + } + + return ret +} + +// SliceSame returns true if the two provided slices have equal elements, +// regardless of order. +func SliceSame[T comparable](a []T, b []T) bool { + if len(a) != len(b) { return false } - if v1.Type() != v2.Type() { - return false - } - - visited := make(map[int]bool) - for i := 0; i < v1.Len(); i++ { + visited := make(map[int]struct{}) + for i := range a { found := false - for j := 0; j < v2.Len(); j++ { - if visited[j] { + for j := range b { + if _, exists := visited[j]; exists { continue } - if reflect.DeepEqual(v1.Index(i).Interface(), v2.Index(j).Interface()) { + if a[i] == b[j] { found = true - visited[j] = true + visited[j] = struct{}{} break } } @@ -105,3 +132,24 @@ func SliceSame(a, b interface{}) bool { return true } + +// Filter returns a slice containing the elements of the vs slice +// that meet the condition specified by f. +func Filter[T any](vs []T, f func(T) bool) []T { + var ret []T + for _, v := range vs { + if f(v) { + ret = append(ret, v) + } + } + return ret +} + +// Filter returns the result of applying f to each element of the vs slice. +func Map[T any, V any](vs []T, f func(T) V) []V { + ret := make([]V, len(vs)) + for i, v := range vs { + ret[i] = f(v) + } + return ret +} diff --git a/pkg/sliceutil/collections_test.go b/pkg/sliceutil/collections_test.go index cfd93c86f..70d34946f 100644 --- a/pkg/sliceutil/collections_test.go +++ b/pkg/sliceutil/collections_test.go @@ -1,32 +1,21 @@ package sliceutil -import "testing" +import ( + "testing" + + "github.com/stretchr/testify/assert" +) func TestSliceSame(t *testing.T) { - objs := []struct { - a string - b int - }{ - {"1", 2}, - {"1", 2}, - {"2", 1}, - } - tests := []struct { name string - a interface{} - b interface{} + a []int + b []int want bool }{ {"nil values", nil, nil, true}, {"empty", []int{}, []int{}, true}, {"nil and empty", nil, []int{}, true}, - { - "different type", - []string{"1"}, - []int{1}, - false, - }, { "different length", []int{1, 2, 3}, @@ -69,24 +58,11 @@ func TestSliceSame(t *testing.T) { []int{1, 1, 2, 2, 3}, false, }, - { - "structs equal", - objs[0:1], - objs[0:1], - true, - }, - { - "structs not equal", - objs[0:2], - objs[1:3], - false, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := SliceSame(tt.a, tt.b); got != tt.want { - t.Errorf("SliceSame() = %v, want %v", got, tt.want) - } + got := SliceSame(tt.a, tt.b) + assert.Equal(t, tt.want, got) }) } } diff --git a/pkg/sliceutil/intslice/int_collections.go b/pkg/sliceutil/intslice/int_collections.go index a4df048f5..91a983eb6 100644 --- a/pkg/sliceutil/intslice/int_collections.go +++ b/pkg/sliceutil/intslice/int_collections.go @@ -2,87 +2,6 @@ package intslice import "strconv" -// IntIndex returns the first index of the provided int value in the provided -// int slice. It returns -1 if it is not found. -func IntIndex(vs []int, t int) int { - for i, v := range vs { - if v == t { - return i - } - } - return -1 -} - -// IntInclude returns true if the provided int value exists in the provided int -// slice. -func IntInclude(vs []int, t int) bool { - return IntIndex(vs, t) >= 0 -} - -// IntAppendUnique appends toAdd to the vs int slice if toAdd does not already -// exist in the slice. It returns the new or unchanged int slice. -func IntAppendUnique(vs []int, toAdd int) []int { - if IntInclude(vs, toAdd) { - return vs - } - - return append(vs, toAdd) -} - -// IntAppendUniques appends a slice of int values to the vs int slice. It only -// appends values that do not already exist in the slice. It returns the new or -// unchanged int slice. -func IntAppendUniques(vs []int, toAdd []int) []int { - for _, v := range toAdd { - vs = IntAppendUnique(vs, v) - } - - return vs -} - -// IntExclude removes all instances of any value in toExclude from the vs int -// slice. It returns the new or unchanged int slice. -func IntExclude(vs []int, toExclude []int) []int { - var ret []int - for _, v := range vs { - if !IntInclude(toExclude, v) { - ret = append(ret, v) - } - } - - return ret -} - -// IntIntercect returns a slice of ints containing values that exist in both provided slices. -func IntIntercect(v1, v2 []int) []int { - var ret []int - for _, v := range v1 { - if IntInclude(v2, v) { - ret = append(ret, v) - } - } - - return ret -} - -// IntNotIntersect returns a slice of ints containing values that do not exist in both provided slices. -func IntNotIntersect(v1, v2 []int) []int { - var ret []int - for _, v := range v1 { - if !IntInclude(v2, v) { - ret = append(ret, v) - } - } - - for _, v := range v2 { - if !IntInclude(v1, v) { - ret = append(ret, v) - } - } - - return ret -} - // IntSliceToStringSlice converts a slice of ints to a slice of strings. func IntSliceToStringSlice(ss []int) []string { ret := make([]string, len(ss)) diff --git a/pkg/sliceutil/stringslice/string_collections.go b/pkg/sliceutil/stringslice/string_collections.go index 3c66c5c48..051fe1d9e 100644 --- a/pkg/sliceutil/stringslice/string_collections.go +++ b/pkg/sliceutil/stringslice/string_collections.go @@ -5,97 +5,6 @@ import ( "strings" ) -// https://gobyexample.com/collection-functions - -func StrIndex(vs []string, t string) int { - for i, v := range vs { - if v == t { - return i - } - } - return -1 -} - -func StrInclude(vs []string, t string) bool { - return StrIndex(vs, t) >= 0 -} - -func StrFilter(vs []string, f func(string) bool) []string { - vsf := make([]string, 0) - for _, v := range vs { - if f(v) { - vsf = append(vsf, v) - } - } - return vsf -} - -func StrMap(vs []string, f func(string) string) []string { - vsm := make([]string, len(vs)) - for i, v := range vs { - vsm[i] = f(v) - } - return vsm -} - -// StrAppendUnique appends toAdd to the vs string slice if toAdd does not already -// exist in the slice. It returns the new or unchanged string slice. -func StrAppendUnique(vs []string, toAdd string) []string { - if StrInclude(vs, toAdd) { - return vs - } - - return append(vs, toAdd) -} - -// StrAppendUniques appends a slice of string values to the vs string slice. It only -// appends values that do not already exist in the slice. It returns the new or -// unchanged string slice. -func StrAppendUniques(vs []string, toAdd []string) []string { - for _, v := range toAdd { - vs = StrAppendUnique(vs, v) - } - - return vs -} - -// StrExclude removes all instances of any value in toExclude from the vs string -// slice. It returns the new or unchanged string slice. -func StrExclude(vs []string, toExclude []string) []string { - var ret []string - for _, v := range vs { - if !StrInclude(toExclude, v) { - ret = append(ret, v) - } - } - - return ret -} - -// StrUnique returns the vs string slice with non-unique values removed. -func StrUnique(vs []string) []string { - distinctValues := make(map[string]struct{}) - var ret []string - for _, v := range vs { - if _, exists := distinctValues[v]; !exists { - distinctValues[v] = struct{}{} - ret = append(ret, v) - } - } - return ret -} - -// StrDelete returns the vs string slice with toDel values removed. -func StrDelete(vs []string, toDel string) []string { - var ret []string - for _, v := range vs { - if v != toDel { - ret = append(ret, v) - } - } - return ret -} - // StringSliceToIntSlice converts a slice of strings to a slice of ints. // Returns an error if any values cannot be parsed. func StringSliceToIntSlice(ss []string) ([]int, error) { diff --git a/pkg/sqlite/gallery.go b/pkg/sqlite/gallery.go index 371aca324..a305b1b25 100644 --- a/pkg/sqlite/gallery.go +++ b/pkg/sqlite/gallery.go @@ -12,7 +12,7 @@ import ( "github.com/doug-martin/goqu/v9/exp" "github.com/jmoiron/sqlx" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "gopkg.in/guregu/null.v4" "gopkg.in/guregu/null.v4/zero" ) @@ -343,7 +343,7 @@ func (qb *GalleryStore) FindMany(ctx context.Context, ids []int) ([]*models.Gall } for _, s := range unsorted { - i := intslice.IntIndex(ids, s.ID) + i := sliceutil.Index(ids, s.ID) galleries[i] = s } diff --git a/pkg/sqlite/gallery_chapter.go b/pkg/sqlite/gallery_chapter.go index c8999cd43..f0d9c5298 100644 --- a/pkg/sqlite/gallery_chapter.go +++ b/pkg/sqlite/gallery_chapter.go @@ -11,7 +11,7 @@ import ( "github.com/jmoiron/sqlx" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" ) const ( @@ -162,7 +162,7 @@ func (qb *GalleryChapterStore) FindMany(ctx context.Context, ids []int) ([]*mode } for _, s := range unsorted { - i := intslice.IntIndex(ids, s.ID) + i := sliceutil.Index(ids, s.ID) ret[i] = s } diff --git a/pkg/sqlite/image.go b/pkg/sqlite/image.go index 7a2e58ca4..45de02e6e 100644 --- a/pkg/sqlite/image.go +++ b/pkg/sqlite/image.go @@ -9,7 +9,7 @@ import ( "github.com/jmoiron/sqlx" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "gopkg.in/guregu/null.v4" "gopkg.in/guregu/null.v4/zero" @@ -323,7 +323,7 @@ func (qb *ImageStore) FindMany(ctx context.Context, ids []int) ([]*models.Image, } for _, s := range unsorted { - i := intslice.IntIndex(ids, s.ID) + i := sliceutil.Index(ids, s.ID) images[i] = s } diff --git a/pkg/sqlite/migrations/42_postmigrate.go b/pkg/sqlite/migrations/42_postmigrate.go index 235687f92..afb0db9e7 100644 --- a/pkg/sqlite/migrations/42_postmigrate.go +++ b/pkg/sqlite/migrations/42_postmigrate.go @@ -10,7 +10,7 @@ import ( "github.com/jmoiron/sqlx" "github.com/stashapp/stash/pkg/logger" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/sqlite" ) @@ -136,7 +136,7 @@ func (m *schema42Migrator) migratePerformerAliases(id int, aliases string) error } // remove duplicates - aliasList = stringslice.StrAppendUniques(nil, aliasList) + aliasList = sliceutil.AppendUniques(nil, aliasList) // insert aliases into table for _, alias := range aliasList { diff --git a/pkg/sqlite/movies.go b/pkg/sqlite/movies.go index 169ee9885..6dc03f9fb 100644 --- a/pkg/sqlite/movies.go +++ b/pkg/sqlite/movies.go @@ -13,7 +13,7 @@ import ( "gopkg.in/guregu/null.v4/zero" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" ) const ( @@ -204,7 +204,7 @@ func (qb *MovieStore) FindMany(ctx context.Context, ids []int) ([]*models.Movie, } for _, s := range unsorted { - i := intslice.IntIndex(ids, s.ID) + i := sliceutil.Index(ids, s.ID) ret[i] = s } diff --git a/pkg/sqlite/performer.go b/pkg/sqlite/performer.go index 758faad20..a63529420 100644 --- a/pkg/sqlite/performer.go +++ b/pkg/sqlite/performer.go @@ -12,7 +12,7 @@ import ( "github.com/doug-martin/goqu/v9/exp" "github.com/jmoiron/sqlx" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/utils" "gopkg.in/guregu/null.v4" "gopkg.in/guregu/null.v4/zero" @@ -336,7 +336,7 @@ func (qb *PerformerStore) FindMany(ctx context.Context, ids []int) ([]*models.Pe } for _, s := range unsorted { - i := intslice.IntIndex(ids, s.ID) + i := sliceutil.Index(ids, s.ID) ret[i] = s } diff --git a/pkg/sqlite/saved_filter.go b/pkg/sqlite/saved_filter.go index 6b92b7657..e4369bda5 100644 --- a/pkg/sqlite/saved_filter.go +++ b/pkg/sqlite/saved_filter.go @@ -13,7 +13,7 @@ import ( "github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" ) const ( @@ -182,7 +182,7 @@ func (qb *SavedFilterStore) FindMany(ctx context.Context, ids []int, ignoreNotFo } for _, s := range unsorted { - i := intslice.IntIndex(ids, s.ID) + i := sliceutil.Index(ids, s.ID) ret[i] = s } diff --git a/pkg/sqlite/scene.go b/pkg/sqlite/scene.go index 74a2b2651..b576b54eb 100644 --- a/pkg/sqlite/scene.go +++ b/pkg/sqlite/scene.go @@ -18,7 +18,7 @@ import ( "gopkg.in/guregu/null.v4/zero" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/utils" ) @@ -456,7 +456,7 @@ func (qb *SceneStore) FindMany(ctx context.Context, ids []int) ([]*models.Scene, } for _, s := range unsorted { - i := intslice.IntIndex(ids, s.ID) + i := sliceutil.Index(ids, s.ID) scenes[i] = s } @@ -1819,7 +1819,7 @@ func (qb *SceneStore) FindDuplicates(ctx context.Context, distance int, duration var sceneIds []int for _, strId := range strIds { if intId, err := strconv.Atoi(strId); err == nil { - sceneIds = intslice.IntAppendUnique(sceneIds, intId) + sceneIds = sliceutil.AppendUnique(sceneIds, intId) } } // filter out diff --git a/pkg/sqlite/scene_marker.go b/pkg/sqlite/scene_marker.go index e36c17c4f..9476541a4 100644 --- a/pkg/sqlite/scene_marker.go +++ b/pkg/sqlite/scene_marker.go @@ -11,7 +11,7 @@ import ( "github.com/jmoiron/sqlx" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" ) const sceneMarkerTable = "scene_markers" @@ -171,7 +171,7 @@ func (qb *SceneMarkerStore) FindMany(ctx context.Context, ids []int) ([]*models. } for _, s := range unsorted { - i := intslice.IntIndex(ids, s.ID) + i := sliceutil.Index(ids, s.ID) ret[i] = s } diff --git a/pkg/sqlite/scene_marker_test.go b/pkg/sqlite/scene_marker_test.go index 0dd8e249f..fffd0b88f 100644 --- a/pkg/sqlite/scene_marker_test.go +++ b/pkg/sqlite/scene_marker_test.go @@ -9,7 +9,7 @@ import ( "testing" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/sliceutil/stringslice" "github.com/stretchr/testify/assert" ) @@ -112,7 +112,7 @@ func verifyIDs(t *testing.T, modifier models.CriterionModifier, values []int, re case models.CriterionModifierNotEquals: foundAll := true for _, v := range values { - if !intslice.IntInclude(results, v) { + if !sliceutil.Contains(results, v) { foundAll = false break } diff --git a/pkg/sqlite/scene_test.go b/pkg/sqlite/scene_test.go index a3fb5eeed..71cdd77b1 100644 --- a/pkg/sqlite/scene_test.go +++ b/pkg/sqlite/scene_test.go @@ -15,7 +15,7 @@ import ( "time" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stretchr/testify/assert" ) @@ -2376,12 +2376,12 @@ func TestSceneQueryPath(t *testing.T) { mustInclude := indexesToIDs(sceneIDs, tt.mustInclude) mustExclude := indexesToIDs(sceneIDs, tt.mustExclude) - missing := intslice.IntExclude(mustInclude, got.IDs) + missing := sliceutil.Exclude(mustInclude, got.IDs) if len(missing) > 0 { t.Errorf("SceneStore.TestSceneQueryPath() missing expected IDs: %v", missing) } - notExcluded := intslice.IntIntercect(mustExclude, got.IDs) + notExcluded := sliceutil.Intersect(mustExclude, got.IDs) if len(notExcluded) > 0 { t.Errorf("SceneStore.TestSceneQueryPath() expected IDs to be excluded: %v", notExcluded) } diff --git a/pkg/sqlite/setup_test.go b/pkg/sqlite/setup_test.go index 71c64e052..9f5f75f5b 100644 --- a/pkg/sqlite/setup_test.go +++ b/pkg/sqlite/setup_test.go @@ -15,7 +15,7 @@ import ( "time" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/sqlite" "github.com/stashapp/stash/pkg/txn" @@ -1506,7 +1506,7 @@ func getTagMarkerCount(id int) int { count := 0 idx := indexFromID(tagIDs, id) for _, s := range markerSpecs { - if s.primaryTagIdx == idx || intslice.IntInclude(s.tagIdxs, idx) { + if s.primaryTagIdx == idx || sliceutil.Contains(s.tagIdxs, idx) { count++ } } diff --git a/pkg/sqlite/studio.go b/pkg/sqlite/studio.go index fec08ed45..51f65d973 100644 --- a/pkg/sqlite/studio.go +++ b/pkg/sqlite/studio.go @@ -13,7 +13,7 @@ import ( "gopkg.in/guregu/null.v4/zero" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/studio" ) @@ -240,7 +240,7 @@ func (qb *StudioStore) FindMany(ctx context.Context, ids []int) ([]*models.Studi } for _, s := range unsorted { - i := intslice.IntIndex(ids, s.ID) + i := sliceutil.Index(ids, s.ID) ret[i] = s } diff --git a/pkg/sqlite/table.go b/pkg/sqlite/table.go index 510b5877c..795fda7ef 100644 --- a/pkg/sqlite/table.go +++ b/pkg/sqlite/table.go @@ -14,8 +14,6 @@ import ( "github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/sliceutil" - "github.com/stashapp/stash/pkg/sliceutil/intslice" - "github.com/stashapp/stash/pkg/sliceutil/stringslice" ) type table struct { @@ -202,7 +200,7 @@ func (t *joinTable) insertJoins(ctx context.Context, id int, foreignIDs []int) e defer stmt.Close() // eliminate duplicates - foreignIDs = intslice.IntAppendUniques(nil, foreignIDs) + foreignIDs = sliceutil.AppendUniques(nil, foreignIDs) for _, fk := range foreignIDs { if _, err := tx.ExecStmt(ctx, stmt, id, fk); err != nil { @@ -229,7 +227,7 @@ func (t *joinTable) addJoins(ctx context.Context, id int, foreignIDs []int) erro } // only add foreign keys that are not already present - foreignIDs = intslice.IntExclude(foreignIDs, fks) + foreignIDs = sliceutil.Exclude(foreignIDs, fks) return t.insertJoins(ctx, id, foreignIDs) } @@ -440,7 +438,7 @@ func (t *stringTable) addJoins(ctx context.Context, id int, v []string) error { } // only add values that are not already present - filtered := stringslice.StrExclude(v, existing) + filtered := sliceutil.Exclude(v, existing) return t.insertJoins(ctx, id, filtered) } diff --git a/pkg/sqlite/tag.go b/pkg/sqlite/tag.go index ace5f8346..7eaff3d5c 100644 --- a/pkg/sqlite/tag.go +++ b/pkg/sqlite/tag.go @@ -14,7 +14,7 @@ import ( "gopkg.in/guregu/null.v4/zero" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" ) const ( @@ -205,7 +205,7 @@ func (qb *TagStore) FindMany(ctx context.Context, ids []int) ([]*models.Tag, err } for _, s := range unsorted { - i := intslice.IntIndex(ids, s.ID) + i := sliceutil.Index(ids, s.ID) ret[i] = s } diff --git a/pkg/utils/phash.go b/pkg/utils/phash.go index 395d86f93..413293c65 100644 --- a/pkg/utils/phash.go +++ b/pkg/utils/phash.go @@ -5,7 +5,7 @@ import ( "strconv" "github.com/corona10/goimagehash" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" ) type Phash struct { @@ -58,7 +58,7 @@ func findNeighbors(bucket int, neighbors []int, hashes []*Phash, scenes *[]int) hash := hashes[id] if hash.Bucket == -1 { hash.Bucket = bucket - *scenes = intslice.IntAppendUnique(*scenes, hash.SceneID) + *scenes = sliceutil.AppendUnique(*scenes, hash.SceneID) findNeighbors(bucket, hash.Neighbors, hashes, scenes) } } diff --git a/scripts/test_db_generator/makeTestDB.go b/scripts/test_db_generator/makeTestDB.go index 32b66f289..66174862f 100644 --- a/scripts/test_db_generator/makeTestDB.go +++ b/scripts/test_db_generator/makeTestDB.go @@ -21,7 +21,7 @@ import ( "github.com/stashapp/stash/pkg/fsutil" "github.com/stashapp/stash/pkg/hash/md5" "github.com/stashapp/stash/pkg/models" - "github.com/stashapp/stash/pkg/sliceutil/intslice" + "github.com/stashapp/stash/pkg/sliceutil" "github.com/stashapp/stash/pkg/sqlite" "github.com/stashapp/stash/pkg/txn" ) @@ -554,7 +554,7 @@ func makeMarkers(n int) { tags := getRandomTags(ctx, 0, 5) // remove primary tag - tags = intslice.IntExclude(tags, []int{marker.PrimaryTagID}) + tags = sliceutil.Exclude(tags, []int{marker.PrimaryTagID}) if err := repo.SceneMarker.UpdateTags(ctx, created.ID, tags); err != nil { return err } @@ -642,12 +642,12 @@ func getRandomPerformers(ctx context.Context) []int { // } // for _, pp := range p { - // ret = intslice.IntAppendUnique(ret, pp.ID) + // ret = sliceutil.AppendUnique(ret, pp.ID) // } // } for i := 0; i < n; i++ { - ret = intslice.IntAppendUnique(ret, rand.Intn(c.Performers)+1) + ret = sliceutil.AppendUnique(ret, rand.Intn(c.Performers)+1) } return ret @@ -677,12 +677,12 @@ func getRandomTags(ctx context.Context, min, max int) []int { // } // for _, tt := range t { - // ret = intslice.IntAppendUnique(ret, tt.ID) + // ret = sliceutil.AppendUnique(ret, tt.ID) // } // } for i := 0; i < n; i++ { - ret = intslice.IntAppendUnique(ret, rand.Intn(c.Tags)+1) + ret = sliceutil.AppendUnique(ret, rand.Intn(c.Tags)+1) } return ret @@ -699,12 +699,12 @@ func getRandomImages(ctx context.Context) []int { // } // for _, tt := range t { - // ret = intslice.IntAppendUnique(ret, tt.ID) + // ret = sliceutil.AppendUnique(ret, tt.ID) // } // } for i := 0; i < n; i++ { - ret = intslice.IntAppendUnique(ret, rand.Intn(c.Images)+1) + ret = sliceutil.AppendUnique(ret, rand.Intn(c.Images)+1) } return ret