< Summary - Jellyfin

Information
Class: MediaBrowser.Controller.Entities.InternalItemsQuery
Assembly: MediaBrowser.Controller
File(s): /srv/git/jellyfin/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
Line coverage
87%
Covered lines: 168
Uncovered lines: 24
Coverable lines: 192
Total lines: 595
Line coverage: 87.5%
Branch coverage
48%
Covered branches: 101
Total branches: 209
Branch coverage: 48.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 3/8/2026 - 12:12:00 AM Line coverage: 98.4% (64/65) Branch coverage: 83.3% (5/6) Total lines: 3923/14/2026 - 12:13:58 AM Line coverage: 73.9% (71/96) Branch coverage: 38.7% (12/31) Total lines: 4635/4/2026 - 12:15:16 AM Line coverage: 74.7% (74/99) Branch coverage: 38.7% (12/31) Total lines: 4845/16/2026 - 12:15:55 AM Line coverage: 75.2% (76/101) Branch coverage: 38.7% (12/31) Total lines: 4925/20/2026 - 12:15:44 AM Line coverage: 75.2% (76/101) Branch coverage: 35.4% (11/31) Total lines: 4925/22/2026 - 12:15:17 AM Line coverage: 75.4% (77/102) Branch coverage: 35.4% (11/31) Total lines: 4996/6/2026 - 12:15:50 AM Line coverage: 75.4% (77/102) Branch coverage: 38.7% (12/31) Total lines: 4996/18/2026 - 12:16:24 AM Line coverage: 87.5% (168/192) Branch coverage: 48.3% (101/209) Total lines: 595 3/8/2026 - 12:12:00 AM Line coverage: 98.4% (64/65) Branch coverage: 83.3% (5/6) Total lines: 3923/14/2026 - 12:13:58 AM Line coverage: 73.9% (71/96) Branch coverage: 38.7% (12/31) Total lines: 4635/4/2026 - 12:15:16 AM Line coverage: 74.7% (74/99) Branch coverage: 38.7% (12/31) Total lines: 4845/16/2026 - 12:15:55 AM Line coverage: 75.2% (76/101) Branch coverage: 38.7% (12/31) Total lines: 4925/20/2026 - 12:15:44 AM Line coverage: 75.2% (76/101) Branch coverage: 35.4% (11/31) Total lines: 4925/22/2026 - 12:15:17 AM Line coverage: 75.4% (77/102) Branch coverage: 35.4% (11/31) Total lines: 4996/6/2026 - 12:15:50 AM Line coverage: 75.4% (77/102) Branch coverage: 38.7% (12/31) Total lines: 4996/18/2026 - 12:16:24 AM Line coverage: 87.5% (168/192) Branch coverage: 48.3% (101/209) Total lines: 595

Coverage delta

Coverage delta 45 -45

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
.ctor(...)100%22100%
get_HasFilters()50%178178100%
set_Parent(...)100%22100%
SetUser(...)50%2294.11%
ApplyFilters(...)28%3152522.58%

File(s)

/srv/git/jellyfin/MediaBrowser.Controller/Entities/InternalItemsQuery.cs

