/// <summary> /// Sets the current dataflow. /// </summary> /// <param name="currentDataflow"> /// The current dataflow. /// </param> private void SetCurrentDataflow(IDataflowObject currentDataflow) { this._currentDataflow = currentDataflow; // If the current dataset header does not reference a Dataflow then amend it if (this._datasetHeader == null) { this._datasetHeader = new DatasetHeaderCore(Guid.NewGuid().ToString(), DatasetActionEnumType.Information, new DatasetStructureReferenceCore(currentDataflow.AsReference)); } else if (this._datasetHeader.DataProviderReference == null) { IDatasetStructureReference datasetStructureReference = new DatasetStructureReferenceCore(currentDataflow.AsReference); this._datasetHeader = this._datasetHeader.ModifyDataStructureReference(datasetStructureReference); } if (this._defaultDsd != null && this._defaultDsd.Urn.Equals(currentDataflow.DataStructureRef.TargetUrn)) { this.SetCurrentDsd(this._defaultDsd); } else if (this._objectRetrieval != null) { this.SetCurrentDsd(this._objectRetrieval.GetMaintainableObject<IDataStructureObject>(currentDataflow.DataStructureRef.MaintainableReference) as ICrossSectionalDataStructureObject); } }
/// <summary> /// Sets the current DSD. /// </summary> /// <param name="currentDsd"> /// The current DSD. /// </param> protected void SetCurrentDsd(ICrossSectionalDataStructureObject currentDsd) { this._currentDsd = currentDsd; foreach (var component in currentDsd.Components) { this._conceptToComponentId[component.ConceptRef.FullId] = component.Id; } this._availableDimensions.AddRange(currentDsd.GetDimensions(SdmxStructureEnumType.Dimension).Select(dimension => dimension.Id)); this._availableMeasureDimensions.AddRange(currentDsd.GetDimensions(SdmxStructureEnumType.MeasureDimension).Select(dimension => dimension.Id)); this._availableCrossSectionalMeasures.AddRange(currentDsd.CrossSectionalMeasures.Select(measure => measure.Id)); this._primaryMeasure = currentDsd.PrimaryMeasure.Id; if (currentDsd.TimeDimension != null) { this._timeDimensionId = currentDsd.TimeDimension.Id; } // If the current dataset header does not reference a DSD then amend it var datasetHeader = this._datasetHeader; if (datasetHeader != null && datasetHeader.DataStructureReference == null) { IDatasetStructureReference datasetStructureReference = new DatasetStructureReferenceCore(currentDsd.AsReference); this._datasetHeader = this._datasetHeader.ModifyDataStructureReference(datasetStructureReference); } }
/// <summary> /// Retrieve data from a DDB and write it to the specified <paramref name="writer"/> This is the main public method of the DataRetriever class. It is called with a populated QueryBean (containing essentially an SDMX-ML Query) and a database Connection to a "Mapping Store" database. This method is responsible for: /// <list type="bullet"> /// <item> /// Retrieving the <see cref="MappingSetEntity"/> (the class containing the performed mappings), according to the provided Dataflow ID, from the "Mapping Store". Mapping Sets are defined on a Dataflow basis. Thus, this method checks the input QueryBean for the Dataflow that data are requested and fetches the appropriate /// <see cref="MappingSetEntity"/>. If no <see cref="MappingSetEntity"/> exists, an exception (<see cref="DataRetrieverException"/>) is thrown. /// </item> /// <item> /// Calling the method generating the appropriate SQL for the dissemination database. /// </item> /// <item> /// Calling the method that executes the generated SQL and uses the /// <paramref name="writer"/> /// to write the output. /// </item> /// </list> /// <note type="note"> /// The "Data Retriever" expects exactly one Dataflow clause under the DataWhere clause, exactly one /// DataFlowBean within the DataWhereBean (which in turn resides inside the incoming QueryBean). /// </note> /// </summary> /// <exception cref="DataRetrieverException"> /// See the /// <see cref="ErrorTypes"/> /// for more details /// </exception> /// <exception cref="System.ArgumentNullException"> /// <paramref name="query"/> /// is null /// -or- /// <paramref name="writer"/> /// is null /// </exception> /// <param name="query"> /// The query bean for which data will be requested /// </param> /// <param name="writer"> /// The Cross Sectional writer /// </param> /// <example> /// An example using this method in C# with <see cref="CrossSectionalWriter"/> /// <code source="ReUsingExamples\DataRetriever\ReUsingDataRetrieverCrossSectional.cs" lang="cs"> /// </code> /// </example> public void GetData(IDataQuery dataQuery, ICrossSectionalWriterEngine dataWriter) { if (dataQuery == null) { throw new ArgumentNullException("query"); } if (dataWriter == null) { throw new ArgumentNullException("writer"); } try { Logger.Info(Resources.InfoDataRetrieverBBInvoked); Logger.Info(Resources.InfoOutput + dataWriter.GetType().Name); // validate input and initialize the mappingset entitiy MappingSetEntity mappingSet = this.Initialize(dataQuery); var info = new DataRetrievalInfoXS(mappingSet, dataQuery, this._connectionStringSettings, dataWriter) { DefaultHeader = this._defaultHeader }; ValidateMappingSet(info); this.WriteHeader(dataWriter, info); ICrossSectionalDataStructureObject crossDsd = dataQuery.DataStructure as ICrossSectionalDataStructureObject; //(SRA-345) //DR the info from I*DataQuery. DimensionAtObservation to IDataWriterEngine.StartDataSet IDatasetStructureReference dsr = new DatasetStructureReferenceCore("", dataQuery.DataStructure.AsReference, null, null, dataQuery.DimensionAtObservation); IDatasetHeader header = new DatasetHeaderCore(this._defaultHeader.DatasetId, this._defaultHeader.Action, dsr); dataWriter.StartDataset(dataQuery.Dataflow, crossDsd, header); this.GenerateSql(info, _sqlXsBuilder); // execute sql query. this.ExecuteSql(info, CrossSectionalQueryEngineManager.Instance.GetQueryEngine(info)); // close output dataWriter.Close(); Logger.Info(Resources.InfoEndDataRetrieverBBInvoked); } catch (DataRetrieverException) { throw; } catch (SdmxException) { throw; } catch (DbException ex) { Logger.Error(ex.ToString()); throw new DataRetrieverException(ex, SdmxErrorCode.GetFromEnum(SdmxErrorCodeEnumType.InternalServerError), Resources.DataRetriever_ExecuteSqlQuery_Error_executing_generated_SQL_and_populating_SDMX_model); //ErrorTypes.DDB_CONNECTION_ERROR, //Resources.DataRetriever_ExecuteSqlQuery_Error_executing_generated_SQL_and_populating_SDMX_model, //ex); } catch (OutOfMemoryException) { throw; } catch (Exception ex) { Logger.Error(ex.ToString()); throw new DataRetrieverException(ex, SdmxErrorCode.GetFromEnum(SdmxErrorCodeEnumType.InternalServerError), Resources.DataRetriever_ExecuteSqlQuery_Error_during_writing_responce); //ErrorTypes.WRITING_OUTPUT_ERROR, //Resources.DataRetriever_ExecuteSqlQuery_Error_during_writing_responce, //ex); } }
/// <summary> /// Retrieve data from a DDB and write it to the specified <paramref name="writer"/> This is the main public method of the DataRetriever class. It is called with a populated QueryBean (containing essentially an SDMX-ML Query) and a database Connection to a "Mapping Store" database. This method is responsible for: /// <list type="bullet"> /// <item> /// Retrieving the <see cref="MappingSetEntity"/> (the class containing the performed mappings), according to the provided Dataflow ID, from the "Mapping Store". Mapping Sets are defined on a Dataflow basis. Thus, this method checks the input QueryBean for the Dataflow that data are requested and fetches the appropriate /// <see cref="MappingSetEntity"/>. If no <see cref="MappingSetEntity"/> exists, an exception (<see cref="DataRetrieverException"/>) is thrown. /// </item> /// <item> /// Calling the method generating the appropriate SQL for the dissemination database. /// </item> /// <item> /// Calling the method that executes the generated SQL and uses the /// <paramref name="writer"/> /// to write the output. /// </item> /// </list> /// <note type="note"> /// The "Data Retriever" expects exactly one Dataflow clause under the DataWhere clause, exactly one /// DataFlowBean within the DataWhereBean (which in turn resides inside the incoming QueryBean). /// </note> /// </summary> /// <exception cref="DataRetrieverException"> /// See the /// <see cref="ErrorTypes"/> /// for more details /// </exception> /// <exception cref="System.ArgumentNullException"> /// <paramref name="query"/> /// is null /// -or- /// <paramref name="writer"/> /// is null /// </exception> /// <param name="query"> /// The query bean for which data will be requested /// </param> /// <param name="writer"> /// The <see cref="ISeriesWriter"/> (e.g. Compact, Generic) writer /// </param> /// <example> /// An example using this method in C# with <see cref="CompactWriter"/> /// <code source="ReUsingExamples\DataRetriever\ReUsingDataRetriever.cs" lang="cs"> /// </code> /// An example using this method in C# with <see cref="GenericDataWriter"/> /// <code source="ReUsingExamples\DataRetriever\ReUsingDataRetrieverGeneric.cs" lang="cs"> /// </code> /// </example> public void GetData(IDataQuery dataQuery, IDsplDataWriterEngine dataWriter) { if (dataQuery == null) { throw new ArgumentNullException("query"); } if (dataWriter == null) { throw new ArgumentNullException("writer"); } try { Logger.Info(Resources.InfoDataRetrieverBBInvoked); Logger.Info(Resources.InfoOutput + dataWriter.GetType().Name); // validate input and initialize the mappingset entitiy MappingSetEntity mappingSet = this.Initialize(dataQuery); var info = new DataRetrievalInfoSeries(mappingSet, dataQuery, this._connectionStringSettings, dataWriter, this._sdmxSchemaVersion) { DefaultHeader = this._defaultHeader }; ValidateMappingSet(info); //Pietro 27/01 //this.WriteHeader(dataWriter, info); //(SRA-345) //DR the info from I*DataQuery. DimensionAtObservation to IDataWriterEngine.StartDataSet IDatasetStructureReference dsr = new DatasetStructureReferenceCore("", dataQuery.DataStructure.AsReference, null, null, dataQuery.DimensionAtObservation); IDatasetHeader header = new DatasetHeaderCore(this._defaultHeader.DatasetId, this._defaultHeader.Action, dsr); //info.MappingSet.DataSet.Description.ToString() //info.MappingSet.Dataflow.Dsd.Id.ToString() dataWriter.SetDsdOrder(dataQuery.DataStructure); dataWriter.StartDataset(info.MappingSet.DataSet.Description.ToString(), dataQuery.Dataflow, dataQuery.DataStructure, header, null); // Generate sql query this.GenerateSql(info, _sqlBuilder); this.GenerateSql(info, SeriesDataSetSqlBuilder.Instance); this.GenerateSql(info, SeriesGroupSqlBuilder.Instance); // execute sql query this.ExecuteSql(info, SeriesQueryEngineManager.Instance.GetQueryEngine(info)); // close output dataWriter.Close(); Logger.Info(Resources.InfoEndDataRetrieverBBInvoked); } catch (DataRetrieverException) { throw; } catch (SdmxException) { throw; } catch (DbException ex) { Logger.Error(ex.ToString()); throw new DataRetrieverException(ex, SdmxErrorCode.GetFromEnum(SdmxErrorCodeEnumType.InternalServerError), Resources.DataRetriever_ExecuteSqlQuery_Error_executing_generated_SQL_and_populating_SDMX_model); } catch (OutOfMemoryException) { throw; } catch (Exception ex) { Logger.Error(ex.ToString()); throw new DataRetrieverException(ex, SdmxErrorCode.GetFromEnum(SdmxErrorCodeEnumType.InternalServerError), Resources.DataRetriever_ExecuteSqlQuery_Error_during_writing_responce); } }
/// <summary> /// Move to the next OBS. /// </summary> /// <param name="includeObs"> /// if set to <c>true</c> [include OBS]. /// </param> /// <returns> /// True if it successfully moves to the next OBS; otherwise false; /// </returns> protected override bool Next(bool includeObs) { while (this.Parser.Read()) { var nodeType = this.Parser.NodeType; string nodeName; if (nodeType == XmlNodeType.Element) { // TODO check why java uses ignore case for DataSet check since both SDMX v2.0 and v2.1 use the same casing. nodeName = this.Parser.LocalName; ElementNameTable elementName; if (Enum.TryParse(nodeName, out elementName)) { switch (elementName) { case ElementNameTable.DataSet: this.DatasetPositionInternal = Api.Constants.DatasetPosition.Dataset; this._attributesOnDatasetNode = new Dictionary<string, string>(StringComparer.Ordinal); this.DatasetHeader = new DatasetHeaderCore(this.Parser, this.Header); string dsdId = this.ProcessDatasetNode(); IDatasetStructureReference dataStructureReference = this.DatasetHeader.DataStructureReference; IStructureReference structureReference = null; string id = null; Uri serviceUrl = null; Uri structureUrl = null; string dimensionAtObservation = null; if (dataStructureReference != null) { id = dataStructureReference.Id; serviceUrl = dataStructureReference.ServiceUrl; structureUrl = dataStructureReference.StructureUrl; dimensionAtObservation = dataStructureReference.DimensionAtObservation; structureReference = dataStructureReference.StructureReference; } if (structureReference == null) { if (this.DefaultDsd != null && this.DefaultDsd.Id.Equals(dsdId)) { structureReference = this.DefaultDsd.AsReference; } else { structureReference = new StructureReferenceImpl(null, dsdId, MaintainableObject.DefaultVersion, SdmxStructureEnumType.Dsd); } } dataStructureReference = new DatasetStructureReferenceCore(id, structureReference, serviceUrl, structureUrl, dimensionAtObservation); this.DatasetHeader = this.DatasetHeader.ModifyDataStructureReference(dataStructureReference); return true; case ElementNameTable.Series: StaxUtil.SkipToEndNode(this.RunAheadParser, ElementNameTable.SeriesKey.FastToString()); this.DatasetPositionInternal = Api.Constants.DatasetPosition.Series; return true; case ElementNameTable.Group: StaxUtil.SkipToEndNode(this.RunAheadParser, ElementNameTable.GroupKey.FastToString()); this.DatasetPositionInternal = Api.Constants.DatasetPosition.Group; // TODO test in Java it is possible to ignore the namespace. this.GroupId = this.Parser.GetAttribute(AttributeNameTable.type); return true; case ElementNameTable.Obs: if (this.DatasetPositionInternal == Api.Constants.DatasetPosition.Series || this.DatasetPositionInternal == Api.Constants.DatasetPosition.Observation) { if (includeObs) { this.DatasetPositionInternal = Api.Constants.DatasetPosition.Observation; return true; } continue; } this.DatasetPositionInternal = Api.Constants.DatasetPosition.ObservationAsSeries; return true; case ElementNameTable.Annotations: case ElementNameTable.Attributes: this.Parser.Skip(); break; case ElementNameTable.KeyFamilyRef: case ElementNameTable.Time: case ElementNameTable.ObsValue: case ElementNameTable.ObsDimension: case ElementNameTable.SeriesKey: case ElementNameTable.Value: case ElementNameTable.GroupKey: break; default: throw new SdmxSyntaxException("Unexpected Node in XML: " + nodeName); } } } else if (nodeType == XmlNodeType.EndElement) { nodeName = this.Parser.LocalName; if (ElementNameTable.Series.Is(nodeName) || ElementNameTable.Group.Is(nodeName)) { this.DatasetPositionInternal = Api.Constants.DatasetPosition.Null; } } } this.HasNext = false; return false; }
/// <summary> /// Sets the current DSD. /// </summary> /// <param name="currentDsd"> /// The current DSD. /// </param> protected virtual void SetCurrentDsd(IDataStructureObject currentDsd) { this._currentDsd = currentDsd; // If the current dataset header does not reference a DSD then amend it if (this._datasetHeader.DataStructureReference == null) { IDatasetStructureReference datasetStructureReference = new DatasetStructureReferenceCore(currentDsd.AsReference); this._datasetHeader = this._datasetHeader.ModifyDataStructureReference(datasetStructureReference); } }