/// <summary>
        /// Gets the list of <paramref name="dimension"/> values inside a <paramref name="query"/>
        /// </summary>
        /// <param name="query">
        /// The SDMX Model query 
        /// </param>
        /// <param name="dimension">
        /// The <see cref="ComponentEntity"/> of a dimension 
        /// </param>
        /// <returns>
        /// the list of <paramref name="dimension"/> values inside a <paramref name="query"/> 
        /// </returns>
        private static IEnumerable<string> GetFromQueryDimensionValues(IDataQuery query, ComponentEntity dimension)
        {
            var xsMeasureValues = new List<string>();

            foreach (IDataQuerySelectionGroup sg in query.SelectionGroups)
            {
                if (sg.HasSelectionForConcept(dimension.Id))
                {
                    var selection = sg.GetSelectionsForConcept(dimension.Id);
                    if (selection.HasMultipleValues)
                    {
                        xsMeasureValues.AddRange(selection.Values);
                    }
                    else
                    {
                        xsMeasureValues.Add(selection.Value);
                    }
                }
            }

            return xsMeasureValues;
        }
예제 #2
0
 /// <summary>
 /// Add a dimension to the Dimensions list
 /// </summary>
 /// <param name="dimension">
 /// &gt;The <see cref="ComponentEntity"/>
 /// that needs to be added
 /// </param>
 public void AddDimensions(ComponentEntity dimension)
 {
     this._dimensions.Add(dimension);
 }
예제 #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ComponentValue"/> class.
 /// </summary>
 /// <param name="key">
 /// The dsd component.
 /// </param>
 public ComponentValue(ComponentEntity key)
 {
     this.Key = key;
 }
 /// <summary>
 /// SRA-349 check the component entity type observation
 /// </summary>
 /// <param name="component">
 /// The ComponentEntity containing the component
 /// </param>
 /// <returns>
 /// True for an observation component, false for all other types 
 /// </returns>
 private bool IsObservationComponent(ComponentEntity component)
 {
     switch (component.ComponentType)
     {
         case SdmxComponentType.Dimension:
             return true;
         case SdmxComponentType.Attribute:
             switch (component.AttributeAttachmentLevel)
             {
                 case AttachmentLevel.Series:
                 case AttachmentLevel.Observation:
                     return true;
                 default:
                     break;
             }
             break;
         case SdmxComponentType.PrimaryMeasure:
             return true;
         case SdmxComponentType.CrossSectionalMeasure:
             return true;
         default:
             break;
     }
     return false;
 }
 /// <summary>
 /// SRA-349 check the component entity type attribute
 /// </summary>
 /// <param name="component">
 /// The ComponentEntity containing the component
 /// </param>
 /// <returns>
 /// True for an attribute component, false for all other types 
 /// </returns>
 private bool IsAttributeComponent(ComponentEntity component)
 {
     switch (component.ComponentType)
     {
         case SdmxComponentType.Attribute:
             switch (component.AttributeAttachmentLevel)
             {
                 case AttachmentLevel.DataSet:
                     return true;
                 default:
                     break;
             }
             break;
         default:
             break;
     }
     return false;
 }
        /// <summary>
        /// Compare two <paramref name="x"/> amd <paramref name="y"/> based on their Cross Sectional attachment level. The <see cref="ComponentEntity"/> attached to DataSet will be first, followed by Group, Section and finally observation.
        /// </summary>
        /// <param name="x">
        /// The first <see cref="ComponentEntity"/> to compare 
        /// </param>
        /// <param name="y">
        /// The second <see cref="ComponentEntity"/> to compare 
        /// </param>
        /// <returns>
        /// A signed integer that indicates the relative values of <paramref name="x"/> and <paramref name="y"/> , 1 if <paramref name="x"/> is attached to a lower level than <paramref name="y"/> , -1 if <paramref name="x"/> is attached to a higher level than <paramref name="y"/> , else 0. 
        /// </returns>
        private static int OnCrossSectionalComparison(ComponentEntity x, ComponentEntity y)
        {
            var firstConditions = GetCrossSectionalFlags(x);
            var secondConditions = GetCrossSectionalFlags(y);

            for (var i = 0; i < firstConditions.Length; i++)
            {
                if (firstConditions[i] && secondConditions[i])
                {
                    return 0;
                }

                if (firstConditions[i] && !secondConditions[i])
                {
                    return 1;
                }

                if (!firstConditions[i] && secondConditions[i])
                {
                    return -1;
                }
            }

            return 0;
        }
