public void TestBuild()
        {
            IStructureParsingManager manager = new StructureParsingManager();
            IDataQueryParseManager queryParseManager = new DataQueryParseManager(SdmxSchemaEnumType.VersionTwoPointOne);
            IComplexDataQueryBuilderManager dataQueryBuilderManager = new ComplexDataQueryBuilderManager(new ComplexDataQueryFactoryV21());
            
            IDataflowObject dataFlow;
            IDataStructureObject dsd;
            using (var readable = new FileReadableDataLocation("tests/V21/Structure/test-sdmxv2.1-ESTAT+SSTSCONS_PROD_M+2.0.xml"))
            {
                var structureWorkspace = manager.ParseStructures(readable);
                dataFlow = structureWorkspace.GetStructureObjects(false).Dataflows.First();
            }

            using (var readable = new FileReadableDataLocation("tests/V21/Structure/test-sdmxv2.1-ESTAT+STS+2.0.xml"))
            {
                var structureWorkspace = manager.ParseStructures(readable);
                dsd = structureWorkspace.GetStructureObjects(false).DataStructures.First();
            }

            ISet<IComplexDataQuerySelection> sections = new HashSet<IComplexDataQuerySelection>();
            var freqCriteria = new ComplexDataQuerySelectionImpl("FREQ", new IComplexComponentValue[] { new ComplexComponentValueImpl("M", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.Equal), SdmxStructureEnumType.Dimension), new ComplexComponentValueImpl("A", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.NotEqual), SdmxStructureEnumType.Dimension), new ComplexComponentValueImpl("B", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.Equal), SdmxStructureEnumType.Dimension) });
            sections.Add(freqCriteria);
            var adjustmentCriteria = new ComplexDataQuerySelectionImpl("ADJUSTMENT", new IComplexComponentValue[] { new ComplexComponentValueImpl("01", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.NotEqual), SdmxStructureEnumType.Dimension) });
            sections.Add(adjustmentCriteria);
            var titleCriteria = new ComplexDataQuerySelectionImpl(
                "TITLE", 
                new IComplexComponentValue[] { new ComplexComponentValueImpl("PAOKARA", TextSearch.GetFromEnum(TextSearchEnumType.Contains), SdmxStructureEnumType.DataAttribute),  new ComplexComponentValueImpl("ARIS", TextSearch.GetFromEnum(TextSearchEnumType.DoesNotContain), SdmxStructureEnumType.DataAttribute), });
            sections.Add(titleCriteria);
            OrderedOperator equalOperator = OrderedOperator.GetFromEnum(OrderedOperatorEnumType.Equal);
            var dateFrom = new SdmxDateCore("2000-01");
            var dateFromOperator = OrderedOperator.GetFromEnum(OrderedOperatorEnumType.GreaterThanOrEqual);
            var primaryMeasureValue = new ComplexComponentValueImpl("200.20", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.GreaterThan), SdmxStructureEnumType.PrimaryMeasure);
            ICollection<IComplexDataQuerySelectionGroup> collection = new[] { new ComplexDataQuerySelectionGroupImpl(sections, dateFrom, dateFromOperator, null, equalOperator, new HashSet<IComplexComponentValue> { primaryMeasureValue }) };

            var complexDataQueryImpl = new ComplexDataQueryImpl(
                null, 
                null, 
                null, 
                dsd, 
                dataFlow, 
                null, 
                null, 
                0, 
                null, 
                false, 
                null, 
                DimensionAtObservation.GetFromEnum(DimensionAtObservationEnumType.Time).Value, 
                false, 
                DataQueryDetail.GetFromEnum(DataQueryDetailEnumType.Full), 
                collection);

            var dataQuery = this._builder.Build(complexDataQueryImpl);
            Assert.NotNull(dataQuery);
        }
        /// <summary>
        /// Retrieve Codelist
        /// </summary>
        /// <param name="info">
        /// The current StructureRetrieval state 
        /// </param>
        /// <returns>
        /// A <see cref="ICodelistMutableObject"/> 
        /// </returns>
        public ICodelistMutableObject GetCodeList(StructureRetrievalInfo info)
        {
            ISdmxDate minPeriod = new SdmxDateCore(CustomCodelistConstants.TimePeriodMax);
            ISdmxDate maxPeriod = new SdmxDateCore(CustomCodelistConstants.TimePeriodMin);

            var frequencyMapping = info.FrequencyInfo != null ? info.FrequencyInfo.ComponentMapping : null;
            var timeTranscoder = info.TimeTranscoder;
            using (DbConnection ddbConnection = DDbConnectionBuilder.Instance.Build(info))
            using (DbCommand cmd = ddbConnection.CreateCommand())
            {
                cmd.CommandTimeout = 0;
                cmd.CommandText = info.SqlQuery;
                using (IDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        string frequency = frequencyMapping != null ? frequencyMapping.MapComponent(reader) : null; 
                        string period = timeTranscoder.MapComponent(reader, frequency);
                        if (!string.IsNullOrEmpty(period))
                        {
                            ISdmxDate currentPeriod = new SdmxDateCore(period);
                            if (currentPeriod.StartsBefore(minPeriod))
                            {
                                minPeriod = currentPeriod;
                            }

                            if (currentPeriod.EndsAfter(maxPeriod))
                            {
                                maxPeriod = currentPeriod;
                            }
                        }
                    }
                }
            }

            return TimeDimensionCodeListHelper.BuildTimeCodelist(minPeriod, maxPeriod);
        }
 /// <summary>
 /// Retrieve Codelist
 /// </summary>
 /// <param name="info">
 /// The current StructureRetrieval state 
 /// </param>
 /// <returns>
 /// A <see cref="ICodelistMutableObject"/> 
 /// </returns>
 public ICodelistMutableObject GetCodeList(StructureRetrievalInfo info)
 {
     ISdmxDate constantDate = new SdmxDateCore(info.TimeMapping.Constant);
     return TimeDimensionCodeListHelper.BuildTimeCodelist(constantDate, constantDate);
 }
	    public ComplexDataQueryImpl(string datasetId, TextSearch datasetIdOperator, 
                                    ISet<IDataProvider> dataProviders, 
			                        IDataStructureObject dataStructure, IDataflowObject dataFlow,
			                        IProvisionAgreementObject provisionAgreement, 
                                    IList<ITimeRange> lastUpdatedDate,  
			                        int? firstNObs, int? lastNObs, int? defaultLimit, 
                                    ObservationAction obsAction, string dimensionAtObservation,
			                        bool hasExplicitMeasures, DataQueryDetail queryDetail, 
                                    ISet<IComplexDataQuerySelection> complexSelections, 
			                        DateTime dateFrom, OrderedOperator dateFromOperator, 
                                    DateTime dateTo,  OrderedOperator dateToOperator,
                                    ISet<IComplexComponentValue> primaryMeasureValues)
        {
		    this._datasetId = datasetId;
		    if (datasetIdOperator != null)
			    this._datasetIdOperator = datasetIdOperator;
		    else
			    this._datasetIdOperator = TextSearch.GetFromEnum(TextSearchEnumType.Equal);

		    this._dataProviders = dataProviders;
		    base.DataStructure = dataStructure;
		    base.Dataflow = dataFlow;
		    this._provisionAgreement = provisionAgreement;
		    this._lastUpdatedDate = lastUpdatedDate;
		    base.FirstNObservations = firstNObs;
		    base.LastNObservations = lastNObs;
		    this._defaultLimit = defaultLimit;

		    if (obsAction != null)
			    this._obsAction = obsAction;
		    else 
			    this._obsAction = ObservationAction.GetFromEnum(ObservationActionEnumType.Active);

		    this.DimensionAtObservation = dimensionAtObservation;
		    if (dimensionAtObservation != null)
            {
			    //the values: 'AllDimensions' and 'TIME_PERIOD' are valid values.
			    if (dimensionAtObservation.Equals(_allDimensions) || dimensionAtObservation.Equals(DimensionAtObservationEnumType.Time.ToString()))
				    this.DimensionAtObservation = dimensionAtObservation;
			    else//check if the value is a dimension Value
				    CheckDimensionExistence(dimensionAtObservation, dataStructure);
		    }
            else
            {
			    this.DimensionAtObservation = GetDimensionAtObservationLevel(dataStructure);
		    }
		
		    this._hasExplicitMeasures = hasExplicitMeasures;
		    if (queryDetail != null)
			    this._queryDetail = queryDetail;
		    else
			    this._queryDetail = DataQueryDetail.GetFromEnum(DataQueryDetailEnumType.Full);

		    if(ObjectUtil.ValidCollection(complexSelections) || dateFrom != null || dateTo != null) 
            {
			    ISdmxDate sdmxDateFrom = null;
			    if(dateFrom != null) 
                {
				    sdmxDateFrom = new SdmxDateCore(dateFrom, TimeFormatEnumType.Date);
			    }
			    ISdmxDate sdmxDateTo = null;
			    if(dateFrom != null) {
				    sdmxDateTo = new SdmxDateCore(dateTo, TimeFormatEnumType.Date);
			    }
			    this._complexDataQuerySelectionGroups.Add(new ComplexDataQuerySelectionGroupImpl(complexSelections, sdmxDateFrom, dateFromOperator, sdmxDateTo,  dateToOperator, primaryMeasureValues));
		    }

		    //perform validation 	
		    ValidateQuery();
		    ValidateProvisionAgreement();
	    }
        /// <summary>
        /// Generates the SQL Query where condition from the SDMX Query Time
        /// </summary>
        /// <param name="dateFrom">
        /// The start time
        /// </param>
        /// <param name="dateTo">
        /// The end time
        /// </param>
        /// <param name="frequencyValue">
        /// The frequency value
        /// </param>
        /// <returns>
        /// The string containing SQL Query where condition
        /// </returns>
        public string GenerateWhere(ISdmxDate dateFrom, ISdmxDate dateTo, string frequencyValue)
        {
            if (!string.IsNullOrEmpty(frequencyValue))
            {
                TimeFormat format = TimeFormat.GetTimeFormatFromCodeId(frequencyValue);
                if (dateFrom != null)
                {
                    dateFrom = new SdmxDateCore(dateFrom.Date, format.EnumType);
                }

                if (dateTo != null)
                {
                    dateTo = new SdmxDateCore(dateTo.Date, format.EnumType);
                }
            }

            return this._timeDimensionMapping.GenerateWhere(dateFrom, dateTo);
        }
        /**
         * Builds a time range from time range value from XML
         * @param timeRangeValueType
         * @return
         */
        private ITimeRange BuildTimeRange(TimeRangeValueType timeRangeValueType)
        {
            if (timeRangeValueType == null)
            {
                return null;
            }

            bool range = false;
            ISdmxDate startDate = null;
            ISdmxDate endDate = null;
            bool endInclusive = false;
            bool startInclusive = false;

            if (timeRangeValueType.AfterPeriod != null)
            {
                TimePeriodRangeType afterPeriod = timeRangeValueType.AfterPeriod;
                startDate = new SdmxDateCore(afterPeriod.TypedValue.ToString());
                startInclusive = afterPeriod.isInclusive;
            }
            else if (timeRangeValueType.BeforePeriod != null)
            {
                TimePeriodRangeType beforePeriod = timeRangeValueType.BeforePeriod;
                endDate = new SdmxDateCore(beforePeriod.TypedValue.ToString());
                endInclusive = beforePeriod.isInclusive;
            }
            else
            { //case that range is set
                range = true;
                TimePeriodRangeType startPeriod = timeRangeValueType.StartPeriod;
                startDate = new SdmxDateCore(startPeriod.TypedValue.ToString());
                startInclusive = startPeriod.isInclusive;

                TimePeriodRangeType endPeriod = timeRangeValueType.EndPeriod;
                endDate = new SdmxDateCore(endPeriod.TypedValue.ToString());
                endInclusive = endPeriod.isInclusive;
            }


            return new TimeRangeCore(range, startDate, endDate, startInclusive, endInclusive);
        }
        public void TestBuildComplexDataQuery()
        {
            IStructureParsingManager manager = new StructureParsingManager();
            IDataQueryParseManager queryParseManager = new DataQueryParseManager(SdmxSchemaEnumType.VersionTwoPointOne);
            IComplexDataQueryBuilderManager dataQueryBuilderManager = new ComplexDataQueryBuilderManager(new ComplexDataQueryFactoryV21());
            
            IDataflowObject dataFlow;
            IDataStructureObject dsd;
            using (var readable = new FileReadableDataLocation("tests/V21/Structure/test-sdmxv2.1-ESTAT+SSTSCONS_PROD_M+2.0.xml"))
            {
                var structureWorkspace = manager.ParseStructures(readable);
                dataFlow = structureWorkspace.GetStructureObjects(false).Dataflows.First();
            }

            using (var readable = new FileReadableDataLocation("tests/V21/Structure/test-sdmxv2.1-ESTAT+STS+2.0.xml"))
            {
                var structureWorkspace = manager.ParseStructures(readable);
                dsd = structureWorkspace.GetStructureObjects(false).DataStructures.First();
            }

            ISet<IComplexDataQuerySelection> sections = new HashSet<IComplexDataQuerySelection>();
            var freqCriteria = new ComplexDataQuerySelectionImpl("FREQ", new IComplexComponentValue[] { new ComplexComponentValueImpl("M", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.Equal), SdmxStructureEnumType.Dimension), new ComplexComponentValueImpl("A", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.NotEqual), SdmxStructureEnumType.Dimension), new ComplexComponentValueImpl("B", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.Equal), SdmxStructureEnumType.Dimension) });
            sections.Add(freqCriteria);
            var adjustmentCriteria = new ComplexDataQuerySelectionImpl("ADJUSTMENT", new IComplexComponentValue[] { new ComplexComponentValueImpl("01", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.NotEqual), SdmxStructureEnumType.Dimension),  new ComplexComponentValueImpl("S2", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.NotEqual), SdmxStructureEnumType.Dimension) });
            sections.Add(adjustmentCriteria);
            var titleCriteria = new ComplexDataQuerySelectionImpl(
                "TITLE", 
                new IComplexComponentValue[] { new ComplexComponentValueImpl("PAOKARA", TextSearch.GetFromEnum(TextSearchEnumType.Contains), SdmxStructureEnumType.DataAttribute),  new ComplexComponentValueImpl("ARIS", TextSearch.GetFromEnum(TextSearchEnumType.DoesNotContain), SdmxStructureEnumType.DataAttribute) });
            sections.Add(titleCriteria);
            OrderedOperator equalOperator = OrderedOperator.GetFromEnum(OrderedOperatorEnumType.Equal);
            var dateFrom = new SdmxDateCore("2000-01");
            var dateFromOperator = OrderedOperator.GetFromEnum(OrderedOperatorEnumType.GreaterThanOrEqual);
            var primaryMeasureValue = new ComplexComponentValueImpl("200.20", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.GreaterThan), SdmxStructureEnumType.PrimaryMeasure);
            ICollection<IComplexDataQuerySelectionGroup> collection = new[] { new ComplexDataQuerySelectionGroupImpl(sections, dateFrom, dateFromOperator, null, equalOperator, new HashSet<IComplexComponentValue> { primaryMeasureValue }) };

            var complexDataQueryImpl = new ComplexDataQueryImpl(
                null, 
                null, 
                null, 
                dsd, 
                dataFlow, 
                null, 
                null, 
                0, 
                null, 
                false, 
                null, 
                DimensionAtObservation.GetFromEnum(DimensionAtObservationEnumType.Time).Value, 
                false, 
                DataQueryDetail.GetFromEnum(DataQueryDetailEnumType.Full), 
                collection);

            var buildComplexDataQuery = dataQueryBuilderManager.BuildComplexDataQuery(
                complexDataQueryImpl, new StructSpecificDataFormatV21());

            var fileName = string.Format("test-TestBuildComplexDataQuery.xml");
            buildComplexDataQuery.Save(fileName);

            ISdmxObjects objects = new SdmxObjectsImpl();
            objects.AddDataStructure(dsd);
            objects.AddDataflow(dataFlow);
            ISdmxObjectRetrievalManager beanRetrievalManager = new InMemoryRetrievalManager(objects);

            IComplexDataQuery query;
            using (var readable = new FileReadableDataLocation(fileName))
            {
                XMLParser.ValidateXml(readable, SdmxSchemaEnumType.VersionTwoPointOne);

                query = queryParseManager.BuildComplexDataQuery(readable, beanRetrievalManager).First();
            }

            Assert.AreEqual(1, query.SelectionGroups.Count);
            var selectionGroup = query.SelectionGroups.First();
            Assert.AreEqual(dateFrom, selectionGroup.DateFrom);
            Assert.AreEqual(dateFromOperator, selectionGroup.DateFromOperator);
            Assert.IsNull(selectionGroup.DateTo);
            Assert.AreEqual(1, selectionGroup.PrimaryMeasureValue.Count);
            var primaryValue = selectionGroup.PrimaryMeasureValue.First();
            Assert.AreEqual(primaryMeasureValue.Value, primaryValue.Value);
            Assert.AreEqual(primaryMeasureValue.OrderedOperator, primaryValue.OrderedOperator);
            Assert.AreEqual(3, selectionGroup.Selections.Count);

            var gotFreqCriteria = selectionGroup.GetSelectionsForConcept(freqCriteria.ComponentId);
            Assert.AreEqual(gotFreqCriteria, freqCriteria, "FREQ diff");
            
            var gotAdjustmentCriteria = selectionGroup.GetSelectionsForConcept(adjustmentCriteria.ComponentId);
            Assert.AreEqual(gotAdjustmentCriteria, adjustmentCriteria, "ADJ diff");
            Assert.IsTrue(gotAdjustmentCriteria.Values.All(value => value.OrderedOperator.EnumType == OrderedOperatorEnumType.NotEqual));

            var gotTitleCriteria = selectionGroup.GetSelectionsForConcept(titleCriteria.ComponentId);
            Assert.AreEqual(gotTitleCriteria, titleCriteria, "TITLE diff");
        }
        /// <summary>
        /// Generates the SQL Query where condition from the SDMX Query TimeBean <see cref="ISdmxDate"/>
        /// </summary>
        /// <param name="dateFrom">The start time period</param>
        /// <param name="dateTo">The end time period</param>
        /// <returns>
        /// The string containing SQL Query where condition
        /// </returns>
        public string GenerateWhere(ISdmxDate dateFrom, ISdmxDate dateTo)
        {
            if (dateFrom == null && dateTo == null)
            {
                return string.Empty;
            }

            ISdmxDate constantDate = new SdmxDateCore(Mapping.Constant);

            var ret = new StringBuilder("(");
            bool timeWhereStarted = false;
            string normDateFrom = dateFrom != null ? new SdmxDateCore(dateFrom.Date, constantDate.TimeFormatOfDate.EnumType).DateInSdmxFormat : null;
            string normDateTo = dateTo != null ? new SdmxDateCore(dateTo.Date, constantDate.TimeFormatOfDate.EnumType).DateInSdmxFormat : null;
            bool areEqual = Equals(normDateFrom, normDateTo);

            if (normDateFrom != null)
            {
                var startTime = normDateFrom.Replace("'", "''");
                if (areEqual)
                {
                    ret.AppendFormat(this._equalsWhere, startTime);
                }
                else
                {
                    ret.AppendFormat(this._fromWhere, startTime);
                    timeWhereStarted = true;
                }
            }

            if (normDateTo != null && !areEqual)
            {
                if (timeWhereStarted)
                {
                    ret.Append(" and ");
                }

                var endTime = normDateTo.Replace("'", "''");
                ret.AppendFormat(this._toWhere, endTime);
            }

            ret.Append(") ");
            return ret.ToString();
        }
        public DataQueryImpl(
            IDataStructureObject dataStructure,
            ISdmxDate lastUpdated,
            DataQueryDetail dataQueryDetail,
            int maxObs,
            bool orderAsc,
            ISet<IDataProvider> dataProviders,
            IDataflowObject dataflow,
            string dimensionAtObservation,
            ISet<IDataQuerySelection> selections,
            DateTime? dateFrom,
            DateTime? dateTo)
        {
            base.DataStructure = dataStructure;
            this._lastUpdated = lastUpdated;
            this._dataQueryDetail = dataQueryDetail ?? DataQueryDetail.GetFromEnum(DataQueryDetailEnumType.Full);
            if (orderAsc)
            {
                base.FirstNObservations = maxObs;
            }
            else
            {
                base.LastNObservations = maxObs;
            }
            if (dataProviders != null)
            {
                this._dataProviders = new HashSet<IDataProvider>(dataProviders);
            }
            base.Dataflow = dataflow;
            this.DimensionAtObservation = dimensionAtObservation;

            if (ObjectUtil.ValidCollection(selections) || dateFrom != null || dateTo != null)
            {
                ISdmxDate sdmxDateFrom = null;
                if (dateFrom != null)
                {
                    sdmxDateFrom = new SdmxDateCore(dateFrom, TimeFormatEnumType.Date);
                }
                ISdmxDate sdmxDateTo = null;
                if (dateTo != null)
                {
                    sdmxDateTo = new SdmxDateCore(dateTo, TimeFormatEnumType.Date);
                }
                //TODO: move to fluent interface
                this._dataQuerySelectionGroups.Add(new DataQuerySelectionGroupImpl(selections, sdmxDateFrom, sdmxDateTo));
            }
            ValidateQuery();
        }
        /// <summary>
        /// This method generates the WHERE part of the SQL query that will be used against the DDB for retrieving the available codes
        /// </summary>
        /// <param name="info">
        /// The current structure retrieval information 
        /// </param>
        /// <returns>
        /// A string containing the WHERE part of the SQL Query or an Empty string 
        /// </returns>
        protected static string GenerateWhere(StructureRetrievalInfo info)
        {
            var sb = new StringBuilder();
            int lastClause = 0;

            foreach (IKeyValues member in info.Criteria)
            {
                if (!string.IsNullOrEmpty(member.Id))
                {
                    if (member.Id.Equals(info.TimeDimension))
                    {
                        if (member.Values.Count > 0)
                        {
                            ISdmxDate startDate = new SdmxDateCore(member.Values[0]);
                            ISdmxDate endDate = null;
                            if (member.Values.Count > 1)
                            {
                                endDate = new SdmxDateCore(member.Values[1]);
                            }

                            sb.Append("(");
                            sb.Append(
                                info.TimeTranscoder.GenerateWhere(startDate, endDate, null));
                            sb.Append(")");
                            lastClause = sb.Length;
                            sb.Append(" AND ");
                        }
                    }
                    else
                    {
                        ComponentInfo compInfo;
                        if (info.ComponentMapping.TryGetValue(member.Id, out compInfo))
                        {
                            sb.Append("(");
                            foreach (string value in member.Values)
                            {
                                sb.Append(compInfo.ComponentMapping.GenerateComponentWhere(value));
                                lastClause = sb.Length;
                                sb.Append(" OR ");
                            }

                            sb.Length = lastClause;
                            if (lastClause > 0)
                            {
                                sb.Append(")");
                                lastClause = sb.Length;
                                sb.Append(" AND ");
                            }
                        }
                    }
                }
            }

            if (info.ReferencePeriod != null)
            {
                // TODO DEPRECIATED. We should not use it. We never did. But leaving it in case a 3rd party client uses it.
                IReferencePeriodMutableObject time = info.ReferencePeriod;

                sb.Append("(");
                sb.Append(info.TimeTranscoder.GenerateWhere(new SdmxDateCore(time.StartTime, TimeFormatEnumType.DateTime),
                                                            new SdmxDateCore(time.StartTime, TimeFormatEnumType.DateTime), null));
                sb.Append(")");
                lastClause = sb.Length;
            }

            sb.Length = lastClause;
            if (sb.Length > 0)
            {
                return " where " + sb;
            }

            return string.Empty;
        }
