protected override object DoDeserializeValue(XmlReader reader, bool isSimpleValue)
        {
            if (SoapHelper.ReadEmptyStartElement(reader)) // Read start of enclosing element
            {
                return(null);
            }
            if (!reader.MoveToAttribute("type"))
            {
                throw new ArgumentException("Cannot deserialize value, 'type' attribute missing");
            }
            String typeStr = reader.ReadContentAsString();
            Type   type    = Type.GetType(typeStr);

            reader.MoveToElement();
            HomogenousMap result = new HomogenousMap(type, typeof(int));

            if (SoapHelper.ReadEmptyStartElement(reader, "Values"))
            {
                return(result);
            }
            while (reader.NodeType != XmlNodeType.EndElement)
            {
                result.Add(MediaItemAspect.DeserializeValue(reader, type), MediaItemAspect.DeserializeValue(reader, typeof(int)));
            }
            reader.ReadEndElement(); // End of enclosing element
            return(result);
        }
예제 #2
0
        public override ICollection <FilterValue> GetAvailableValues(IEnumerable <Guid> necessaryMIATypeIds, IFilter selectAttributeFilter, IFilter filter)
        {
            IContentDirectory cd = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;

            if (cd == null)
            {
                throw new NotConnectedException("The MediaLibrary is not connected");
            }
            HomogenousMap       valueGroups = cd.GetValueGroups(_attributeType, selectAttributeFilter, ProjectionFunction.None, necessaryMIATypeIds, filter, true);
            IList <FilterValue> result      = new List <FilterValue>(valueGroups.Count);
            int numEmptyEntries             = 0;

            foreach (KeyValuePair <object, object> group in valueGroups)
            {
                string name = GetDisplayName(group.Key);
                if (name == string.Empty)
                {
                    numEmptyEntries += (int)group.Value;
                }
                else
                {
                    result.Add(new FilterValue(name, new RelationalFilter(_attributeType, RelationalOperator.EQ, group.Key), null, (int)group.Value, this));
                }
            }
            if (numEmptyEntries > 0)
            {
                result.Insert(0, new FilterValue(Consts.RES_VALUE_EMPTY_TITLE, new EmptyFilter(_attributeType), null, numEmptyEntries, this));
            }
            return(result);
        }
예제 #3
0
        public override void Initialise(string sortCriteria, uint?offset = null, uint?count = null)
        {
            base.Initialise(sortCriteria, offset, count);

            HomogenousMap items = GetItems(sortCriteria);

            foreach (KeyValuePair <object, object> item in items.OrderBy(y => y.Key.ToString()))
            {
                try
                {
                    if (item.Key == null)
                    {
                        continue;
                    }
                    string title = item.Key.ToString();
                    string key   = Id + ":" + title;

                    Add(new MediaLibraryYearItem(key, title, _necessaryMiaTypeIds, _optionalMiaTypeIds, Client));
                }
                catch (Exception ex)
                {
                    Logger.Error("Item '{0}' could not be added", ex, item.Key);
                }
            }
        }
예제 #4
0
        public static Task <IList <WebGenre> > ProcessAsync(IOwinContext context, WebSortField?sort, WebSortOrder?order)
        {
            ISet <Guid> necessaryMIATypes = new HashSet <Guid>();

            necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
            necessaryMIATypes.Add(SeriesAspect.ASPECT_ID);

            HomogenousMap items = MediaLibraryAccess.GetGroups(context, necessaryMIATypes, GenreAspect.ATTR_GENRE);

            if (items.Count == 0)
            {
                return(Task.FromResult <IList <WebGenre> >(new List <WebGenre>()));
            }

            var output = (from item in items where item.Key is string select new WebGenre {
                Title = item.Key.ToString()
            });

            // sort
            if (sort != null && order != null)
            {
                output = output.SortWebGenre(sort, order);
            }

            return(Task.FromResult <IList <WebGenre> >(output.ToList()));
        }