예제 #7
0
 /// <summary>
 /// Add a dimension to the Dimensions list
 /// </summary>
 /// <param name="dimension">
 /// &gt;The <see cref="ComponentEntity"/> 
 /// that needs to be added
 /// </param>
 public void AddDimensions(ComponentEntity dimension)
 {
     this._dimensions.Add(dimension);
 }
 /// <summary>
 /// Gets an array of the CrossSectional flags of <paramref name="component"/>
 /// </summary>
 /// <param name="component">
 /// The <see cref="ComponentEntity"/> 
 /// </param>
 /// <returns>
 /// an array of the CrossSectional flags of <paramref name="component"/> 
 /// </returns>
 private static bool[] GetCrossSectionalFlags(ComponentEntity component)
 {
     return new[]
         {
             component.MeasureDimension, component.CrossSectionalLevelObs, component.CrossSectionalLevelSection, 
             component.CrossSectionalLevelGroup || component.FrequencyDimension
             || component.ComponentType == SdmxComponentType.TimeDimension, component.CrossSectionalLevelDataSet
         };
 }
예제 #9
0
 /// <summary>
 /// Gets the value for the specified <paramref name="component"/>
 /// </summary>
 /// <param name="component">
 /// The CrossSectional measure 
 /// </param>
 /// <returns>
 /// the value for the specified <paramref name="component"/> 
 /// </returns>
 private string GetXSMeasureValue(ComponentEntity component)
 {
     return this._xsMeasures.Find(x => x.Key.Equals(component)).Value;
 }
