/// <summary>
        /// Handles the ordered.
        /// </summary>
        /// <param name="dsd">The DSD.</param>
        /// <param name="dimensionAtObservation">The dimension attribute observation.</param>
        /// <param name="orderComponents">The order components.</param>
        private static void HandleOrdered(DsdEntity dsd, string dimensionAtObservation, List<ComponentEntity> orderComponents)
        {
            ComponentEntity dimensionAtObsEntity = dsd.TimeDimension;
            foreach (ComponentEntity dim in dsd.Dimensions)
            {
                if (!dim.Id.Equals(dimensionAtObservation))
                {
                    orderComponents.Add(dim);
                }
                else
                {
                    dimensionAtObsEntity = dim;
                }
            }

            if (!Equals(dimensionAtObsEntity, dsd.TimeDimension))
            {
               orderComponents.Add(dsd.TimeDimension);
            }

            orderComponents.Add(dimensionAtObsEntity);
        }
 /// <summary>
 /// Handles the flat.
 /// </summary>
 /// <param name="orderComponents">The order components.</param>
 /// <param name="dsd">The DSD.</param>
 private static void HandleFlat(List<ComponentEntity> orderComponents, DsdEntity dsd)
 {
     bool bFlat;
     if (!bool.TryParse(ConfigurationManager.AppSettings["QueryFlatFormat"], out bFlat) || !bFlat)
     {
         orderComponents.AddRange(dsd.Dimensions);
         if (dsd.TimeDimension == null)
         {
             // Comment out because I don't understand why we remove the last dimension and why we add the last attribute to the order by.
             // This code will fail if there are no attributes in a DSD 
             ////orderComponents.RemoveAt(orderComponents.Count - 1);
             ////orderComponents.Add(dsd.Attributes[dsd.Attributes.Count - 1]);
         }
         else
         {
             orderComponents.Add(dsd.TimeDimension);
         }
     }
 }