예제 #5
0
        // We produce hardcoded titles for this filter criterion like "< 1950", "1950-1960", ... Should we use language
        // resources for them?

        #region Base overrides

        public override ICollection <FilterValue> GetAvailableValues(IEnumerable <Guid> necessaryMIATypeIds, IFilter selectAttributeFilter, IFilter filter)
        {
            // We'll do the grouping here at the client. We could also implement a grouping function for decades at the server,
            // but that seems to be not better since it increases the server code size, the server workload, it complicates the
            // call structure and it doesn't bring us an advantage
            IContentDirectory cd = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;

            if (cd == null)
            {
                throw new NotConnectedException("The MediaLibrary is not connected");
            }

            HomogenousMap valueGroups = cd.GetValueGroups(MediaAspect.ATTR_RECORDINGTIME, null, ProjectionFunction.DateToYear,
                                                          necessaryMIATypeIds, filter, true, ShowVirtualSetting.ShowVirtualMedia(necessaryMIATypeIds));
            IList <FilterValue> result = new List <FilterValue>(valueGroups.Count);
            int numEmptyEntries        = 0;
            IDictionary <int, int> decadesToNumItems = new Dictionary <int, int>();

            foreach (KeyValuePair <object, object> group in valueGroups)
            {
                int?year = (int?)group.Key;
                if (year.HasValue)
                {
                    int yearVal = year.Value;
                    int decade  = yearVal / 10;
                    int numItems;
                    if (!decadesToNumItems.TryGetValue(decade, out numItems))
                    {
                        numItems = 0;
                    }
                    decadesToNumItems[decade] = numItems + (int)group.Value;
                }
                else
                {
                    numEmptyEntries += (int)group.Value;
                }
            }
            if (numEmptyEntries > 0)
            {
                result.Insert(0, new FilterValue(Consts.RES_VALUE_EMPTY_TITLE, new EmptyFilter(MediaAspect.ATTR_RECORDINGTIME), null, numEmptyEntries, this));
            }
            for (int decade = 0; decade < 300; decade++)
            {
                int year = decade * 10;
                int numItems;
                if (!decadesToNumItems.TryGetValue(decade, out numItems))
                {
                    continue;
                }
                result.Add(new FilterValue(year.ToString(),
                                           new BooleanCombinationFilter(BooleanOperator.And, new IFilter[]
                {
                    new RelationalFilter(MediaAspect.ATTR_RECORDINGTIME, RelationalOperator.GE, new DateTime(year, 1, 1)),
                    new RelationalFilter(MediaAspect.ATTR_RECORDINGTIME, RelationalOperator.LT, new DateTime(year + 10, 1, 1)),
                }), null, numItems, this));
            }
            return(result);
        }
        public override async Task <ICollection <FilterValue> > GetAvailableValuesAsync(IEnumerable <Guid> necessaryMIATypeIds, IFilter selectAttributeFilter, IFilter filter)
        {
            IServerConnectionManager serverConnectionManager = ServiceRegistration.Get <IServerConnectionManager>();
            IServerController        serverController        = serverConnectionManager.ServerController;

            if (serverController == null)
            {
                throw new NotConnectedException("The MediaLibrary is not connected");
            }

            IDictionary <string, string> systemNames = new Dictionary <string, string>();

            foreach (MPClientMetadata client in serverController.GetAttachedClients())
            {
                systemNames.Add(client.SystemId, client.LastClientName);
            }
            systemNames.Add(serverConnectionManager.HomeServerSystemId, serverConnectionManager.LastHomeServerName);

            IContentDirectory cd = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;

            if (cd == null)
            {
                return(new List <FilterValue>());
            }

            bool showVirtual = VirtualMediaHelper.ShowVirtualMedia(necessaryMIATypeIds);

            HomogenousMap valueGroups = await cd.GetValueGroupsAsync(ProviderResourceAspect.ATTR_SYSTEM_ID, null, ProjectionFunction.None, necessaryMIATypeIds, filter, true, showVirtual);

            IList <FilterValue> result = new List <FilterValue>(valueGroups.Count);
            int numEmptyEntries        = 0;

            foreach (KeyValuePair <object, object> group in valueGroups)
            {
                string name = group.Key as string ?? string.Empty;
                name = name.Trim();
                if (name == string.Empty)
                {
                    numEmptyEntries += (int)group.Value;
                }
                else
                {
                    string systemName;
                    if (systemNames.TryGetValue(name, out systemName) && !string.IsNullOrEmpty(systemName))
                    {
                        name = systemName;
                    }
                    result.Add(new FilterValue(name,
                                               new RelationalFilter(ProviderResourceAspect.ATTR_SYSTEM_ID, RelationalOperator.EQ, group.Key), null, (int)group.Value, this));
                }
            }
            if (numEmptyEntries > 0)
            {
                result.Insert(0, new FilterValue(Consts.RES_VALUE_EMPTY_TITLE, new EmptyFilter(ProviderResourceAspect.ATTR_SYSTEM_ID), null, numEmptyEntries, this));
            }
            return(result);
        }
        public HomogenousMap Execute()
        {
            ISQLDatabase database    = ServiceRegistration.Get <ISQLDatabase>();
            ITransaction transaction = database.BeginTransaction();

            try
            {
                using (IDbCommand command = transaction.CreateCommand())
                {
                    string          valueAlias;
                    string          groupSizeAlias;
                    string          statementStr;
                    IList <BindVar> bindVars;
                    if (_selectAttribute.Cardinality == Cardinality.Inline || _selectAttribute.Cardinality == Cardinality.ManyToOne)
                    {
                        QueryAttribute   selectAttributeQA = new QueryAttribute(_selectAttribute);
                        MainQueryBuilder builder           = new MainQueryBuilder(_miaManagement,
                                                                                  new QueryAttribute[] { selectAttributeQA }, _selectProjectionFunction,
                                                                                  _necessaryRequestedMIATypes, new MediaItemAspectMetadata[] {}, _filter, null);
                        IDictionary <QueryAttribute, string> qa2a;
                        builder.GenerateSqlGroupByStatement(out groupSizeAlias, out qa2a, out statementStr, out bindVars);
                        valueAlias = qa2a[selectAttributeQA];
                    }
                    else
                    {
                        ComplexAttributeQueryBuilder builder = new ComplexAttributeQueryBuilder(_miaManagement, _selectAttribute,
                                                                                                _selectProjectionFunction, _necessaryRequestedMIATypes, _filter);
                        builder.GenerateSqlGroupByStatement(_selectAttributeFilter, out valueAlias, out groupSizeAlias,
                                                            out statementStr, out bindVars);
                    }
                    command.CommandText = statementStr;
                    foreach (BindVar bindVar in bindVars)
                    {
                        database.AddParameter(command, bindVar.Name, bindVar.Value, bindVar.VariableType);
                    }

                    Type          valueType = _projectionValueType ?? _selectAttribute.AttributeType;
                    HomogenousMap result    = new HomogenousMap(valueType, typeof(int));
                    using (IDataReader reader = command.ExecuteReader())
                    {
                        int valueCol     = reader.GetOrdinal(valueAlias);
                        int groupSizeCol = reader.GetOrdinal(groupSizeAlias);
                        while (reader.Read())
                        {
                            result.Add(database.ReadDBValue(valueType, reader, valueCol),
                                       database.ReadDBValue <int>(reader, groupSizeCol));
                        }
                    }
                    return(result);
                }
            }
            finally
            {
                transaction.Dispose();
            }
        }
        protected override void DoSerializeValue(object value, bool forceSimpleValue, XmlWriter writer)
        {
            HomogenousMap map = (HomogenousMap)value;

            writer.WriteStartElement("Values");
            Type type = map.KeyType;

            writer.WriteAttributeString("type", type.FullName);
            foreach (KeyValuePair <object, object> kvp in map)
            {
                MediaItemAspect.SerializeValue(writer, kvp.Key, type);
                MediaItemAspect.SerializeValue(writer, kvp.Value, typeof(int));
            }
        }
        public override async Task <ICollection <FilterValue> > GetAvailableValuesAsync(IEnumerable <Guid> necessaryMIATypeIds, IFilter selectAttributeFilter, IFilter filter)
        {
            IContentDirectory cd = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;

            if (cd == null)
            {
                throw new NotConnectedException("The MediaLibrary is not connected");
            }

            bool showVirtual = VirtualMediaHelper.ShowVirtualMedia(necessaryMIATypeIds);

            HomogenousMap valueGroups = await cd.GetValueGroupsAsync(MediaAspect.ATTR_RECORDINGTIME, null, ProjectionFunction.DateToYear,
                                                                     necessaryMIATypeIds, filter, true, showVirtual);

            IList <FilterValue> result = new List <FilterValue>(valueGroups.Count);
            int numEmptyEntries        = 0;

            foreach (KeyValuePair <object, object> group in valueGroups)
            {
                int?year = (int?)group.Key;
                if (year.HasValue)
                {
                    result.Add(new FilterValue(year.Value.ToString(),
                                               new BooleanCombinationFilter(BooleanOperator.And, new IFilter[]
                    {
                        new RelationalFilter(MediaAspect.ATTR_RECORDINGTIME, RelationalOperator.GE, new DateTime(year.Value, 1, 1)),
                        new RelationalFilter(MediaAspect.ATTR_RECORDINGTIME, RelationalOperator.LT, new DateTime(year.Value + 1, 1, 1)),
                    }), null, (int)group.Value, this));
                }
                else
                {
                    numEmptyEntries += (int)group.Value;
                }
            }
            if (numEmptyEntries > 0)
            {
                result.Insert(0, new FilterValue(Consts.RES_VALUE_EMPTY_TITLE, new EmptyFilter(MediaAspect.ATTR_RECORDINGTIME), null, numEmptyEntries, this));
            }
            return(result);
        }
        public override void Initialise(string sortCriteria, uint?offset = null, uint?count = null)
        {
            base.Initialise(sortCriteria, offset, count);

            HomogenousMap items = GetItems(sortCriteria);

            foreach (var item in items.OrderBy(g => g.Key.ToString()))
            {
                try
                {
                    if (item.Key == null)
                    {
                        continue;
                    }
                    string title = item.Key.ToString();
                    string key   = Id + ":" + title;

                    if (_necessaryMIAs.Contains(MovieAspect.ASPECT_ID))
                    {
                        Add(new MediaLibraryMovieGenreItem(key, title, new RelationalFilter(GenreAspect.ATTR_GENRE, RelationalOperator.EQ, title), Client));
                    }
                    else if (_necessaryMIAs.Contains(AudioAspect.ASPECT_ID))
                    {
                        Add(new MediaLibraryMusicGenreItem(key, title, new RelationalFilter(GenreAspect.ATTR_GENRE, RelationalOperator.EQ, title), Client));
                    }
                    else if (_necessaryMIAs.Contains(AudioAlbumAspect.ASPECT_ID))
                    {
                        Add(new MediaLibraryAlbumGenreItem(key, title, new RelationalFilter(GenreAspect.ATTR_GENRE, RelationalOperator.EQ, title), Client));
                    }
                    else if (_necessaryMIAs.Contains(SeriesAspect.ASPECT_ID))
                    {
                        Add(new MediaLibrarySeriesGenreItem(key, title, new RelationalFilter(GenreAspect.ATTR_GENRE, RelationalOperator.EQ, title), Client));
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error("Item '{0}' could not be added", ex, item.Key);
                }
            }
        }
 protected override object DoDeserializeValue(XmlReader reader, bool isSimpleValue)
 {
   if (SoapHelper.ReadEmptyStartElement(reader)) // Read start of enclosing element
     return null;
   if (!reader.MoveToAttribute("type"))
     throw new ArgumentException("Cannot deserialize value, 'type' attribute missing");
   String typeStr = reader.ReadContentAsString();
   Type type = Type.GetType(typeStr);
   reader.MoveToElement();
   HomogenousMap result = new HomogenousMap(type, typeof(int));
   if (SoapHelper.ReadEmptyStartElement(reader, "Values"))
     return result;
   while (reader.NodeType != XmlNodeType.EndElement)
     result.Add(MediaItemAspect.DeserializeValue(reader, type), MediaItemAspect.DeserializeValue(reader, typeof(int)));
   reader.ReadEndElement(); // End of enclosing element
   return result;
 }
예제 #12
0
        public override async Task <ICollection <FilterValue> > GetAvailableValuesAsync(IEnumerable <Guid> necessaryMIATypeIds, IFilter selectAttributeFilter, IFilter filter)
        {
            IContentDirectory cd = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;

            if (cd == null)
            {
                throw new NotConnectedException("The MediaLibrary is not connected");
            }

            bool showVirtual = VirtualMediaHelper.ShowVirtualMedia(necessaryMIATypeIds);

            if (string.IsNullOrEmpty(CertificationHelper.DisplayMovieCertificationCountry))
            {
                HomogenousMap valueGroups = await cd.GetValueGroupsAsync(MovieAspect.ATTR_CERTIFICATION, null, ProjectionFunction.None,
                                                                         necessaryMIATypeIds, filter, true, showVirtual);

                IList <FilterValue> result = new List <FilterValue>(valueGroups.Count);
                int numEmptyEntries        = 0;
                foreach (KeyValuePair <object, object> group in valueGroups)
                {
                    string certification = (string)group.Key;
                    if (!string.IsNullOrEmpty(certification))
                    {
                        CertificationMapping cert;
                        if (CertificationMapper.TryFindMovieCertification(certification, out cert))
                        {
                            result.Add(new FilterValue(cert.CertificationId, cert.Name,
                                                       new RelationalFilter(MovieAspect.ATTR_CERTIFICATION, RelationalOperator.EQ, certification), null, (int)group.Value, this));
                        }
                    }
                    else
                    {
                        numEmptyEntries += (int)group.Value;
                    }
                }
                if (numEmptyEntries > 0)
                {
                    result.Insert(0, new FilterValue("UR", Consts.RES_VALUE_UNRATED_TITLE, new EmptyFilter(MovieAspect.ATTR_CERTIFICATION), null, numEmptyEntries, this));
                }
                return(result);
            }
            else
            {
                IList <FilterValue> result      = new List <FilterValue>();
                IFilter             emptyFilter = new EmptyFilter(MovieAspect.ATTR_CERTIFICATION);
                int numEmptyItems = await cd.CountMediaItemsAsync(necessaryMIATypeIds, BooleanCombinationFilter.CombineFilters(BooleanOperator.And, filter, emptyFilter), true, showVirtual);

                if (numEmptyItems > 0)
                {
                    result.Add(new FilterValue("UR", Consts.RES_VALUE_UNRATED_TITLE, emptyFilter, null, numEmptyItems, this));
                }
                List <string> usedFilters = new List <string>();
                foreach (var cert in CertificationMapper.GetMovieCertificationsForCountry(CertificationHelper.DisplayMovieCertificationCountry))
                {
                    IEnumerable <CertificationMapping> certs = CertificationMapper.FindAllAllowedMovieCertifications(cert.CertificationId);
                    if (certs.Count() > 0)
                    {
                        List <string> certList = new List <string>(certs.Select(c => c.CertificationId).Except(usedFilters));
                        usedFilters.AddRange(certList);
                        IFilter certFilter = new InFilter(MovieAspect.ATTR_CERTIFICATION, certList);
                        int     numItems   = await cd.CountMediaItemsAsync(necessaryMIATypeIds, BooleanCombinationFilter.CombineFilters(BooleanOperator.And, filter, certFilter), true, showVirtual);

                        result.Add(new FilterValue(cert.CertificationId, cert.Name, certFilter, null, numItems, this));
                    }
                }
                return(result);
            }
        }
    public HomogenousMap Execute()
    {
      ISQLDatabase database = ServiceRegistration.Get<ISQLDatabase>();
      ITransaction transaction = database.BeginTransaction();
      try
      {
        using (IDbCommand command = transaction.CreateCommand())
        {
          string valueAlias;
          string groupSizeAlias;
          string statementStr;
          IList<BindVar> bindVars;
          if (_selectAttribute.Cardinality == Cardinality.Inline || _selectAttribute.Cardinality == Cardinality.ManyToOne)
          {
            QueryAttribute selectAttributeQA = new QueryAttribute(_selectAttribute);
            MainQueryBuilder builder = new MainQueryBuilder(_miaManagement,
                new QueryAttribute[] {selectAttributeQA}, _selectProjectionFunction,
                _necessaryRequestedMIATypes, new MediaItemAspectMetadata[] {}, _filter, null);
            IDictionary<QueryAttribute, string> qa2a;
            builder.GenerateSqlGroupByStatement(out groupSizeAlias, out qa2a, out statementStr, out bindVars);
            valueAlias = qa2a[selectAttributeQA];
          }
          else
          {
            ComplexAttributeQueryBuilder builder = new ComplexAttributeQueryBuilder(_miaManagement, _selectAttribute,
                _selectProjectionFunction, _necessaryRequestedMIATypes, _filter);
            builder.GenerateSqlGroupByStatement(_selectAttributeFilter, out valueAlias, out groupSizeAlias,
                out statementStr, out bindVars);
          }
          command.CommandText = statementStr;
          foreach (BindVar bindVar in bindVars)
            database.AddParameter(command, bindVar.Name, bindVar.Value, bindVar.VariableType);

          Type valueType = _projectionValueType ?? _selectAttribute.AttributeType;
          HomogenousMap result = new HomogenousMap(valueType, typeof(int));
          using (IDataReader reader = command.ExecuteReader())
          {
            int valueCol = reader.GetOrdinal(valueAlias);
            int groupSizeCol = reader.GetOrdinal(groupSizeAlias);
            while (reader.Read())
              result.Add(database.ReadDBValue(valueType, reader, valueCol),
                  database.ReadDBValue<int>(reader, groupSizeCol));
          }
          return result;
        }
      }
      finally
      {
        transaction.Dispose();
      }
    }
        public override ICollection <FilterValue> GetAvailableValues(IEnumerable <Guid> necessaryMIATypeIds, IFilter selectAttributeFilter, IFilter filter)
        {
            IContentDirectory cd = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;

            if (cd == null)
            {
                throw new NotConnectedException("The MediaLibrary is not connected");
            }

            if (_necessaryMIATypeIds != null)
            {
                necessaryMIATypeIds = _necessaryMIATypeIds;
            }
            HomogenousMap valueGroups = null;
            HomogenousMap valueKeys   = null;

            if (_keyAttributeType != null)
            {
                Tuple <HomogenousMap, HomogenousMap> values = cd.GetKeyValueGroups(_keyAttributeType, _valueAttributeType, selectAttributeFilter, ProjectionFunction.None, necessaryMIATypeIds, filter, true,
                                                                                   ShowVirtualSetting.ShowVirtualMedia(necessaryMIATypeIds));
                valueGroups = values.Item1;
                valueKeys   = values.Item2;
            }
            else
            {
                valueGroups = cd.GetValueGroups(_valueAttributeType, selectAttributeFilter, ProjectionFunction.None, necessaryMIATypeIds, filter, true,
                                                ShowVirtualSetting.ShowVirtualMedia(necessaryMIATypeIds));
            }
            IList <FilterValue> result = new List <FilterValue>(valueGroups.Count);
            int numEmptyEntries        = 0;

            foreach (KeyValuePair <object, object> group in valueGroups)
            {
                if (_keyAttributeType != null)
                {
                    string name = GetDisplayName(group.Key);
                    if (name == string.Empty)
                    {
                        numEmptyEntries += (int)group.Value;
                    }
                    else
                    {
                        IFilter queryFilter = new RelationalFilter(_valueAttributeType, RelationalOperator.EQ, group.Key);
                        if (filter != null)
                        {
                            queryFilter = BooleanCombinationFilter.CombineFilters(BooleanOperator.And, queryFilter, filter);
                        }
                        result.Add(new FilterValue(valueKeys[group.Key], name, new FilteredRelationshipFilter(Guid.Empty, queryFilter), null, (int)group.Value, this));
                    }
                }
                else
                {
                    string name = GetDisplayName(group.Key);
                    if (name == string.Empty)
                    {
                        numEmptyEntries += (int)group.Value;
                    }
                    else
                    {
                        IFilter queryFilter = new RelationalFilter(_valueAttributeType, RelationalOperator.EQ, group.Key);
                        if (filter != null)
                        {
                            queryFilter = BooleanCombinationFilter.CombineFilters(BooleanOperator.And, queryFilter, filter);
                        }
                        result.Add(new FilterValue(name, new FilteredRelationshipFilter(Guid.Empty, queryFilter), null, (int)group.Value, this));
                    }
                }
            }
            if (numEmptyEntries > 0)
            {
                IFilter queryFilter = new EmptyFilter(_valueAttributeType);
                if (filter != null)
                {
                    queryFilter = BooleanCombinationFilter.CombineFilters(BooleanOperator.And, queryFilter, filter);
                }
                result.Insert(0, new FilterValue(Consts.RES_VALUE_EMPTY_TITLE, new FilteredRelationshipFilter(Guid.Empty, queryFilter), null, numEmptyEntries, this));
            }
            return(result);
        }
        public Tuple <HomogenousMap, HomogenousMap> Execute()
        {
            ISQLDatabase database    = ServiceRegistration.Get <ISQLDatabase>();
            ITransaction transaction = database.BeginTransaction();

            try
            {
                using (IDbCommand command = transaction.CreateCommand())
                {
                    string          keyAlias       = null;
                    string          valueAlias     = null;
                    string          groupSizeAlias = null;
                    string          statementStr   = null;
                    IList <BindVar> bindVars       = null;
                    if (_selectValueAttribute.Cardinality == Cardinality.Inline || _selectValueAttribute.Cardinality == Cardinality.ManyToOne)
                    {
                        List <QueryAttribute> qAttributes            = new List <QueryAttribute>();
                        QueryAttribute        selectValueAttributeQA = new QueryAttribute(_selectValueAttribute);
                        qAttributes.Add(selectValueAttributeQA);
                        QueryAttribute selectKeyAttributeQA = null;
                        if (_selectKeyAttribute != null)
                        {
                            selectKeyAttributeQA = new QueryAttribute(_selectKeyAttribute);
                            qAttributes.Add(selectKeyAttributeQA);
                        }
                        MIAQueryBuilder builder = new MIAQueryBuilder(_miaManagement, qAttributes, _selectProjectionFunction,
                                                                      _necessaryRequestedMIATypes, new MediaItemAspectMetadata[] {}, _filter, _subqueryFilter, null);
                        IDictionary <QueryAttribute, string> qa2a;
                        builder.GenerateSqlGroupByStatement(out groupSizeAlias, out qa2a, out statementStr, out bindVars);
                        valueAlias = qa2a[selectValueAttributeQA];
                        if (_selectKeyAttribute != null)
                        {
                            keyAlias = qa2a[selectKeyAttributeQA];
                        }
                    }
                    else
                    {
                        if (_selectKeyAttribute != null)
                        {
                            throw new InvalidDataException("Value attribute '{0}' does not support key value grouping", _selectValueAttribute.AttributeName);
                        }
                        ComplexAttributeQueryBuilder builder = new ComplexAttributeQueryBuilder(_miaManagement, _selectValueAttribute,
                                                                                                _selectProjectionFunction, _necessaryRequestedMIATypes, _filter, _subqueryFilter);
                        builder.GenerateSqlGroupByStatement(_selectAttributeFilter, out valueAlias, out groupSizeAlias,
                                                            out statementStr, out bindVars);
                    }
                    command.CommandText = statementStr;
                    foreach (BindVar bindVar in bindVars)
                    {
                        database.AddParameter(command, bindVar.Name, bindVar.Value, bindVar.VariableType);
                    }

                    Tuple <HomogenousMap, HomogenousMap> result = null;
                    if (_selectKeyAttribute != null)
                    {
                        Type          valueType = _projectionValueType ?? _selectValueAttribute.AttributeType;
                        Type          keyType   = _selectKeyAttribute.AttributeType;
                        HomogenousMap valueMap  = new HomogenousMap(valueType, typeof(int));
                        HomogenousMap keyMap    = new HomogenousMap(valueType, keyType);
                        using (IDataReader reader = command.ExecuteReader())
                        {
                            int keyCol       = reader.GetOrdinal(keyAlias);
                            int valueCol     = reader.GetOrdinal(valueAlias);
                            int groupSizeCol = reader.GetOrdinal(groupSizeAlias);
                            while (reader.Read())
                            {
                                if (!keyMap.ContainsKey(database.ReadDBValue(valueType, reader, valueCol)))
                                {
                                    keyMap.Add(database.ReadDBValue(valueType, reader, valueCol), database.ReadDBValue(keyType, reader, keyCol));
                                    valueMap.Add(database.ReadDBValue(valueType, reader, valueCol), database.ReadDBValue <int>(reader, groupSizeCol));
                                }
                            }
                        }
                        result = new Tuple <HomogenousMap, HomogenousMap>(valueMap, keyMap);
                    }
                    else
                    {
                        Type          valueType = _projectionValueType ?? _selectValueAttribute.AttributeType;
                        HomogenousMap valueMap  = new HomogenousMap(valueType, typeof(int));
                        using (IDataReader reader = command.ExecuteReader())
                        {
                            int valueCol     = reader.GetOrdinal(valueAlias);
                            int groupSizeCol = reader.GetOrdinal(groupSizeAlias);
                            while (reader.Read())
                            {
                                valueMap.Add(database.ReadDBValue(valueType, reader, valueCol),
                                             database.ReadDBValue <int>(reader, groupSizeCol));
                            }
                        }
                        result = new Tuple <HomogenousMap, HomogenousMap>(valueMap, null);
                    }
                    return(result);
                }
            }
            finally
            {
                transaction.Dispose();
            }
        }
        public override async Task <ICollection <FilterValue> > GetAvailableValuesAsync(IEnumerable <Guid> necessaryMIATypeIds, IFilter selectAttributeFilter, IFilter filter)
        {
            IContentDirectory cd = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;

            if (cd == null)
            {
                throw new NotConnectedException("The MediaLibrary is not connected");
            }

            bool            showVirtual = VirtualMediaHelper.ShowVirtualMedia(necessaryMIATypeIds);
            ViewSettings    settings    = ServiceRegistration.Get <ISettingsManager>().Load <ViewSettings>();
            IGenreConverter converter   = ServiceRegistration.Get <IGenreConverter>();
            Dictionary <int, FilterValue> genredFilters   = new Dictionary <int, FilterValue>();
            List <FilterValue>            ungenredFilters = new List <FilterValue>();

            if (_necessaryMIATypeIds != null)
            {
                necessaryMIATypeIds = _necessaryMIATypeIds;
            }
            HomogenousMap valueGroups = null;
            HomogenousMap valueKeys   = null;

            if (_keyAttributeType != null)
            {
                Tuple <HomogenousMap, HomogenousMap> values = await cd.GetKeyValueGroupsAsync(_keyAttributeType, _valueAttributeType, selectAttributeFilter, ProjectionFunction.None, necessaryMIATypeIds, filter, true, showVirtual);

                valueGroups = values.Item1;
                valueKeys   = values.Item2;
            }
            else
            {
                valueGroups = await cd.GetValueGroupsAsync(_valueAttributeType, selectAttributeFilter, ProjectionFunction.None, necessaryMIATypeIds, filter, true, showVirtual);
            }
            IList <FilterValue> result = new List <FilterValue>(valueGroups.Count);
            int numEmptyEntries        = 0;

            foreach (KeyValuePair <object, object> group in valueGroups)
            {
                string name = GetDisplayName(group.Key);
                if (name == string.Empty)
                {
                    numEmptyEntries += (int)group.Value;
                }
                else if (!string.IsNullOrEmpty(_genreCategory) && settings.UseLocalizedGenres)
                {
                    int?genreId = valueKeys[group.Key] as int?;
                    if (!genreId.HasValue)
                    {
                        ungenredFilters.Add(new FilterValue(valueKeys[group.Key], name, new RelationalFilter(_valueAttributeType, RelationalOperator.EQ, group.Key), null, (int)group.Value, this));
                    }
                    else if (!genredFilters.ContainsKey(genreId.Value))
                    {
                        if (converter.GetGenreName(genreId.Value, _genreCategory, null, out string genreName))
                        {
                            name = genreName;
                        }
                        genredFilters.Add(genreId.Value, new FilterValue(genreId.Value, name, new RelationalFilter(_valueAttributeType, RelationalOperator.EQ, group.Key), null, (int)group.Value, this));
                    }
                    else
                    {
                        genredFilters[genreId.Value] = new FilterValue(genreId.Value, genredFilters[genreId.Value].Title,
                                                                       BooleanCombinationFilter.CombineFilters(BooleanOperator.Or, genredFilters[genreId.Value].Filter, new RelationalFilter(_valueAttributeType, RelationalOperator.EQ, group.Key)), null,
                                                                       genredFilters[genreId.Value].NumItems.Value + (int)group.Value, this);
                    }
                }
                else
                {
                    result.Add(new FilterValue(valueKeys[group.Key], name, new RelationalFilter(_valueAttributeType, RelationalOperator.EQ, group.Key), null, (int)group.Value, this));
                }
            }

            foreach (var gf in genredFilters.Values)
            {
                result.Add(gf);
            }

            foreach (var ugf in ungenredFilters)
            {
                result.Add(ugf);
            }

            if (numEmptyEntries > 0)
            {
                result.Insert(0, new FilterValue(Consts.RES_VALUE_EMPTY_TITLE, new EmptyFilter(_valueAttributeType), null, numEmptyEntries, this));
            }

            return(result);
        }