예제 #10
0
        /// <summary>
        /// Add <paramref name="xsComponent"/> to buffer
        /// </summary>
        /// <param name="xsComponent">
        /// The XS Measure to add to buffer 
        /// </param>
        public void AddToBuffer(ComponentEntity xsComponent)
        {
            XsMeasureCache xsMeasureCache;
            if (!this._xsMeasureCaches.TryGetValue(xsComponent, out xsMeasureCache))
            {
                xsMeasureCache = new XsMeasureCache(
                    this._xsMeasureCachedSeriesKey,
                    this._xsMeasureCachedSeriesAttribute,
                    xsComponent.CrossSectionalMeasureCode);
                this._xsMeasureCaches.Add(xsComponent, xsMeasureCache);
            }

            xsMeasureCache.XSMeasureCachedObservations.Add(
                new KeyValuePair<string, string>(this.TimeValue, this.GetXSMeasureValue(xsComponent)));
            xsMeasureCache.Attributes.Add(new List<ComponentValue>(this._attributeObservationValues));
        }
        /// <summary>
        /// The method populates all the <see cref="ComponentEntity">DSD components</see>
        /// of a <see cref="DsdEntity"/> object by the data structure definition identifier
        /// </summary>
        /// <param name="mappingStoreDb">
        /// The <see cref="Database"/> instance for Mapping Store database
        /// </param>
        /// <param name="sysId">
        /// The data flow with the specified system identifier
        /// </param>
        /// <param name="dsd">
        /// The populated <see cref="DsdEntity"/>object containing also the
        /// <see cref="ComponentEntity">DSD components</see> 
        /// </param>
        private static void PoulateDsdComponentsByDsdSysId(Database mappingStoreDb, long sysId, ref DsdEntity dsd)
        {
            GroupEntity group;
            string id;

            string paramId = mappingStoreDb.BuildParameterName(ParameterNameConstants.IdParameter);

            var sqlCommand = new StringBuilder();
            sqlCommand.Append("SELECT G.GR_ID AS GR_ID, G.ID AS ID, DG.COMP_ID AS COMP_ID ");
            sqlCommand.Append("FROM DSD D, DSD_GROUP G, DIM_GROUP DG ");
            sqlCommand.AppendFormat("WHERE D.DSD_ID = G.DSD_ID AND G.GR_ID = DG.GR_ID AND D.DSD_ID = {0} ", paramId);
            sqlCommand.Append("ORDER BY G.GR_ID");

            // used to store the groups given the dimension system id. Is used later to gather actual ComponentVO objects and set them to Group
            var groupsFromDim = new Dictionary<long, List<GroupEntity>>();

            // holds the groups created given their group id
            var groupsFromId = new Dictionary<string, GroupEntity>();
            using (DbCommand command = mappingStoreDb.GetSqlStringCommand(sqlCommand.ToString()))
            {
                mappingStoreDb.AddInParameter(command, ParameterNameConstants.IdParameter, DbType.Int64, sysId);

                using (IDataReader dataReader = mappingStoreDb.ExecuteReader(command))
                {
                    // we expect only 1 record here ?
                    while (dataReader.Read())
                    {
                        id = DataReaderHelper.GetString(dataReader, "ID");

                        // do we have a new group id
                        if (!groupsFromId.ContainsKey(id))
                        {
                            group = new GroupEntity(DataReaderHelper.GetInt64(dataReader, "GR_ID")) { Id = id };

                            dsd.AddGroup(group);
                            groupsFromId.Add(id, group);
                        }
                        else
                        {
                            group = groupsFromId[id];
                        }

                        long dimId = DataReaderHelper.GetInt64(dataReader, "COMP_ID");
                        List<GroupEntity> groupsList;
                        if (!groupsFromDim.TryGetValue(dimId, out groupsList))
                        {
                            groupsList = new List<GroupEntity>();
                            groupsFromDim.Add(dimId, groupsList);
                        }

                        groupsList.Add(group);
                    }
                }
            }

            sqlCommand = new StringBuilder();
            sqlCommand.Append("SELECT COMP.COMP_ID, COMP.ID as CID, COMP.TYPE, COMP.DSD_ID, COMP.CON_ID, COMP.CL_ID, ");
            sqlCommand.Append("COMP.IS_FREQ_DIM, COMP.IS_MEASURE_DIM, COMP.ATT_ASS_LEVEL, COMP.ATT_STATUS, ");
            sqlCommand.Append("COMP.ATT_IS_TIME_FORMAT, COMP.XS_ATTLEVEL_DS, COMP.XS_ATTLEVEL_GROUP, ");
            sqlCommand.Append("COMP.XS_ATTLEVEL_SECTION, COMP.XS_ATTLEVEL_OBS, COMP.XS_MEASURE_CODE, ");
            sqlCommand.Append("AG.GR_ID, GR.ID AS GID, MC.ID as MID ");

            sqlCommand.Append("FROM DSD INNER JOIN COMPONENT COMP ON DSD.DSD_ID = COMP.DSD_ID ");
            sqlCommand.Append("LEFT OUTER JOIN ATT_GROUP AG ON COMP.COMP_ID = AG.COMP_ID ");
            sqlCommand.Append("LEFT OUTER JOIN DSD_GROUP GR ON AG.GR_ID = GR.GR_ID ");
            sqlCommand.Append("LEFT OUTER JOIN ATT_MEASURE AM ON AM.ATT_COMP_ID = COMP.COMP_ID ");
            sqlCommand.Append("LEFT OUTER JOIN COMPONENT MC ON AM.MEASURE_COMP_ID = MC.COMP_ID ");

            sqlCommand.AppendFormat("WHERE DSD.DSD_ID = {0} ", paramId);

            // make sure that they are returned in the order they were inserted (proper order)
            sqlCommand.Append("ORDER BY COMP.COMP_ID ");

            // hashmap keeping components already met with key the sys id.
            var componentsMap = new Dictionary<long, ComponentEntity>();
            using (DbCommand command = mappingStoreDb.GetSqlStringCommand(sqlCommand.ToString()))
            {
                mappingStoreDb.AddInParameter(command, ParameterNameConstants.IdParameter, DbType.Int64, sysId);

                using (IDataReader dataReader = mappingStoreDb.ExecuteReader(command))
                {
                    // GetOrdinal positions
                    int compIdIdx = dataReader.GetOrdinal("COMP_ID");
                    int type = dataReader.GetOrdinal("TYPE");
                    int isFreqDim = dataReader.GetOrdinal("IS_FREQ_DIM");
                    int isMeasureDim = dataReader.GetOrdinal("IS_MEASURE_DIM");
                    int attAssLevel = dataReader.GetOrdinal("ATT_ASS_LEVEL");
                    int attStatus = dataReader.GetOrdinal("ATT_STATUS");
                    int attIsTimeFormat = dataReader.GetOrdinal("ATT_IS_TIME_FORMAT");
                    int crossSectionalAttachmentlevelDataSet = dataReader.GetOrdinal("XS_ATTLEVEL_DS");
                    int attlevelGroup = dataReader.GetOrdinal("XS_ATTLEVEL_GROUP");
                    int attlevelSection = dataReader.GetOrdinal("XS_ATTLEVEL_SECTION");
                    int attlevelObs = dataReader.GetOrdinal("XS_ATTLEVEL_OBS");
                    int measureCode = dataReader.GetOrdinal("XS_MEASURE_CODE");
                    int gid = dataReader.GetOrdinal("GID");
                    int cid = dataReader.GetOrdinal("CID");
                    int mid = dataReader.GetOrdinal("MID");
                    while (dataReader.Read())
                    {
                        long compSysId = DataReaderHelper.GetInt64(dataReader, compIdIdx);

                        // check if new populate
                        ComponentEntity component;
                        if (!componentsMap.TryGetValue(compSysId, out component))
                        {
                            component = new ComponentEntity(compSysId);
                            component.Id = DataReaderHelper.GetString(dataReader, cid);
                            component.SetType(DataReaderHelper.GetString(dataReader, type));
                            component.CrossSectionalLevelDataSet = DataReaderHelper.GetBoolean(
                                dataReader, crossSectionalAttachmentlevelDataSet);
                            component.CrossSectionalLevelGroup = DataReaderHelper.GetBoolean(dataReader, attlevelGroup);
                            component.CrossSectionalLevelSection = DataReaderHelper.GetBoolean(
                                dataReader, attlevelSection);
                            component.CrossSectionalLevelObs = DataReaderHelper.GetBoolean(dataReader, attlevelObs);
                            component.CrossSectionalMeasureCode = DataReaderHelper.GetString(dataReader, measureCode);
                            switch (component.ComponentType)
                            {
                                case SdmxComponentType.Dimension:
                                    component.FrequencyDimension = DataReaderHelper.GetBoolean(dataReader, isFreqDim);
                                    component.MeasureDimension = DataReaderHelper.GetBoolean(dataReader, isMeasureDim);
                                    dsd.Dimensions.Add(component);
                                    break;
                                case SdmxComponentType.Attribute:
                                    component.SetAttachmentLevel(DataReaderHelper.GetString(dataReader, attAssLevel));
                                    component.SetAssignmentStatus(DataReaderHelper.GetString(dataReader, attStatus));
                                    component.AttTimeFormat = DataReaderHelper.GetBoolean(dataReader, attIsTimeFormat);
                                    dsd.Attributes.Add(component);
                                    break;
                                case SdmxComponentType.TimeDimension:
                                    dsd.TimeDimension = component;
                                    break;
                                case SdmxComponentType.PrimaryMeasure:
                                    dsd.PrimaryMeasure = component;
                                    break;
                                case SdmxComponentType.CrossSectionalMeasure:
                                    dsd.CrossSectionalMeasures.Add(component);
                                    break;
                            }

                            componentsMap.Add(compSysId, component);
                        }

                        // populate for current groups the related assigned groups if any
                        id = DataReaderHelper.GetString(dataReader, gid);
                        if (!string.IsNullOrEmpty(id))
                        {
                            group = groupsFromId[id];
                            component.AttAssignmentGroups.Add(group);
                        }

                        var measureId = DataReaderHelper.GetString(dataReader, mid);
                        if (!string.IsNullOrEmpty(measureId))
                        {
                            component.AttAttachmentMeasures.Add(measureId);
                        }

                        // if component is a dimension used in group definition, add it in their object
                        List<GroupEntity> groupFromDim;
                        if (groupsFromDim.TryGetValue(compSysId, out groupFromDim))
                        {
                            foreach (GroupEntity groupsItem in groupFromDim)
                            {
                                groupsItem.Dimensions.Add(component);
                            }
                        }
                    }
                }
            }

            foreach (var kv in componentsMap)
            {
                kv.Value.Concept = GetConceptByComponentSysId(mappingStoreDb, kv.Key);
                kv.Value.CodeList = GetCodeListByComponentSysId(mappingStoreDb, kv.Key);
            }
        }