#LineLine coverage
 1#pragma warning disable CA1044, CA1819, CA2227, CS1591
 2
 3using System;
 4using System.Collections.Generic;
 5using System.Linq;
 6using Diacritics.Extensions;
 7using Jellyfin.Data;
 8using Jellyfin.Data.Enums;
 9using Jellyfin.Database.Implementations.Entities;
 10using Jellyfin.Database.Implementations.Enums;
 11using MediaBrowser.Controller.Dto;
 12using MediaBrowser.Model.Entities;
 13using MediaBrowser.Model.Querying;
 14
 15namespace MediaBrowser.Controller.Entities
 16{
 17    public class InternalItemsQuery
 18    {
 19        public InternalItemsQuery()
 20        {
 57221            AlbumArtistIds = [];
 57222            AlbumIds = [];
 57223            AncestorIds = [];
 57224            LinkedChildAncestorIds = [];
 57225            ArtistIds = [];
 57226            BlockUnratedItems = [];
 57227            BoxSetLibraryFolders = [];
 57228            ChannelIds = [];
 57229            ContributingArtistIds = [];
 57230            DtoOptions = new DtoOptions();
 57231            EnableTotalRecordCount = true;
 57232            ExcludeArtistIds = [];
 57233            ExcludeInheritedTags = [];
 57234            IncludeInheritedTags = [];
 57235            ExcludeItemIds = [];
 57236            ExcludeItemTypes = [];
 57237            ExcludeTags = [];
 57238            GenreIds = [];
 57239            Genres = [];
 57240            GroupByPresentationUniqueKey = true;
 57241            ImageTypes = [];
 57242            IncludeItemTypes = [];
 57243            ItemIds = [];
 57244            OwnerIds = [];
 57245            ExtraTypes = [];
 57246            MediaTypes = [];
 57247            OfficialRatings = [];
 57248            OrderBy = [];
 57249            OwnerIds = [];
 57250            PersonIds = [];
 57251            PersonTypes = [];
 57252            PresetViews = [];
 57253            SeriesStatuses = [];
 57254            SourceTypes = [];
 57255            StudioIds = [];
 57256            Tags = [];
 57257            TopParentIds = [];
 57258            TrailerTypes = [];
 57259            VideoTypes = [];
 57260            Years = [];
 57261            SkipDeserialization = false;
 57262            AudioLanguages = [];
 57263            SubtitleLanguages = [];
 57264        }
 65
 66        public InternalItemsQuery(User? user)
 1167            : this()
 68        {
 1169            if (user is not null)
 70            {
 571                SetUser(user);
 72            }
 1173        }
 74
 75        /// <summary>
 76        /// Gets a value indicating whether the query carries any criteria that narrows the
 77        /// result set, as opposed to user context, pagination, sorting or DTO options.
 78        /// </summary>
 79        public bool HasFilters =>
 380            IncludeItemTypes.Length > 0
 381            || ExcludeItemTypes.Length > 0
 382            || Genres.Count > 0
 383            || GenreIds.Count > 0
 384            || Years.Length > 0
 385            || Tags.Length > 0
 386            || ExcludeTags.Length > 0
 387            || OfficialRatings.Length > 0
 388            || StudioIds.Length > 0
 389            || ArtistIds.Length > 0
 390            || AlbumArtistIds.Length > 0
 391            || ContributingArtistIds.Length > 0
 392            || ExcludeArtistIds.Length > 0
 393            || AlbumIds.Length > 0
 394            || PersonIds.Length > 0
 395            || PersonTypes.Length > 0
 396            || MediaTypes.Length > 0
 397            || VideoTypes.Length > 0
 398            || ImageTypes.Length > 0
 399            || SeriesStatuses.Length > 0
 3100            || ItemIds.Length > 0
 3101            || ExcludeItemIds.Length > 0
 3102            || AudioLanguages.Count > 0
 3103            || SubtitleLanguages.Count > 0
 3104            || LinkedChildAncestorIds.Length > 0
 3105            || AncestorIds.Length > 0
 3106            || IsFavorite.HasValue
 3107            || IsFavoriteOrLiked.HasValue
 3108            || IsLiked.HasValue
 3109            || IsPlayed.HasValue
 3110            || IsResumable.HasValue
 3111            || IsFolder.HasValue
 3112            || IsMissing.HasValue
 3113            || IsUnaired.HasValue
 3114            || IsSpecialSeason.HasValue
 3115            || Is3D.HasValue
 3116            || IsHD.HasValue
 3117            || Is4K.HasValue
 3118            || IsLocked.HasValue
 3119            || IsPlaceHolder.HasValue
 3120            || IsMovie.HasValue
 3121            || IsSports.HasValue
 3122            || IsKids.HasValue
 3123            || IsNews.HasValue
 3124            || IsSeries.HasValue
 3125            || IsAiring.HasValue
 3126            || IsVirtualItem.HasValue
 3127            || HasImdbId.HasValue
 3128            || HasTmdbId.HasValue
 3129            || HasTvdbId.HasValue
 3130            || HasOverview.HasValue
 3131            || HasOfficialRating.HasValue
 3132            || HasParentalRating.HasValue
 3133            || HasThemeSong.HasValue
 3134            || HasThemeVideo.HasValue
 3135            || HasSubtitles.HasValue
 3136            || HasSpecialFeature.HasValue
 3137            || HasTrailer.HasValue
 3138            || HasChapterImages.HasValue
 3139            || MinCriticRating.HasValue
 3140            || MinCommunityRating.HasValue
 3141            || MinParentalRating is not null
 3142            || MinIndexNumber.HasValue
 3143            || MinParentAndIndexNumber.HasValue
 3144            || IndexNumber.HasValue
 3145            || ParentIndexNumber.HasValue
 3146            || AiredDuringSeason.HasValue
 3147            || MinWidth.HasValue
 3148            || MinHeight.HasValue
 3149            || MaxWidth.HasValue
 3150            || MaxHeight.HasValue
 3151            || MinPremiereDate.HasValue
 3152            || MaxPremiereDate.HasValue
 3153            || MinStartDate.HasValue
 3154            || MaxStartDate.HasValue
 3155            || MinEndDate.HasValue
 3156            || MaxEndDate.HasValue
 3157            || MinDateCreated.HasValue
 3158            || MinDateLastSaved.HasValue
 3159            || MinDateLastSavedForUser.HasValue
 3160            || AdjacentTo.HasValue
 3161            || !string.IsNullOrEmpty(NameStartsWith)
 3162            || !string.IsNullOrEmpty(NameStartsWithOrGreater)
 3163            || !string.IsNullOrEmpty(NameLessThan)
 3164            || !string.IsNullOrEmpty(NameContains)
 3165            || !string.IsNullOrEmpty(MinSortName)
 3166            || !string.IsNullOrEmpty(Name)
 3167            || !string.IsNullOrEmpty(Person)
 3168            || !string.IsNullOrEmpty(SearchTerm)
 3169            || !string.IsNullOrEmpty(Path);
 170
 171        public bool Recursive { get; set; }
 172
 173        public int? StartIndex { get; set; }
 174
 175        public int? Limit { get; set; }
 176
 177        public User? User { get; set; }
 178
 179        public bool? IsFolder { get; set; }
 180
 181        public bool? IsFavorite { get; set; }
 182
 183        public bool? IsFavoriteOrLiked { get; set; }
 184
 185        public bool? IsLiked { get; set; }
 186
 187        public bool? IsPlayed { get; set; }
 188
 189        public bool? IsResumable { get; set; }
 190
 191        public bool? IncludeItemsByName { get; set; }
 192
 193        public MediaType[] MediaTypes { get; set; }
 194
 195        public BaseItemKind[] IncludeItemTypes { get; set; }
 196
 197        public BaseItemKind[] ExcludeItemTypes { get; set; }
 198
 199        public string[] ExcludeTags { get; set; }
 200
 201        public string[] ExcludeInheritedTags { get; set; }
 202
 203        public string[] IncludeInheritedTags { get; set; }
 204
 205        public IReadOnlyList<string> Genres { get; set; }
 206
 207        public bool? IsSpecialSeason { get; set; }
 208
 209        public bool? IsMissing { get; set; }
 210
 211        public bool? IsUnaired { get; set; }
 212
 213        public bool? CollapseBoxSetItems { get; set; }
 214
 215        /// <summary>
 216        /// Gets or sets the item types that should be collapsed into box sets.
 217        /// When empty, all types are collapsed. When set, only items of these types are replaced by their parent box se
 218        /// </summary>
 219        public BaseItemKind[] CollapseBoxSetItemTypes { get; set; } = [];
 220
 221        public string? NameStartsWithOrGreater { get; set; }
 222
 223        public string? NameStartsWith { get; set; }
 224
 225        public string? NameLessThan { get; set; }
 226
 227        public string? NameContains { get; set; }
 228
 229        public string? MinSortName { get; set; }
 230
 231        public string? PresentationUniqueKey { get; set; }
 232
 233        public string? Path { get; set; }
 234
 235        public string? Name { get; set; }
 236
 237        public bool? UseRawName { get; set; }
 238
 239        public string? Person { get; set; }
 240
 241        public Guid[] PersonIds { get; set; }
 242
 243        public Guid[] ItemIds { get; set; }
 244
 245        public Guid[] OwnerIds { get; set; }
 246
 247        public ExtraType[] ExtraTypes { get; set; }
 248
 249        public Guid[] ExcludeItemIds { get; set; }
 250
 251        public Guid? AdjacentTo { get; set; }
 252
 253        public string[] PersonTypes { get; set; }
 254
 255        public bool? Is3D { get; set; }
 256
 257        public bool? IsHD { get; set; }
 258
 259        public bool? IsLocked { get; set; }
 260
 261        public bool? IsPlaceHolder { get; set; }
 262
 263        public bool? HasImdbId { get; set; }
 264
 265        public bool? HasOverview { get; set; }
 266
 267        public bool? HasTmdbId { get; set; }
 268
 269        public bool? HasOfficialRating { get; set; }
 270
 271        public bool? HasTvdbId { get; set; }
 272
 273        public bool? HasThemeSong { get; set; }
 274
 275        public bool? HasThemeVideo { get; set; }
 276
 277        public bool? HasSubtitles { get; set; }
 278
 279        public bool? HasSpecialFeature { get; set; }
 280
 281        public bool? HasTrailer { get; set; }
 282
 283        public bool? HasParentalRating { get; set; }
 284
 285        public Guid[] StudioIds { get; set; }
 286
 287        public IReadOnlyList<Guid> GenreIds { get; set; }
 288
 289        public ImageType[] ImageTypes { get; set; }
 290
 291        public VideoType[] VideoTypes { get; set; }
 292
 293        public UnratedItem[] BlockUnratedItems { get; set; }
 294
 295        public int[] Years { get; set; }
 296
 297        public string[] Tags { get; set; }
 298
 299        public string[] OfficialRatings { get; set; }
 300
 301        public DateTime? MinPremiereDate { get; set; }
 302
 303        public DateTime? MaxPremiereDate { get; set; }
 304
 305        public DateTime? MinStartDate { get; set; }
 306
 307        public DateTime? MaxStartDate { get; set; }
 308
 309        public DateTime? MinEndDate { get; set; }
 310
 311        public DateTime? MaxEndDate { get; set; }
 312
 313        public bool? IsAiring { get; set; }
 314
 315        public bool? IsMovie { get; set; }
 316
 317        public bool? IsSports { get; set; }
 318
 319        public bool? IsKids { get; set; }
 320
 321        public bool? IsNews { get; set; }
 322
 323        public bool? IsSeries { get; set; }
 324
 325        public int? MinIndexNumber { get; set; }
 326
 327        /// <summary>
 328        /// Gets or sets the minimum ParentIndexNumber and IndexNumber.
 329        /// </summary>
 330        /// <remarks>
 331        /// It produces this where clause:
 332        /// <para>(ParentIndexNumber = X and IndexNumber >= Y) or ParentIndexNumber > X.
 333        /// </para>
 334        /// </remarks>
 335        public (int ParentIndexNumber, int IndexNumber)? MinParentAndIndexNumber { get; set; }
 336
 337        public int? AiredDuringSeason { get; set; }
 338
 339        public double? MinCriticRating { get; set; }
 340
 341        public double? MinCommunityRating { get; set; }
 342
 343        public IReadOnlyList<Guid> ChannelIds { get; set; }
 344
 345        public int? ParentIndexNumber { get; set; }
 346
 347        public int? ParentIndexNumberNotEquals { get; set; }
 348
 349        public int? IndexNumber { get; set; }
 350
 351        public ParentalRatingScore? MinParentalRating { get; set; }
 352
 353        public ParentalRatingScore? MaxParentalRating { get; set; }
 354
 355        public bool? HasDeadParentId { get; set; }
 356
 357        public bool? IsVirtualItem { get; set; }
 358
 359        public Guid ParentId { get; set; }
 360
 361        public BaseItemKind? ParentType { get; set; }
 362
 363        public Guid[] AncestorIds { get; set; }
 364
 365        /// <summary>
 366        /// Gets or sets a list of ancestor ids that the item's linked children must descend from.
 367        /// Useful for filtering BoxSets/Playlists to only those that contain items from a specific library.
 368        /// </summary>
 369        public Guid[] LinkedChildAncestorIds { get; set; }
 370
 371        public Guid[] TopParentIds { get; set; }
 372
 373        public CollectionType?[] PresetViews { get; set; }
 374
 375        public TrailerType[] TrailerTypes { get; set; }
 376
 377        public SourceType[] SourceTypes { get; set; }
 378
 379        public SeriesStatus[] SeriesStatuses { get; set; }
 380
 381        public string? ExternalSeriesId { get; set; }
 382
 383        public string? ExternalId { get; set; }
 384
 385        public Guid[] AlbumIds { get; set; }
 386
 387        public Guid[] ArtistIds { get; set; }
 388
 389        public Guid[] ExcludeArtistIds { get; set; }
 390
 391        public string? AncestorWithPresentationUniqueKey { get; set; }
 392
 393        public string? SeriesPresentationUniqueKey { get; set; }
 394
 395        public bool GroupByPresentationUniqueKey { get; set; }
 396
 397        public bool GroupBySeriesPresentationUniqueKey { get; set; }
 398
 399        public bool EnableTotalRecordCount { get; set; }
 400
 401        public bool ForceDirect { get; set; }
 402
 403        public Dictionary<string, string>? ExcludeProviderIds { get; set; }
 404
 405        public bool EnableGroupByMetadataKey { get; set; }
 406
 407        public bool? HasChapterImages { get; set; }
 408
 409        public IReadOnlyList<(ItemSortBy OrderBy, SortOrder SortOrder)> OrderBy { get; set; }
 410
 411        public DateTime? MinDateCreated { get; set; }
 412
 413        public DateTime? MinDateLastSaved { get; set; }
 414
 415        public DateTime? MinDateLastSavedForUser { get; set; }
 416
 417        public DtoOptions DtoOptions { get; set; }
 418
 419        public string? HasNoAudioTrackWithLanguage { get; set; }
 420
 421        public string? HasNoInternalSubtitleTrackWithLanguage { get; set; }
 422
 423        public string? HasNoExternalSubtitleTrackWithLanguage { get; set; }
 424
 425        public string? HasNoSubtitleTrackWithLanguage { get; set; }
 426
 427        public bool? IsDeadArtist { get; set; }
 428
 429        public bool? IsDeadStudio { get; set; }
 430
 431        public bool? IsDeadGenre { get; set; }
 432
 433        public bool? IsDeadPerson { get; set; }
 434
 435        /// <summary>
 436        /// Gets or sets a value indicating whether album sub-folders should be returned if they exist.
 437        /// </summary>
 438        public bool? DisplayAlbumFolders { get; set; }
 439
 440        public BaseItem? Parent
 441        {
 442            set
 443            {
 258444                if (value is null)
 445                {
 60446                    ParentId = Guid.Empty;
 60447                    ParentType = null;
 448                }
 449                else
 450                {
 198451                    ParentId = value.Id;
 198452                    ParentType = value.GetBaseItemKind();
 453                }
 198454            }
 455        }
 456
 457        public Dictionary<string, string>? HasAnyProviderId { get; set; }
 458
 459        public Dictionary<string, string[]>? HasAnyProviderIds { get; set; }
 460
 461        public Guid[] AlbumArtistIds { get; set; }
 462
 463        public Guid[] BoxSetLibraryFolders { get; set; }
 464
 465        public Guid[] ContributingArtistIds { get; set; }
 466
 467        public bool? HasAired { get; set; }
 468
 469        public bool? HasOwnerId { get; set; }
 470
 471        /// <summary>
 472        /// Gets or sets a value indicating whether to include items with an OwnerId
 473        /// (additional parts, alternate versions) that are normally excluded from general queries.
 474        /// </summary>
 475        public bool IncludeOwnedItems { get; set; }
 476
 477        public bool? Is4K { get; set; }
 478
 479        public int? MaxHeight { get; set; }
 480
 481        public int? MaxWidth { get; set; }
 482
 483        public int? MinHeight { get; set; }
 484
 485        public int? MinWidth { get; set; }
 486
 487        public string? SearchTerm { get; set; }
 488
 489        public string? SeriesTimerId { get; set; }
 490
 491        public bool SkipDeserialization { get; set; }
 492
 493        public bool IncludeExtras { get; set; }
 494
 495        public IReadOnlyList<string> AudioLanguages { get; set; }
 496
 497        public IReadOnlyList<string> SubtitleLanguages { get; set; }
 498
 499        public void SetUser(User user)
 500        {
 5501            var maxRating = user.MaxParentalRatingScore;
 5502            if (maxRating.HasValue)
 503            {
 0504                MaxParentalRating = new(maxRating.Value, user.MaxParentalRatingSubScore);
 505            }
 506
 5507            var other = UnratedItem.Other.ToString();
 5508            BlockUnratedItems = user.GetPreference(PreferenceKind.BlockUnratedItems)
 5509                .Where(i => i != other)
 5510                .Select(e => Enum.Parse<UnratedItem>(e, true)).ToArray();
 511
 5512            ExcludeInheritedTags = user.GetPreference(PreferenceKind.BlockedTags)
 5513                .Where(tag => !string.IsNullOrWhiteSpace(tag))
 5514                .Select(tag => tag.RemoveDiacritics().ToLowerInvariant())
 5515                .ToArray();
 516
 5517            IncludeInheritedTags = user.GetPreference(PreferenceKind.AllowedTags)
 5518                .Where(tag => !string.IsNullOrWhiteSpace(tag))
 5519                .Select(tag => tag.RemoveDiacritics().ToLowerInvariant())
 5520                .ToArray();
 521
 5522            User = user;
 5523        }
 524
 525        public void ApplyFilters(ItemFilter[] filters)
 526        {
 527            static void ThrowConflictingFilters()
 528                => throw new ArgumentException("Conflicting filters", nameof(filters));
 529
 15530            foreach (var filter in filters)
 531            {
 532                switch (filter)
 533                {
 534                    case ItemFilter.IsFolder:
 1535                        if (filters.Contains(ItemFilter.IsNotFolder))
 536                        {
 1537                            ThrowConflictingFilters();
 538                        }
 539
 0540                        IsFolder = true;
 0541                        break;
 542                    case ItemFilter.IsNotFolder:
 0543                        if (filters.Contains(ItemFilter.IsFolder))
 544                        {
 0545                            ThrowConflictingFilters();
 546                        }
 547
 0548                        IsFolder = false;
 0549                        break;
 550                    case ItemFilter.IsUnplayed:
 0551                        if (filters.Contains(ItemFilter.IsPlayed))
 552                        {
 0553                            ThrowConflictingFilters();
 554                        }
 555
 0556                        IsPlayed = false;
 0557                        break;
 558                    case ItemFilter.IsPlayed:
 1559                        if (filters.Contains(ItemFilter.IsUnplayed))
 560                        {
 1561                            ThrowConflictingFilters();
 562                        }
 563
 0564                        IsPlayed = true;
 0565                        break;
 566                    case ItemFilter.IsFavorite:
 0567                        IsFavorite = true;
 0568                        break;
 569                    case ItemFilter.IsResumable:
 0570                        IsResumable = true;
 0571                        break;
 572                    case ItemFilter.Likes:
 1573                        if (filters.Contains(ItemFilter.Dislikes))
 574                        {
 1575                            ThrowConflictingFilters();
 576                        }
 577
 0578                        IsLiked = true;
 0579                        break;
 580                    case ItemFilter.Dislikes:
 0581                        if (filters.Contains(ItemFilter.Likes))
 582                        {
 0583                            ThrowConflictingFilters();
 584                        }
 585
 0586                        IsLiked = false;
 0587                        break;
 588                    case ItemFilter.IsFavoriteOrLikes:
 0589                        IsFavoriteOrLiked = true;
 590                        break;
 591                }
 592            }
 3593        }
 594    }
 595}