Example #3
0
        /// <summary>
        /// This method checks whether a mapping set is complete, in order to be used for the Data Retriever.
        /// For example,one of the checks is whether all dimensions and mandatory attributes are mapped.
        /// </summary>
        /// <param name="dsd">The DSD to be checked</param>
        /// <param name="componentMapping">Map between components and their mapping</param>
        /// <returns>
        /// True if the mapping is complete
        /// </returns>
        public static bool IsMappingSetComplete(
            DsdEntity dsd, Dictionary<ComponentEntity, MappingEntity> componentMapping)
        {
            // _log.Info(String.Format(CultureInfo.InvariantCulture,"Checking if mapping for dataflow '{0}' DSD '{1}' is complete.",
            // mappingSet.Dataflow.Id, dsd.Id));
            bool returnValue = true;
            bool measureDimensionNotMapped = false;

            if (dsd.Dimensions != null)
            {
                int i = 0;

                // check if all dimensions are mapped
                while (i < dsd.Dimensions.Count)
                {
                    if (!dsd.Dimensions[i].MeasureDimension && !componentMapping.ContainsKey(dsd.Dimensions[i]))
                    {
                        _log.WarnFormat(
                                CultureInfo.InvariantCulture, 
                                "Dimension '{0}' is not mapped.", 
                                dsd.Dimensions[i].Concept.Id);
                        returnValue = false;
                    }
                    else if (dsd.Dimensions[i].MeasureDimension && !componentMapping.ContainsKey(dsd.Dimensions[i]))
                    {
                        measureDimensionNotMapped = true;
                    }

                    i++;
                }
            }
            else
            {
                string message = string.Format(
                    CultureInfo.InvariantCulture, "No dimensions defined in the DSD {0}", dsd.Id);

                _log.Info(message);

                // throw new DataRetrieverException(ErrorTypes.NO_MAPPING_SET, message);
                return false;
            }

            // check if time dimension is mapped, if one exists.
            if (dsd.TimeDimension != null)
            {
                if (!componentMapping.ContainsKey(dsd.TimeDimension))
                {
                    _log.WarnFormat(CultureInfo.InvariantCulture, "Time Dimension '{0}' is not mapped.", dsd.TimeDimension.Concept.Id);
                    returnValue = false;
                }
            }

            // check xs-measures
            if (dsd.CrossSectionalMeasures != null && dsd.CrossSectionalMeasures.Count > 0 && measureDimensionNotMapped)
            {
                foreach (ComponentEntity component in dsd.CrossSectionalMeasures)
                {
                    if (!componentMapping.ContainsKey(component))
                    {
                        _log.WarnFormat(CultureInfo.InvariantCulture, ErrorMessages.CrossSectionalMeasureNotMappedFormat1, component.Concept.Id);
                        returnValue = false;
                    }
                }
            }
            else if (dsd.PrimaryMeasure != null)
            {
                // primary measure
                if (!componentMapping.ContainsKey(dsd.PrimaryMeasure))
                {
                    {
                        _log.WarnFormat(CultureInfo.InvariantCulture, ErrorMessages.PrimaryMeasureNotMappedFormat1, dsd.PrimaryMeasure.Concept.Id);
                        returnValue = false;
                    }
                }
            }

            // atributes
            if (dsd.Attributes != null && dsd.Attributes.Count > 0)
            {
                foreach (ComponentEntity component in dsd.Attributes)
                {
                    if (component.AttStatus == AssignmentStatus.Mandatory && !componentMapping.ContainsKey(component))
                    {
                        _log.WarnFormat(CultureInfo.InvariantCulture, ErrorMessages.MandatoryAttributeNotMappedFormat1, component.Concept.Id);
                        returnValue = false;
                    }
                }
            }

            // test if 1-N or N-1 mappings have transcoding
            foreach (var kv in componentMapping)
            {
                if (kv.Value.Transcoding == null && (kv.Value.Columns.Count > 1 || kv.Value.Components.Count > 1))
                {
                    _log.WarnFormat(CultureInfo.CurrentCulture, ErrorMessages.ComponentMappingNoTranscodingFormat1, kv.Key.Concept.Id);
                    returnValue = false;
                }
            }

            _log.Info(
                string.Format(
                    CultureInfo.InvariantCulture, InformativeMessages.CheckMappingSetResultFormat1, returnValue));

            return returnValue;
        }
        /// <summary>
        /// The method retrieves the <see cref="DsdEntity"/> object
        /// by the data flow system 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>
        /// <returns>
        /// The populated <see cref="DsdEntity"/>object
        /// </returns>
        private static DsdEntity GetDsdByDataFlowSysId(Database mappingStoreDb, long sysId)
        {
            DsdEntity ret = null;

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

            var sqlCommand = new StringBuilder();
            sqlCommand.Append("SELECT DSD.DSD_ID, ART.ID, ART.VERSION, ART.AGENCY ");
            sqlCommand.Append("FROM DSD, DATAFLOW DF, ARTEFACT_VIEW ART ");
            sqlCommand.Append("WHERE DF.DSD_ID = DSD.DSD_ID ");
            sqlCommand.Append("AND DSD.DSD_ID = ART.ART_ID ");
            sqlCommand.AppendFormat("AND DF.DF_ID = {0} ", paramId);

            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
                    if (dataReader.Read())
                    {
                        ret = new DsdEntity(DataReaderHelper.GetInt64(dataReader, "DSD_ID"))
                                  {
                                      Id = DataReaderHelper.GetString(dataReader, "ID"),
                                      Version = DataReaderHelper.GetString(dataReader, "VERSION"),
                                      Agency = DataReaderHelper.GetString(dataReader, "AGENCY")
                                  };
                    }
                }
            }

            if (ret == null)
            {
                throw new MappingStoreException(
                    string.Format(
                        CultureInfo.InvariantCulture, 
                        ErrorMessages.MappingStoreNoEntityFormat2, 
                        typeof(DsdEntity), 
                        sysId));
            }

            // populate the Dsd fields by the correct components
            PoulateDsdComponentsByDsdSysId(mappingStoreDb, ret.SysId, ref ret);

            return ret;
        }
        /// <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);
            }
        }
        /// <summary>
        /// Gets the requested component unique identifier.
        /// </summary>
        /// <param name="dsdEntity">The DSD entity.</param>
        /// <param name="conceptId">The requested component.</param>
        /// <returns>
        /// The Component.Id
        /// </returns>
        private static string GetRequestedComponentId(DsdEntity dsdEntity, string conceptId)
        {
            if (dsdEntity.TimeDimension != null && dsdEntity.TimeDimension.Concept.Id.Equals(conceptId))
            {
                conceptId = dsdEntity.TimeDimension.Id;
            }
            else
            {
                var dimension = dsdEntity.Dimensions.FirstOrDefault(entity => entity.Concept.Id.Equals(conceptId));
                conceptId = dimension == null ? conceptId : dimension.Id;
            }

            return conceptId;
        }