예제 #12
0
        /// <summary>
        /// Create the IComponentMapping object for a specific component in a mapping depending on the type of mapping e.g. 1
        ///     DSD component - N local columns e.t.c.
        /// </summary>
        /// <param name="component">
        /// The component entity
        /// </param>
        /// <param name="mapping">
        /// The mapping entity
        /// </param>
        /// <returns>
        /// An IComponentMapping object based on the mapping or null if the mapping is not supported
        /// </returns>
        /// <exception cref="TranscodingException">
        /// Invalid or unsupported mapping
        /// </exception>
        public static IComponentMapping CreateComponentMapping(ComponentEntity component, MappingEntity mapping)
        {
            IComponentMapping componentMapping;
            if (mapping.Components.Count == 1)
            {
                // one component
                switch (mapping.Columns.Count)
                {
                    case 0: // no columns => constant mapping
                        if (mapping.Constant != null)
                        {
                            componentMapping = new ComponentMapping1C();
                        }
                        else
                        {
                            throw new TranscodingException(string.Format(CultureInfo.CurrentCulture, ErrorMessages.ComponentMappingNoMappingFormat1, mapping.Components[0]));
                        }

                        break;
                    case 1: // 1 to 1 mapping
                        if (mapping.Transcoding != null)
                        {
                            // with transcoding
                            if (mapping.Transcoding.TranscodingRules.ColumnAsKeyPosition.Count > 0 && mapping.Transcoding.TranscodingRules.ComponentAsKeyPosition.Count > 0)
                            {
                                componentMapping = new ComponentMapping1To1T();
                            }
                            else
                            {
                                // transcoding enabled but no transcoding rules
                                // TODO log a warning
                                componentMapping = new ComponentMapping1To1(); // disable transcoding
                            }
                        }
                        else
                        {
                            // without transcoding
                            componentMapping = new ComponentMapping1To1();
                        }

                        break;
                    default: // N columns where N > 1
                        if (mapping.Transcoding != null)
                        {
                            // transcoding is mandatory
                            if (mapping.Transcoding.TranscodingRules.ColumnAsKeyPosition.Count > 0 && mapping.Transcoding.TranscodingRules.ComponentAsKeyPosition.Count > 0)
                            {
                                // there are transcoding rules
                                componentMapping = new ComponentMapping1N();
                            }
                            else
                            {
                                throw new TranscodingException(string.Format(CultureInfo.CurrentCulture, ErrorMessages.ComponentMappingNoTranscodingRulesFormat1, component.Id));
                            }
                        }
                        else
                        {
                            throw new TranscodingException(string.Format(CultureInfo.CurrentCulture, ErrorMessages.ComponentMappingNoTranscodingFormat1, component.Id));
                        }

                        break;
                }
            }
            else if (mapping.Columns.Count == 1 && mapping.Components.Count > 1)
            {
                // N components to 1 column mapping 
                if (mapping.Transcoding != null)
                {
                    // transcoding is mandatory
                    if (mapping.Transcoding.TranscodingRules.ColumnAsKeyPosition.Count > 0 && mapping.Transcoding.TranscodingRules.ComponentAsKeyPosition.Count > 0)
                    {
                        // there are transcoding rules
                        componentMapping = new ComponentMappingNto1(mapping.Transcoding.TranscodingRules.ComponentAsKeyPosition[component.SysId]);
                    }
                    else
                    {
                        throw new TranscodingException(string.Format(CultureInfo.CurrentCulture, ErrorMessages.ComponentMappingNoTranscodingRulesFormat1, component.Id));
                    }
                }
                else
                {
                    throw new TranscodingException(string.Format(CultureInfo.CurrentCulture, ErrorMessages.ComponentMappingNoTranscodingFormat1, component.Id));
                }
            }
            else
            {
                throw new TranscodingException(string.Format(CultureInfo.CurrentCulture, ErrorMessages.ComponentMappingNNMapping, component.Id));
            }

            componentMapping.Mapping = mapping;
            componentMapping.Component = component;
            return componentMapping;
        }