Пример #1
0
        public PartialFindResult <EntryForApiContract> GetList(
            string query,
            int[] tagIds,
            string[] tags,
            bool childTags,
            EntryStatus?status,
            int start, int maxResults, bool getTotalCount,
            EntrySortRule sort,
            NameMatchMode nameMatchMode,
            EntryOptionalFields fields,
            ContentLanguagePreference lang,
            bool searchTags   = false,
            bool searchEvents = false
            )
        {
            var textQuery       = SearchTextQuery.Create(query, nameMatchMode);
            var artistTextQuery = ArtistSearchTextQuery.Create(query, nameMatchMode);             // Can't use the existing words collection here as they are noncanonized

            return(repository.HandleQuery(ctx => {
                // Get all applicable names per entry type
                var artistQuery = ctx.OfType <Artist>().Query()
                                  .Where(a => !a.Deleted)
                                  .WhereHasName_Canonized(artistTextQuery)
                                  .WhereHasTags(tagIds, childTags)
                                  .WhereHasTags(tags)
                                  .WhereStatusIs(status);

                var artistNames = artistQuery
                                  .OrderBy(sort, lang)
                                  .Take(start + maxResults)
                                  .SelectEntryBase(lang, EntryType.Artist)
                                  .ToArray();

                var albumQuery = ctx.OfType <Album>().Query()
                                 .Where(a => !a.Deleted)
                                 .WhereHasName(textQuery)
                                 .WhereHasTags(tagIds, childTags)
                                 .WhereHasTags(tags)
                                 .WhereStatusIs(status);

                var albumNames = albumQuery
                                 .OrderBy(sort, lang, null)
                                 .Take(start + maxResults)
                                 .SelectEntryBase(lang, EntryType.Album)
                                 .ToArray();

                var songQuery = ctx.OfType <Song>().Query()
                                .Where(a => !a.Deleted)
                                .WhereHasName(textQuery)
                                .WhereHasTags(tagIds, childTags)
                                .WhereHasTags(tags)
                                .WhereStatusIs(status);

                var songNames = songQuery
                                .OrderBy(sort, lang)
                                .Take(start + maxResults)
                                .SelectEntryBase(lang, EntryType.Song)
                                .ToArray();

                var eventQuery = searchEvents ? ctx.OfType <ReleaseEvent>().Query()
                                 .WhereNotDeleted()
                                 .WhereHasName(textQuery)
                                 .WhereHasTags(tagIds, childTags)
                                 .WhereStatusIs(status) : null;

                var eventNames = searchEvents ? eventQuery
                                 .OrderBy(sort, lang, null)
                                 .Take(start + maxResults)
                                 .SelectEntryBase(lang, EntryType.ReleaseEvent)
                                 .ToArray() : null;

                var tagQuery = searchTags ? ctx.OfType <Tag>().Query()
                               .WhereNotDeleted()
                               .WhereHasName(textQuery)
                               .WhereStatusIs(status) : null;

                var tagNames = searchTags ? tagQuery
                               .OrderBy(sort, lang)
                               .Take(start + maxResults)
                               .SelectEntryBase(lang, EntryType.Tag)
                               .ToArray() : null;

                // Get page of combined names
                var entryNames = artistNames
                                 .Concat(albumNames)
                                 .Concat(songNames)
                                 .Concat(tagNames ?? new DataContracts.EntryBaseContract[0])
                                 .Concat(eventNames ?? new DataContracts.EntryBaseContract[0])
                                 .OrderBy(e => e.DefaultName)
                                 .Skip(start)
                                 .Take(maxResults)
                                 .ToArray();

                var artistIds = entryNames.Where(e => e.EntryType == EntryType.Artist).Select(a => a.Id).ToArray();
                var albumIds = entryNames.Where(e => e.EntryType == EntryType.Album).Select(a => a.Id).ToArray();
                var songIds = entryNames.Where(e => e.EntryType == EntryType.Song).Select(a => a.Id).ToArray();
                var searchedTagIds = searchTags ? entryNames.Where(e => e.EntryType == EntryType.Tag).Select(a => a.Id).ToArray() : new int[0];
                var eventIds = searchEvents ? entryNames.Where(e => e.EntryType == EntryType.ReleaseEvent).Select(a => a.Id).ToArray() : new int[0];

                // Get the actual entries in the page
                var artists = artistIds.Any() ? ctx.OfType <Artist>().Query()
                              .Where(a => artistIds.Contains(a.Id))
                              .ToArray()
                              .Select(a => new EntryForApiContract(a, lang, entryThumbPersister, fields)) : new EntryForApiContract[0];

                var albums = albumIds.Any() ? ctx.OfType <Album>().Query()
                             .Where(a => albumIds.Contains(a.Id))
                             .ToArray()
                             .Select(a => new EntryForApiContract(a, lang, entryThumbPersister, fields)) : new EntryForApiContract[0];

                var songs = songIds.Any() ? ctx.OfType <Song>().Query()
                            .Where(a => songIds.Contains(a.Id))
                            .ToArray()
                            .Select(a => new EntryForApiContract(a, lang, fields)) : new EntryForApiContract[0];

                var searchedTags = searchTags && searchedTagIds.Any() ? ctx.OfType <Tag>().Query()
                                   .Where(a => searchedTagIds.Contains(a.Id))
                                   .ToArray()
                                   .Select(a => new EntryForApiContract(a, lang, entryImagePersisterOld, fields)) : new EntryForApiContract[0];

                var events = searchEvents && eventIds.Any() ? ctx.OfType <ReleaseEvent>().Query()
                             .Where(a => eventIds.Contains(a.Id))
                             .ToArray()
                             .Select(a => new EntryForApiContract(a, lang, entryThumbPersister, fields)) : new EntryForApiContract[0];

                // Merge and sort the final list
                var entries = artists.Concat(albums).Concat(songs).Concat(searchedTags).Concat(events);

                if (sort == EntrySortRule.Name)
                {
                    entries = entries.OrderBy(a => a.Name);
                }

                if (sort == EntrySortRule.AdditionDate)
                {
                    entries = entries.OrderByDescending(a => a.CreateDate);
                }

                if (sort == EntrySortRule.ActivityDate)
                {
                    entries = entries.OrderByDescending(a => a.ActivityDate);
                }

                var count = 0;

                if (getTotalCount)
                {
                    var artistCount =
                        (artistNames.Length >= maxResults ? artistQuery.Count() : artistNames.Length);

                    var albumCount =
                        (albumNames.Length >= maxResults ? albumQuery.Count() : albumNames.Length);

                    var songCount =
                        (songNames.Length >= maxResults ? songQuery.Count() : songNames.Length);

                    var tagCount =
                        searchTags ? (tagNames.Length >= maxResults ? tagQuery.Count() : tagNames.Length) : 0;

                    var eventCount =
                        searchEvents ? (eventNames.Length >= maxResults ? eventQuery.Count() : eventNames.Length) : 0;

                    count = artistCount + albumCount + songCount + tagCount + eventCount;
                }

                return new PartialFindResult <EntryForApiContract>(entries.ToArray(), count);
            }));
        }