示例#11
0
        /// <summary>
        /// Translates the specified <paramref name="sdmxDate"/> to <see cref="SdmxQueryPeriod"/>
        /// </summary>
        /// <param name="sdmxDate">The SDMX date.</param>
        /// <param name="periodicity">The periodicity.</param>
        /// <returns>
        /// The <see cref="SdmxQueryPeriod" />.
        /// </returns>
        public static SdmxQueryPeriod ToQueryPeriod(this ISdmxDate sdmxDate, IPeriodicity periodicity)
        {
            if (sdmxDate == null)
            {
                return null;
            }

            if (periodicity.TimeFormat.EnumType != sdmxDate.TimeFormatOfDate)
            {
                sdmxDate = new SdmxDateCore(sdmxDate.Date, periodicity.TimeFormat);
            }

            var time = new SdmxQueryPeriod();

            string[] startTime = sdmxDate.DateInSdmxFormat.Split('-');
            var startYear = Convert.ToInt32(startTime[0].Substring(0, 4), _invariantCulture);
            time.Year = startYear;
            if (startTime.Length >= 2)
            {
                int startPeriod;
                if (int.TryParse(startTime[1].Substring(periodicity.DigitStart), NumberStyles.None, _invariantCulture, out startPeriod))
                { 
                    time.HasPeriod = true;
                    time.Period = startPeriod;
                }
            }

            return time;
        }
        /// <summary>
        /// Builds the complex data query groups, by processing the or types, dimension/primary measure/attribute/time dimension values.
        ///  It then calls the 'addGroupIfSelectionsExist' method in order to add the newly built-in ComplexDataQuerySelectionGroup. It returns
        /// a set of Complex Data Query Selection Groups.
        /// Build complex data queries from the specified <paramref name="dataWhere"/>
        /// </summary>
        /// <param name="dataWhere">
        /// The data query type.
        /// </param>
        /// <param name="structureRetrievalManager">
        /// The structure retrieval manager.
        /// </param>
        /// <param name="dataProviders">
        /// The data providers.
        /// </param>
        /// <returns>
        /// The complex data query groups.
        /// </returns>
        private ISet<IComplexDataQuerySelectionGroup> BuildComplexDataQueryGroups(DataParametersAndType dataWhere, ISdmxObjectRetrievalManager structureRetrievalManager, ISet<IDataProvider> dataProviders)
        {
            ISet<IComplexDataQuerySelectionGroup> complexDataQuerySelectionGroups = new HashSet<IComplexDataQuerySelectionGroup>();
            ISet<IComplexDataQuerySelection> complexSelections = new HashSet<IComplexDataQuerySelection>();
            ISet<IComplexComponentValue> primaryMeasureValues = new HashSet<IComplexComponentValue>();
            OrderedOperator dateFromOperator = OrderedOperator.GetFromEnum(OrderedOperatorEnumType.Equal);
            OrderedOperator dateToOperator = OrderedOperator.GetFromEnum(OrderedOperatorEnumType.Equal);
            ISdmxDate dateFrom = null;
            ISdmxDate dateTo = null;

            //primary measure
            if (dataWhere.PrimaryMeasureValue != null && (dataWhere.PrimaryMeasureValue.Count > 0))
            {
                PrimaryMeasureValueType primaryMeasure = dataWhere.PrimaryMeasureValue[0];
                var complexValues = GetComplexComponentValues(primaryMeasure, SdmxStructureEnumType.PrimaryMeasure);
                foreach (var complexValue in complexValues)
                {
                    primaryMeasureValues.Add(complexValue);
                }
            }
            //time dimension
            if (dataWhere.TimeDimensionValue != null && dataWhere.TimeDimensionValue.Count > 0)
            {
                TimeDimensionValueType timeValue = dataWhere.TimeDimensionValue[0];
                var complexValues = GetComplexComponentValues(timeValue, SdmxStructureEnumType.TimeDimension);

                if (complexValues != null && complexValues.Count > 0)
                {
                    var complexValue = complexValues[0];
                    switch (complexValue.OrderedOperator.EnumType)
                    {
                        case OrderedOperatorEnumType.GreaterThan:
                        case OrderedOperatorEnumType.GreaterThanOrEqual:
                        case OrderedOperatorEnumType.Equal:
                            dateFromOperator = complexValue.OrderedOperator;
                            dateFrom = new SdmxDateCore(complexValue.Value);
                            if (complexValues.Count == 2)
                            {
                                dateTo = new SdmxDateCore(complexValues[1].Value);
                                dateToOperator = complexValues[1].OrderedOperator;
                            }

                            break;
                        default:
                            dateToOperator = complexValue.OrderedOperator;
                            dateTo = new SdmxDateCore(complexValue.Value);
                            if (complexValues.Count == 2)
                            {
                                dateFrom = new SdmxDateCore(complexValues[1].Value);
                                dateFromOperator = complexValues[1].OrderedOperator;
                            }

                            break;
                    }

                    if (complexValues.Count == 2)
                    {
                        if (dateFrom != null && dateFrom.IsLater(dateTo))
                        {
                            // interchange dates if not the correct order
                            var tempDate = dateTo;
                            dateTo = dateFrom;
                            dateFrom = tempDate;
                            var tempOperator = dateToOperator;
                            dateToOperator = dateFromOperator;
                            dateFromOperator = tempOperator;
                        }

                        // cases when same operator is used
                        if (dateToOperator.Equals(dateFromOperator))
                        {
                            switch (dateToOperator.EnumType)
                            {
                                case OrderedOperatorEnumType.GreaterThan:
                                case OrderedOperatorEnumType.GreaterThanOrEqual:

                                    // only the greatest date is considered
                                    dateFrom = dateTo;
                                    dateTo = null;
                                    break;
                                case OrderedOperatorEnumType.LessThan:
                                case OrderedOperatorEnumType.LessThanOrEqual:

                                    // only the lowest date is considered
                                    dateTo = dateFrom;
                                    dateFrom = null;
                                    break;
                            }
                        }
                    }
                }
            }
            //dimensions
            if (dataWhere.DimensionValue != null && dataWhere.DimensionValue.Count > 0)
            {
                foreach (DimensionValueType dimValue in dataWhere.DimensionValue)
                {
                    IComplexComponentValue comValue = GetComplexComponentValue(dimValue, SdmxStructureEnumType.Dimension);
                    AddComponentSelection(complexSelections, dimValue.ID, comValue);
                }
            }
            //attributes
            if (dataWhere.AttributeValue != null && dataWhere.AttributeValue.Count > 0)
            {
                foreach (AttributeValueType attrValue in dataWhere.AttributeValue)
                {
                    IComplexComponentValue comValue = GetComplexComponentValue(attrValue, SdmxStructureEnumType.DataAttribute);
                    AddComponentSelection(complexSelections, attrValue.ID, comValue);
                }
            }
            //DataParametersOrType
            ProcessParametersOrType(dataWhere.Or, complexSelections, structureRetrievalManager, dataProviders);
            AddGroupIfSelectionsExist(complexSelections, dateFrom, dateFromOperator, dateTo, dateToOperator, primaryMeasureValues, complexDataQuerySelectionGroups);
            return complexDataQuerySelectionGroups;
        }
        public void TestLikeNsiWcAll(string file)
        {
            IDataReaderManager manager = new DataReaderManager();
            IDataStructureObject dsd = BuildDsd();
            IList<IDictionary<string, string>> dataSetStoreList = new List<IDictionary<string, string>>();
            int obscount = 0;
            using (var sourceData = this._factory.GetReadableDataLocation(new FileInfo(file)))
            using (var compact = manager.GetDataReaderEngine(sourceData, dsd, null))
            {
                int index = 0;
                while (compact.MoveNextKeyable())
                {
                    if (compact.CurrentKey.Series)
                    {
                        IList<IKeyValue> keyValues = compact.CurrentKey.Key;

                        if (index >= 100)
                        {
                            index = 0;
                        }

                        while (compact.MoveNextObservation())
                        {
                            var dataSetStore = new Dictionary<string, string>(StringComparer.Ordinal);
                            foreach (var key in keyValues)
                            {
                                dataSetStore.Add(key.Concept, key.Code);
                            }

                            IObservation currentObservation = compact.CurrentObservation;
                            Assert.IsNotNullOrEmpty(currentObservation.ObservationValue);
                            Assert.IsNotNullOrEmpty(currentObservation.ObsTime);
                            if (currentObservation.CrossSection)
                            {
                                Assert.IsNotNull(currentObservation.CrossSectionalValue);
                                dataSetStore.Add(currentObservation.CrossSectionalValue.Concept, currentObservation.CrossSectionalValue.Code);
                            }

                            dataSetStore.Add(DimensionObject.TimeDimensionFixedId, currentObservation.ObsTime);
                            ISdmxDate sdmxDate = new SdmxDateCore(currentObservation.ObsTime);
                            Assert.AreEqual(sdmxDate.TimeFormatOfDate, currentObservation.ObsTimeFormat);
                            dataSetStore.Add(PrimaryMeasure.FixedId, currentObservation.ObservationValue);
                            int i = int.Parse(currentObservation.ObservationValue, NumberStyles.Any, CultureInfo.InvariantCulture);
                            Assert.AreEqual(index, i, "Expected {0}\nBut was {1} At OBS {2}", index, i, obscount);

                            index++;
                            obscount++;
                            dataSetStoreList.Add(dataSetStore);
                        }
                    }
                }
            }
        }
        public void TestLikeNSIWCVariousDataWithDsdFile(string file, string dsdFile)
        {
            IDataReaderManager manager = new DataReaderManager();
            ISdmxObjects objects;
            using (var dataLocation = this._factory.GetReadableDataLocation(new FileInfo(dsdFile)))
            {
                IStructureParsingManager parsingManager = new StructureParsingManager();
                objects = parsingManager.ParseStructures(dataLocation).GetStructureObjects(false);
            }
            var retrievalManager = new InMemoryRetrievalManager(objects); 
            IList<IDictionary<string, string>> dataSetStoreList = new List<IDictionary<string, string>>();
            using (var sourceData = this._factory.GetReadableDataLocation(new FileInfo(file)))
            using (var compact = manager.GetDataReaderEngine(sourceData, retrievalManager))
            {
                while (compact.MoveNextKeyable())
                {
                    if (compact.CurrentKey.Series)
                    {
                        IList<IKeyValue> keyValues = compact.CurrentKey.Key;

                        while (compact.MoveNextObservation())
                        {
                            var dataSetStore = new Dictionary<string, string>(StringComparer.Ordinal);
                            foreach (var key in keyValues)
                            {
                                dataSetStore.Add(key.Concept, key.Code);
                            }

                            IObservation currentObservation = compact.CurrentObservation;
                            Assert.IsNotNullOrEmpty(currentObservation.ObservationValue);
                            Assert.IsNotNullOrEmpty(currentObservation.ObsTime);
                            Assert.IsFalse(currentObservation.CrossSection);
                            dataSetStore.Add(DimensionObject.TimeDimensionFixedId, currentObservation.ObsTime);
                            ISdmxDate sdmxDate = new SdmxDateCore(currentObservation.ObsTime);
                            Assert.NotNull(sdmxDate);
                            Assert.AreEqual(sdmxDate.TimeFormatOfDate, currentObservation.ObsTimeFormat);
                            dataSetStore.Add(PrimaryMeasure.FixedId, currentObservation.ObservationValue);
                            if (!currentObservation.ObservationValue.Equals(EdiConstants.MissingVal))
                            {
                                double i;
                                Assert.IsTrue(double.TryParse(currentObservation.ObservationValue, NumberStyles.Any, CultureInfo.InvariantCulture, out i), "Cannot convert to int {0}", currentObservation.ObservationValue);
                            }

                            dataSetStoreList.Add(dataSetStore);
                        }
                    }
                }
            }
        }
        public void TestSDMXv20(string queryFile)
        {
            IDataQuery query;
            using (IReadableDataLocation dataLocation = new FileReadableDataLocation(queryFile))
            {
                query = this._dataQueryParseManager.BuildDataQuery(dataLocation, this._retrievalManager).First();
            }
            
            var outputFileName = string.Format("{0}-out.xml", queryFile);

            using (XmlWriter writer = XmlWriter.Create(outputFileName, new XmlWriterSettings() {Indent = true}))
            {
                var compactWriter = new CompactDataWriterEngine(writer, SdmxSchema.GetFromEnum(SdmxSchemaEnumType.VersionTwo));
                this._dataRetrievalRest.GetData(query, compactWriter);
            }
            
            var selectionGroup = query.SelectionGroups.First();

            var fileInfo = new FileInfo(outputFileName);
            Assert.IsTrue(fileInfo.Exists);
            using (var fileStream = fileInfo.OpenRead())
            using (var reader = XmlReader.Create(fileStream))
            {
                TimeFormat freqValue = TimeFormat.GetFromEnum(TimeFormatEnumType.Null);
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            {
                                var localName = reader.LocalName;
                                if (localName.Equals("Series"))
                                {
                                    Assert.IsTrue(reader.HasAttributes);
                                    freqValue = TimeFormat.GetTimeFormatFromCodeId(reader.GetAttribute("FREQ"));
                                }
                                else if (localName.Equals("Obs"))
                                {
                                    Assert.NotNull(freqValue);
                                    Assert.IsTrue(reader.HasAttributes);
                                    var dateStr = reader.GetAttribute(DimensionObject.TimeDimensionFixedId);
                                    ISdmxDate date = new SdmxDateCore(dateStr);
                                    var dateFrom = new SdmxDateCore(new SdmxDateCore(selectionGroup.DateFrom.Date, freqValue).DateInSdmxFormat);
                                    var dateTo = new SdmxDateCore(new SdmxDateCore(selectionGroup.DateTo.Date, freqValue).DateInSdmxFormat);
                                    Assert.GreaterOrEqual(date.Date, dateFrom.Date);
                                    Assert.LessOrEqual(date.Date, dateTo.Date);
                                }
                            }

                            break;
                    }
                }
            }
        }
        public void TestBuildComplexDataQueryRaw()
        {
            IStructureParsingManager manager = new StructureParsingManager();
            IDataQueryParseManager queryParseManager = new DataQueryParseManager(SdmxSchemaEnumType.VersionTwoPointOne);
            IComplexDataQueryBuilderManager dataQueryBuilderManager = new ComplexDataQueryBuilderManager(new ComplexDataQueryFactoryV21());

            IDataflowObject dataFlow;
            IDataStructureObject dsd;
            using (var readable = new FileReadableDataLocation("tests/V21/Structure/test-sdmxv2.1-ESTAT+SSTSCONS_PROD_M+2.0.xml"))
            {
                var structureWorkspace = manager.ParseStructures(readable);
                dataFlow = structureWorkspace.GetStructureObjects(false).Dataflows.First();
            }

            using (var readable = new FileReadableDataLocation("tests/V21/Structure/test-sdmxv2.1-ESTAT+STS+2.0.xml"))
            {
                var structureWorkspace = manager.ParseStructures(readable);
                dsd = structureWorkspace.GetStructureObjects(false).DataStructures.First();
            }

            ISet<IComplexDataQuerySelection> sections = new HashSet<IComplexDataQuerySelection>();
            var freqCriteria = new ComplexDataQuerySelectionImpl("FREQ", new IComplexComponentValue [] { new ComplexComponentValueImpl("M", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.Equal), SdmxStructureEnumType.Dimension), new ComplexComponentValueImpl("A", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.NotEqual), SdmxStructureEnumType.Dimension), new ComplexComponentValueImpl("B", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.Equal), SdmxStructureEnumType.Dimension) });
            sections.Add(freqCriteria);
            var adjustmentCriteria = new ComplexDataQuerySelectionImpl("ADJUSTMENT", new IComplexComponentValue [] { new ComplexComponentValueImpl("01", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.NotEqual), SdmxStructureEnumType.Dimension), new ComplexComponentValueImpl("S2", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.NotEqual), SdmxStructureEnumType.Dimension) });
            sections.Add(adjustmentCriteria);
            var titleCriteria = new ComplexDataQuerySelectionImpl(
                "TITLE",
                new IComplexComponentValue [] { new ComplexComponentValueImpl("PAOKARA", TextSearch.GetFromEnum(TextSearchEnumType.Contains), SdmxStructureEnumType.DataAttribute), new ComplexComponentValueImpl("ARIS", TextSearch.GetFromEnum(TextSearchEnumType.DoesNotContain), SdmxStructureEnumType.DataAttribute) });
            sections.Add(titleCriteria);
            OrderedOperator equalOperator = OrderedOperator.GetFromEnum(OrderedOperatorEnumType.Equal);
            var dateFrom = new SdmxDateCore("2000-01");
            var dateFromOperator = OrderedOperator.GetFromEnum(OrderedOperatorEnumType.GreaterThanOrEqual);
            var primaryMeasureValue = new ComplexComponentValueImpl("200.20", OrderedOperator.GetFromEnum(OrderedOperatorEnumType.GreaterThan), SdmxStructureEnumType.PrimaryMeasure);
            ICollection<IComplexDataQuerySelectionGroup> collection = new [] { new ComplexDataQuerySelectionGroupImpl(sections, dateFrom, dateFromOperator, null, equalOperator, new HashSet<IComplexComponentValue> { primaryMeasureValue }) };

            var complexDataQueryImpl = new ComplexDataQueryImpl(
                null,
                null,
                null,
                dsd,
                dataFlow,
                null,
                null,
                0,
                null,
                false,
                null,
                DimensionAtObservation.GetFromEnum(DimensionAtObservationEnumType.Time).Value,
                false,
                DataQueryDetail.GetFromEnum(DataQueryDetailEnumType.Full),
                collection);

            var buildComplexDataQuery = dataQueryBuilderManager.BuildComplexDataQuery(
                complexDataQueryImpl, new StructSpecificDataFormatV21());

            var fileName = string.Format("test-TestBuildComplexDataQuery.xml");
            buildComplexDataQuery.Save(fileName);

            bool insideOr = false;
            string localName;
            string lastDimension = null;
            string value = null;

            using (var reader = XmlReader.Create(fileName))
            {
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            localName = reader.LocalName;
                            switch (localName)
                            {
                                case "Or":
                                    insideOr = true;  
                                    lastDimension = null;
                                    value = null;
                                    break;

                            }
                            break;
                        case XmlNodeType.Text:
                            value = reader.Value;
                            break;
                        case XmlNodeType.EndElement:
                            if ("ID".Equals(reader.LocalName))
                            {
                                if (insideOr)
                                {
                                    Assert.IsNotNullOrEmpty(value);
                                    if (lastDimension == null)
                                    {
                                        lastDimension = value;
                                    }

                                    Assert.AreEqual(lastDimension, value);
                                }
                            }
                            else if ("Or".Equals(reader.LocalName))
                            {
                                insideOr = false;
                            }
                            break;

                    }
                }
            }
        }