public void ConvertToStruct2()
        {
            TSDateValueStruct tsdvs = new TSDateValueStruct { Date = date2, Value = val2 };
            TimeSeriesValue tsv = new TimeSeriesValue { Date = date2, Value = val2 };

            TSDateValueStruct actual = ((TSDateValueStruct)(tsv));
            Assert.AreEqual(tsdvs, actual);
        }
        public void ConvertFromStruct2()
        {
            TSDateValueStruct tsdvs = new TSDateValueStruct { Date = date2, Value = val2 };
            TimeSeriesValue tsv = new TimeSeriesValue { Date = date2, Value = val2 };

            TimeSeriesValue actual = ((TimeSeriesValue)(tsdvs));
            Assert.IsTrue(tsv.ValueEquals(actual));
        }
        public void WriteTraceIrregular()
        {
            DateTime startDate = DateTime.Parse("2/10/2000");
            DateTime endDate = DateTime.Parse("2/10/2002");
            int timeStepCount = 40;
            int id, traceNumber = 27;

            String extraParamNames = "TimeSeriesType, Unit_Id, RunGUID, VariableType, VariableName, RunElementGUID";
            String extraParamValues = "0, 1, 'A0101010-AAAA-BBBB-2222-3E3E3E3E3E3E', 0, 'eraseme', '00000000-0000-0000-0000-000000000000'";
            id = _lib.WriteParametersIrregular(_connxNumber, GetSbyte(_paramTableName), GetSbyte(_traceTableName),
                    timeStepCount, startDate, endDate, GetSbyte(extraParamNames), GetSbyte(extraParamValues));

            TSDateValueStruct[] dateValArray = new TSDateValueStruct[timeStepCount],
                                testDateValArray = new TSDateValueStruct[timeStepCount];
            double x = 10.0;
            double y = 1.0;
            DateTime curDate = startDate;
            for (int i = 0; i < timeStepCount; i++)
            {
                dateValArray[i].Value = x;
                dateValArray[i].Date = curDate;
                x *= 1.2;
                y += 0.5;
                curDate = curDate.AddDays(y);
            }
            // The method being tested
            _lib.WriteTraceIrregular(_connxNumber, GetSbyte(_paramTableName), GetSbyte(_traceTableName),
                        id, traceNumber, dateValArray);

            String comm = String.Format("select * from {0} where TimeSeries_Id={1} and TraceNumber={2}",
                            _traceTableName, id, traceNumber);
            // SqlDataAdapter object will use the query to fill the DataTable
            using (SqlDataAdapter adp = new SqlDataAdapter(comm, _connx))
            {
                DataTable dTable = new DataTable();
                // Execute the query to fill the DataTable object
                adp.Fill(dTable);
                DataRow row = dTable.Rows[0];
                byte[] blob = row.Field<byte[]>("ValueBlob");
                TSBlobCoder.ConvertBlobToArrayIrregular(timeStepCount,
                            false, 0, startDate, startDate, blob, testDateValArray, TSBlobCoder.currentCompressionCode);
                //
                for (int i = 0; i < timeStepCount; i++)
                    Assert.AreEqual(dateValArray[i], testDateValArray[i]);
            }
        }
        public void ReadDatesValuesRegular()
        {
            DateTime startDate = DateTime.Parse("1/10/1996");
            DateTime endDate = DateTime.Parse("2/10/2002");
            int timeStepCount = 70;
            TSDateCalculator.TimeStepUnitCode timeStepUnit = TSDateCalculator.TimeStepUnitCode.Hour;
            short timeStepQuantity = 6;
            int id, traceNumber = 13;

            String extraParamNames = "TimeSeriesType, Unit_Id, RunGUID, VariableType, VariableName, RunElementGUID";
            String extraParamValues = "0, 1, 'A0101010-AAAA-BBBB-2222-3E3E3E3E3E3E', 0, 'eraseme', '00000000-0000-0000-0000-000000000000'";
            id = _lib.WriteParametersRegular(_connxNumber, GetSbyte(_paramTableName), GetSbyte(_traceTableName),
                    (short)timeStepUnit, timeStepQuantity, timeStepCount, startDate,
                    GetSbyte(extraParamNames), GetSbyte(extraParamValues));

            double[] valArray = new double[timeStepCount];
            TSDateValueStruct[] dateValArray = new TSDateValueStruct[timeStepCount],
                                testDateValArray = new TSDateValueStruct[timeStepCount];
            double x = 5.25;
            DateTime curDate = startDate;
            for (int i = 0; i < timeStepCount; i++)
            {
                valArray[i] = x;
                dateValArray[i].Value = x;
                dateValArray[i].Date = curDate;
                x += 1.75;
                curDate = TSDateCalculator.IncrementDate(curDate, timeStepUnit, timeStepQuantity, 1);
            }
            _lib.WriteTraceRegular(_connxNumber, GetSbyte(_paramTableName), GetSbyte(_traceTableName),
                        id, traceNumber, valArray);

            // The method being tested
            _lib.ReadDatesValues(_connxNumber, GetSbyte(_paramTableName), GetSbyte(_traceTableName),
                        id, traceNumber, timeStepCount, ref testDateValArray, startDate, endDate);

            //
            for (int i = 0; i < timeStepCount; i++)
                Assert.AreEqual(dateValArray[i], testDateValArray[i]);
        }
        public void ReadDatesValuesIrregular()
        {
            DateTime startDate = DateTime.Parse("8/10/1999");
            DateTime endDate = DateTime.Parse("2/10/2002");
            int timeStepCount = 40;
            int id, traceNumber = 4;

            String extraParamNames = "TimeSeriesType, Unit_Id, RunGUID, VariableType, VariableName, RunElementGUID";
            String extraParamValues = "0, 1, 'A0101010-AAAA-BBBB-2222-3E3E3E3E3E3E', 0, 'eraseme', '00000000-0000-0000-0000-000000000000'";
            id = _lib.WriteParametersIrregular(_connxNumber, GetSbyte(_paramTableName), GetSbyte(_traceTableName),
                    timeStepCount, startDate, endDate, GetSbyte(extraParamNames), GetSbyte(extraParamValues));

            TSDateValueStruct[] dateValArray = new TSDateValueStruct[timeStepCount],
                                testDateValArray = new TSDateValueStruct[timeStepCount];
            double x = 10.0;
            double y = 1.0;
            DateTime curDate = startDate;
            for (int i = 0; i < timeStepCount; i++)
            {
                dateValArray[i].Value = x;
                dateValArray[i].Date = curDate;
                x *= 1.5;
                y += 0.25;
                curDate = curDate.AddDays(y);
            }
            _lib.WriteTraceIrregular(_connxNumber, GetSbyte(_paramTableName), GetSbyte(_traceTableName),
                        id, traceNumber, dateValArray);

            // The method being tested
            _lib.ReadDatesValues(_connxNumber, GetSbyte(_paramTableName), GetSbyte(_traceTableName),
                        id, traceNumber, timeStepCount, ref testDateValArray, startDate, endDate);

            //
            for (int i = 0; i < timeStepCount; i++)
                Assert.AreEqual(dateValArray[i], testDateValArray[i]);
        }
        public void ErrorHandling2()
        {
            _lib.ResetErrorHandler();

            TSDateValueStruct[] dateValStructArray = new TSDateValueStruct[10];
            // This should cause an error
            _lib.ReadDatesValues(_connxNumber, GetSbyte("TableThatDoesNotExist"), GetSbyte("TableThatWillNeverExist"), 3,
                                    -33, 10, ref dateValStructArray, DateTime.Parse("1/10/1996"), DateTime.Parse("1/10/1996"));

            Assert.IsTrue(_lib.GetHasError(), "GetHasError should have returned True after an error was triggered");

            sbyte[] errorMessage = new sbyte[4096];
            String errorString;
            fixed (sbyte* pErrorMessage = &errorMessage[0])
            {
                _lib.GetErrorMessage(pErrorMessage);
                errorString = new String(pErrorMessage);
            }
            Assert.IsTrue(errorString.Length > 0);
        }
Пример #7
0
        /// <summary>
        /// This method reads the given XML file and stores each of the timeseries described
        /// therein to the database.  For each timeseries that it stores, it adds an item to
        /// list 'tsImportList', which records metadata of the timeseries that is not processed
        /// directly by TimeSeriesLibrary.  Therefore, the process that calls TimeSeriesLibrary
        /// can process tsImportList to complete the importation of the timeseries.
        /// </summary>
        /// <param name="xmlFileName">Name of the file that will be read.  If xmlText is null,
        /// then this parameter must be non-null, and vice-versa.</param>
        /// <param name="xmlText">The text of an XML file that will be read.  If xmlFileName is null,
        /// then this parameter must be non-null, and vice-versa.</param>
        /// <param name="tsImportList">List of TSImport objects that this function records for
        /// each series that is imported.  This method appends the list.</param>
        /// <param name="shouldStoreToDatabase">If true, then this method will write the timeseries from
        /// the XML file to database.  If false, then this method does not write to database.</param>
        /// <param name="shouldRecordDetails">If true, then this method stores the BLOB and detailed
        /// elements to the list of TSImport objects.  If false, then this method does not store
        /// the BLOB to the TSImport object, and all fields that TimeSeriesLibrary does not process
        /// are stored to the TSImport object's UnprocessedElements field.</param>
        /// <returns>The number of time series records that were successfully stored</returns>
        public int ReadAndStore(
            String xmlFileName, String xmlText,
            List <TSImport> tsImportList,
            Boolean shouldStoreToDatabase, Boolean shouldRecordDetails)
        {
            String s;                                                                               // ephemeral String object
            int    numTs = 0;                                                                       // The # of time series successfuly processed by this method

            TSDateCalculator.TimeStepUnitCode TimeStepUnit = TSDateCalculator.TimeStepUnitCode.Day; // to be read from XML
            short    TimeStepQuantity = 1;                                                          // to be read from XML
            DateTime StartDate        = _defaultTime;                                               // to be read from XML

            double[] valueArray   = null;                                                           // to be read from XML
            var      elementNames = new List <String> {
                "TimeSeries", "Pattern"
            };

            // Flags will indicate if the XML is missing any data
            Boolean foundTimeStepUnit, foundTimeStepQuantity, foundStartDate, foundValueArray;

            // Error checks
            if (xmlFileName == null && xmlText == null)
            {
                throw new TSLibraryException(ErrCode.Enum.Xml_Memory_File_Exclusion,
                                             "The method's xmlFileName and xmlText parameters can not both be null.");
            }
            if (xmlFileName != null && xmlText != null)
            {
                throw new TSLibraryException(ErrCode.Enum.Xml_Memory_File_Exclusion,
                                             "The method's xmlFileName and xmlText parameters can not both be non-null.");
            }
            if (shouldStoreToDatabase && TSConnection == null)
            {
                throw new TSLibraryException(ErrCode.Enum.Xml_Connection_Not_Initialized,
                                             "The method is directed to store results to database, " +
                                             "but a database connection has not been assigned in the constructor.");
            }

            // Initialize a Stream object for the XmlReader object to read from.  This method can
            // be called with either the file name of an XML file, or with a string containing the
            // complete text of the XML to be parsed.  The type of Stream object that we initialize
            // depends on which parameter the method was called with.
            Stream xmlStream;

            if (xmlFileName == null)
            {
                xmlStream        = new MemoryStream(Encoding.ASCII.GetBytes(xmlText));
                ReportedFileName = "The given XML text ";
            }
            else
            {
                xmlStream        = new FileStream(xmlFileName, FileMode.Open);
                ReportedFileName = "The XML file '" + xmlFileName + "' ";
            }

            try
            {
                // Loop once for "TimeSeries" and once for "Pattern".  Note that the approach of looping
                // through the entire file twice seems undesirable, but no better option was evident because
                // methods of XmlReader such as 'ReadToNextSibling' do not have an equivalent that could
                // seek *either* "TimeSeries" or "Pattern".
                foreach (String elementName in elementNames)
                {
                    Boolean isPattern = elementName == "Pattern";
                    // Start at the beginning of the XML file
                    xmlStream.Seek(0, SeekOrigin.Begin);
                    // This XmlReader object opens the XML file and parses it for us.  The 'using'
                    // statement ensures that the XmlReader's resources are properly disposed.
                    using (XmlReader xmlReader = XmlReader.Create(xmlStream))
                    {
                        // All of the data that we'll read is contained inside an element named 'Import'
                        try
                        {
                            if (!xmlReader.ReadToFollowing("Import"))
                            {
                                throw new TSLibraryException(ErrCode.Enum.Xml_File_Empty,
                                                             ReportedFileName + "does not contain an <Import> element.");
                            }
                        }
                        catch
                        {
                            throw new TSLibraryException(ErrCode.Enum.Xml_File_Empty,
                                                         ReportedFileName + "does not contain an <Import> element.");
                        }
                        // The file must contain at least one element named 'TimeSeries'.  Move to the first
                        // such element now.
                        if (!xmlReader.ReadToDescendant(elementName))
                        {
                            // if no such element is found then there is nothing to process in this iteration
                            // of the loop.  After the loop is finished, an exception is thrown if no elements
                            // were read.
                            continue;
                        }
                        // do-while loop through all elements named 'TimeSeries'.  There will be one iteration
                        // of this loop for each timeseries in the XML file.
                        do
                        {
                            // Get a new XmlReader object that can not read outside
                            // of the current 'TimeSeries' element.
                            XmlReader oneSeriesXmlReader = xmlReader.ReadSubtree();
                            // A new TSImport object will store properties of this time series
                            // that the TimeSeriesLibrary is not designed to handle.
                            TSImport tsImport = new TSImport(shouldRecordDetails)
                            {
                                IsPattern = isPattern
                            };
                            // Flags will indicate if the XML is missing any data
                            foundTimeStepUnit = foundTimeStepQuantity = foundStartDate = foundValueArray = false;
                            // This default trace number will be used if the "Trace" attribute is not used on a <Data>
                            // element. The default trace value may be reassigned if a <TraceNumber> element is read.
                            int defaultTraceNumber = 1;
                            // Collection of Strings that hold the unparsed DataSeries.  The key of the
                            // Dictionary is the trace number of the DataSeries
                            Dictionary <int, String> DataStrings = new Dictionary <int, String>();

                            // advance the reader past the outer element
                            oneSeriesXmlReader.ReadStartElement();
                            // Read one timeseries from XML
                            while (oneSeriesXmlReader.Read())
                            {
                                Boolean binaryEncoded = false;
                                // If the current position of the reader is on an element's start tag (e.g. <Name>)
                                if (oneSeriesXmlReader.NodeType == XmlNodeType.Element)
                                {
                                    // Note that XML standard is case sensitive
                                    switch (oneSeriesXmlReader.Name)
                                    {
                                    case "Name":
                                        // <Name> is not processed by TimeSeriesLibrary.  Record it on a list
                                        // so another module can process the <Name> field.  Presumably,
                                        // the process will distinguish timeseries based on the <Name> field.
                                        tsImport.Name = oneSeriesXmlReader.ReadElementContentAsString();
                                        break;

                                    case "StartDate":
                                        // TimeSeriesLibrary will store <StartDate> to the data table
                                        s = oneSeriesXmlReader.ReadElementContentAsString();
                                        if (!TimeExtensions.TryParse(s, out StartDate, _defaultTime))
                                        {
                                            throw new TSLibraryException(ErrCode.Enum.Xml_File_StartDate_Unreadable,
                                                                         ReportedFileName
                                                                         + "contains unreadable StartDate element value " + s);
                                        }
                                        foundStartDate = true;
                                        break;

                                    case "TimeStepUnit":
                                        // TimeSeriesLibrary will store <TimeStepUnit> to the data table
                                        s                 = oneSeriesXmlReader.ReadElementContentAsString();
                                        TimeStepUnit      = ParseTimeStepUnit(s);
                                        foundTimeStepUnit = true;
                                        // If it is an irregular time series
                                        if (TimeStepUnit == TSDateCalculator.TimeStepUnitCode.Irregular)
                                        {
                                            // <TimeStepQuantity> and <StartDate> are unnecessary
                                            // and irrelevant to irregular time series
                                            foundTimeStepQuantity = true;
                                            foundStartDate        = true;
                                        }
                                        break;

                                    case "TimeStepQuantity":
                                        // TimeSeriesLibrary will store <TimeStepQuantity> to the data table
                                        s = oneSeriesXmlReader.ReadElementContentAsString();
                                        TimeStepQuantity      = ParseTimeStepQuantity(s);
                                        foundTimeStepQuantity = true;
                                        break;

                                    case "Data":
                                        // <Data> may have a TraceNumber attribute
                                        int traceNumber = 0;
                                        s = oneSeriesXmlReader.GetAttribute("Trace");
                                        if (int.TryParse(s, out traceNumber) == false)
                                        {
                                            traceNumber = 0;
                                        }
                                        if (DataStrings.ContainsKey(traceNumber))
                                        {
                                            throw new TSLibraryException(ErrCode.Enum.Xml_File_Inconsistent,
                                                                         ReportedFileName + "contains a time series with more than "
                                                                         + "one trace number " + traceNumber.ToString());
                                        }
                                        // <Data> contains a whitespace-deliminted string of values
                                        // that comprise the time series
                                        s = oneSeriesXmlReader.ReadElementContentAsString();
                                        // add the unparsed string to a dictionary
                                        // where the trace number is the dictionary key
                                        DataStrings.Add(traceNumber, s);
                                        foundValueArray = true;
                                        break;

                                    case "Encoding":
                                        // The default is that <Data> contains decimal text.
                                        // However, the <Encoding> element may specify that it is
                                        // Base64 encoded.
                                        s = oneSeriesXmlReader.ReadElementContentAsString();
                                        if (s == "Base64" || s == "base64")
                                        {
                                            binaryEncoded = true;
                                        }
                                        break;

                                    case "Apart":     // <Apart> contains the A part of record name from a HECDSS file
                                        tsImport.SetAPart(oneSeriesXmlReader); break;

                                    case "Bpart":     // <Bpart> contains the B part of record name from a HECDSS file
                                        tsImport.SetBPart(oneSeriesXmlReader); break;

                                    case "Cpart":     // <Cpart> contains the C part of record name from a HECDSS file
                                        tsImport.SetCPart(oneSeriesXmlReader); break;

                                    case "Epart":     // <Epart> contains the E part of record name from a HECDSS file
                                        tsImport.SetEPart(oneSeriesXmlReader); break;

                                    case "Units":     // <Units> contains the name of the units of measurement for the time series values
                                        tsImport.SetUnits(oneSeriesXmlReader); break;

                                    case "TimeSeriesType":
                                        // <TimeSeriesType> contains the text name of the time series type,
                                        // [PER-AVER | PER-CUM | INST-VAL | INST-CUM]
                                        tsImport.SetTimeSeriesType(oneSeriesXmlReader); break;

                                    case "TraceNumber":     // <TraceNumber> contains the trace number for an ensemble
                                        defaultTraceNumber = tsImport.GetTraceNumber(oneSeriesXmlReader); break;

                                    case "MultiplicationFactor":
                                        tsImport.SetMultiplicationFactor(oneSeriesXmlReader); break;

                                    default:
                                        // Any other tags are simply copied to the String object
                                        // 'UnprocessedElements'. Here they are stored with
                                        // the enclosing tags (e.g. "<Units>CFS</Units>").
                                        tsImport.AddUnprocessedElement(oneSeriesXmlReader.ReadOuterXml());
                                        break;
                                    }
                                }
                            }
                            // This XmlReader object was created with the ReadSubtree() method so that it would only
                            // be able to read the current time series element.  We have now reached the end of the
                            // time series element, so the XmlReader should be closed.
                            oneSeriesXmlReader.Close();
                            // The record can not be saved to the table if information for some of the fields is missing.
                            // These flags indicate whether each of the required fields was found in the XML file.
                            if (!(foundTimeStepUnit && foundTimeStepQuantity && foundStartDate && foundValueArray))
                            {
                                // One or more required fields were missing, so we'll throw an exception.
                                String errorList, nameString;
                                if (tsImport.Name == "")
                                {
                                    nameString = "unnamed time series";
                                }
                                else
                                {
                                    nameString = "time series named '" + tsImport.Name + "'";
                                }
                                errorList = "Some required subelements were missing from " + nameString
                                            + " in " + ReportedFileName + "\n";
                                if (!foundStartDate)
                                {
                                    errorList += "\n<StartDate> was not found";
                                }
                                if (!foundTimeStepUnit)
                                {
                                    errorList += "\n<TimeStepUnit> was not found";
                                }
                                if (!foundTimeStepQuantity)
                                {
                                    errorList += "\n<TimeStepQuantity> was not found";
                                }
                                if (!foundValueArray)
                                {
                                    errorList += "\n<Data> was not found";
                                }
                                throw new TSLibraryException(ErrCode.Enum.Xml_File_Incomplete, errorList);
                            }
                            // Now that we've established that all fields have been read, we can parse the
                            // string of timeseries values into an array, and save the array to the database.
                            if (TimeStepUnit == TSDateCalculator.TimeStepUnitCode.Irregular)
                            {
                                // IRREGULAR TIME SERIES

                                // The TS object is used to save one record to the database table
                                TS ts = new TS(TSConnection, TableName, TraceTableName);
                                foreach (KeyValuePair <int, String> keyValuePair in DataStrings)
                                {
                                    int traceNumber = keyValuePair.Key;
                                    if (traceNumber == 0)
                                    {
                                        traceNumber = defaultTraceNumber;
                                    }
                                    // Split the big data string into an array of strings.
                                    // The date/time/value triplets will be all collated together.
                                    String[] stringArray = keyValuePair.Value
                                                           .Split(new char[] { }, StringSplitOptions.RemoveEmptyEntries);
                                    // We'll use this date/value structure to build each item of the date/value array
                                    TSDateValueStruct tsv = new TSDateValueStruct();
                                    // allocate the array of date/value pairs
                                    TSDateValueStruct[] dateValueArray = new TSDateValueStruct[stringArray.Length / 3];
                                    // Loop through the array of strings, 3 elements at a time
                                    for (int i = 2; i < stringArray.Length; i += 3)
                                    {
                                        s                     = stringArray[i - 2] + " " + stringArray[i - 1];
                                        tsv.Date              = DateTime.Parse(s);
                                        tsv.Value             = double.Parse(stringArray[i]);
                                        dateValueArray[i / 3] = tsv;
                                    }
                                    if (tsImport.TraceList.Count == 0)
                                    {
                                        // Ignore whatever was entered in the StartDate element, since it
                                        // might conflict with the date/value entries
                                        StartDate = dateValueArray[0].Date;
                                        // Write parameters to the database and record values in the TSImport object
                                        ts.WriteParametersIrregular(shouldStoreToDatabase, tsImport,
                                                                    dateValueArray.Count(), StartDate, dateValueArray.Last().Date,
                                                                    null, null);
                                    }
                                    else
                                    {
                                        if (StartDate != ts.BlobStartDate)
                                        {
                                            throw new TSLibraryException(ErrCode.Enum.Xml_File_Inconsistent,
                                                                         ReportedFileName + "contains a time series "
                                                                         + "with traces that do not overlay each other.");
                                        }
                                    }
                                    ts.WriteTraceIrregular(0, shouldStoreToDatabase, tsImport,
                                                           traceNumber, dateValueArray);
                                }
                                tsImport.RecordFromTS(ts);
                                // Done with the TS object.
                                ts = null;
                            }
                            else
                            {
                                // REGULAR TIME SERIES

                                // The TS object is used to save one record to the database table
                                TS ts = new TS(TSConnection, TableName, TraceTableName);
                                foreach (KeyValuePair <int, String> keyValuePair in DataStrings)
                                {
                                    int traceNumber = keyValuePair.Key;
                                    if (traceNumber == 0)
                                    {
                                        traceNumber = defaultTraceNumber;
                                    }
                                    // Fancy LINQ statement turns the String object into an array of double[]
                                    valueArray = keyValuePair.Value
                                                 .Split(new char[] { }, StringSplitOptions.RemoveEmptyEntries)
                                                 .Select(z => double.Parse(z)).ToArray();
                                    if (tsImport.TraceList.Count == 0)
                                    {
                                        // Write to the database and record values in the TSImport object
                                        ts.WriteParametersRegular(shouldStoreToDatabase, tsImport,
                                                                  (short)TimeStepUnit, TimeStepQuantity, valueArray.Count(),
                                                                  StartDate, null, null);
                                    }
                                    ts.WriteTraceRegular(0, shouldStoreToDatabase, tsImport,
                                                         traceNumber, valueArray);
                                }
                                tsImport.RecordFromTS(ts);
                                // Done with the TS object.
                                ts = null;
                            }

                            // the TSImport object contains data for this timeseries that TSLibrary does not process.
                            // Add the TSImport object to a list that the calling process can read and use.
                            tsImportList.Add(tsImport);
                            numTs++;
                        } while (xmlReader.ReadToNextSibling(elementName));
                    }
                }
                if (numTs == 0)
                {
                    throw new TSLibraryException(ErrCode.Enum.Xml_File_Empty,
                                                 ReportedFileName + " does not contain any "
                                                 + elementNames.Select(ss => "<" + ss + ">").ToStringWithConjunc("or")
                                                 + " element".Pluralize(elementNames.Count) + ".");
                }
            }
            catch (XmlException e)
            {
                // An XmlException was caught somewhere in the lifetime of the object xmlReader,
                // so we can presumably say there was an error in how the XML file was formatted.
                // The information from the XmlException object is included in the error message
                // that we throw here, and the XmlException is included as an inner exception.
                throw new TSLibraryException(ErrCode.Enum.Xml_File_Malformed,
                                             ReportedFileName + "is malformed.\n\n" + e.Message, e);
            }
            finally
            {
                // Disposing the Stream object ensures that the file is closed, if applicable.
                // This is put into the 'finally' clause so that we can ensure that the Stream
                // is closed no matter how we exit this method.
                xmlStream.Dispose();
            }

            return(numTs);
        }
Пример #8
0
        /// <summary>
        /// This private method creates a List of TimeSeriesValue objects from the given BLOB (byte array)
        /// of time series values.  The method takes parameters for a maximum number of values,
        /// an earliest date, and a latest date, so that only a portion of the BLOB might be
        /// converted to the List.  This method is designed to do the operations that are common between
        /// the public methods ConvertBlobToListLimited() and ConvertBlobToListAll().
        /// </summary>
        /// <param name="timeStepUnit">TSDateCalculator.TimeStepUnitCode value for Minute,Hour,Day,Week,Month, Year, or Irregular</param>
        /// <param name="timeStepQuantity">The number of the given unit that defines the time step.
        /// For instance, if the time step is 6 hours long, then this value is 6.  If timeStepUnit is
        /// Irregular, then this value is ignored.</param>
        /// <param name="timeStepCount">the number of time steps that are stored in the blob</param>
        /// <param name="blobStartDate">The DateTime value of the first time step in the BLOB. If
        /// timeStepUnit is Irregular, then this value is ignored.</param>
        /// <param name="applyLimits">If value is true, then nReqValues, reqStartDate, and reqEndDate will be
        /// used to limit the portion of the BLOB that is converted to dateValueList.  If the value is false, then
        /// nReqValues, reqStartDate, and reqEndDate will be ignored.</param>
        /// <param name="nReqValues">The maximum number of time steps that should be added to dateValueList.
        /// If applyLimits==false, then this value is ignored.</param>
        /// <param name="reqStartDate">The earliest date that will be added to dateValueList.
        /// If applyLimits==false, then this value is ignored.</param>
        /// <param name="reqEndDate">The latest date that will be added to dateValueList.
        /// If applyLimits==false, then this value is ignored.</param>
        /// <param name="blobData">The BLOB (byte array) that this method will convert into a List</param>
        /// <param name="dateValueList">The List of TimeSeriesValues that this method will create from the BLOB.</param>
        /// <param name="compressionCode">a generation number that indicates what compression technique to use</param>
        /// <returns>The number of time steps added to dateValueList</returns>
        private unsafe int ConvertBlobToList(
            TSDateCalculator.TimeStepUnitCode timeStepUnit, short timeStepQuantity,
            int timeStepCount, DateTime blobStartDate, Boolean applyLimits,
            int nReqValues, DateTime reqStartDate, DateTime reqEndDate,
            Byte[] blobData, ref List <TimeSeriesValue> dateValueList, int compressionCode)
        {
            int nValuesRead = 0;

            if (timeStepUnit == TSDateCalculator.TimeStepUnitCode.Irregular)
            {
                // IRREGULAR TIME SERIES

                // If we're not limiting the output list (i.e., we're returning every time step from
                // the BLOB), then set the size of the intermediate array to match the size of the BLOB.
                if (applyLimits == false)
                {
                    nReqValues = timeStepCount;
                }
                // Allocate an array of date/value pairs that TSBlobCoder method will fill
                TSDateValueStruct[] dateValueArray = new TSDateValueStruct[nReqValues];
                // Method in the TSBlobCoder class does the real work
                nValuesRead = TSBlobCoder.ConvertBlobToArrayIrregular(timeStepCount, applyLimits,
                                                                      nReqValues, reqStartDate, reqEndDate,
                                                                      blobData, dateValueArray, compressionCode);
                // resize the array so that the List that we make from it will have exactly the right size
                if (nValuesRead != nReqValues)
                {
                    Array.Resize <TSDateValueStruct>(ref dateValueArray, nValuesRead);
                }
                // Convert the array of date/value pairs into the List that will be used by the caller
                dateValueList = dateValueArray
                                .Select(tsv => (TimeSeriesValue)tsv).ToList <TimeSeriesValue>();
            }
            else
            {
                // REGULAR TIME SERIES

                // If we're not limiting the output list (i.e., we're returning every time step from
                // the BLOB), then set the size of the intermediate array to match the size of the BLOB.
                if (applyLimits == false)
                {
                    nReqValues = timeStepCount;
                }
                // Allocate an array of values that TSBlobCoder method will fill
                double[] valueArray = new double[nReqValues];
                // Method in the TSBlobCoder class does the real work
                nValuesRead = TSBlobCoder.ConvertBlobToArrayRegular(timeStepUnit, timeStepQuantity,
                                                                    timeStepCount, blobStartDate, applyLimits,
                                                                    nReqValues, reqStartDate, reqEndDate,
                                                                    blobData, valueArray, compressionCode);
                // Allocate an array to hold the time series' date values
                DateTime[] dateArray = new DateTime[nValuesRead];
                // Fill the array with the date values corresponding to the time steps defined
                // for this time series in the database.
                TSDateCalculator.FillDateArray(timeStepUnit, timeStepQuantity, nValuesRead, dateArray, reqStartDate);
                // Allocate a List of date/value pairs that will be used by the caller
                dateValueList = new List <TimeSeriesValue>(nValuesRead);
                // Loop through all values, building the List of date/value pairs out of the
                // primitive array of dates and primitive array of values.
                int i;
                for (i = 0; i < nValuesRead; i++)
                {
                    dateValueList.Add(new TimeSeriesValue {
                        Date = dateArray[i], Value = valueArray[i]
                    });
                }
                nValuesRead = i;
            }
            return(nValuesRead);
        }
Пример #9
0
        /// <summary>
        /// This private method creates a List of TimeSeriesValue objects from the given BLOB (byte array)
        /// of time series values.  The method takes parameters for a maximum number of values,
        /// an earliest date, and a latest date, so that only a portion of the BLOB might be 
        /// converted to the List.  This method is designed to do the operations that are common between
        /// the public methods ConvertBlobToListLimited() and ConvertBlobToListAll().
        /// </summary>
        /// <param name="timeStepUnit">TSDateCalculator.TimeStepUnitCode value for Minute,Hour,Day,Week,Month, Year, or Irregular</param>
        /// <param name="timeStepQuantity">The number of the given unit that defines the time step.
        /// For instance, if the time step is 6 hours long, then this value is 6.  If timeStepUnit is 
        /// Irregular, then this value is ignored.</param>
        /// <param name="timeStepCount">the number of time steps that are stored in the blob</param>
        /// <param name="blobStartDate">The DateTime value of the first time step in the BLOB. If 
        /// timeStepUnit is Irregular, then this value is ignored.</param>
        /// <param name="applyLimits">If value is true, then nReqValues, reqStartDate, and reqEndDate will be
        /// used to limit the portion of the BLOB that is converted to dateValueList.  If the value is false, then
        /// nReqValues, reqStartDate, and reqEndDate will be ignored.</param>
        /// <param name="nReqValues">The maximum number of time steps that should be added to dateValueList.
        /// If applyLimits==false, then this value is ignored.</param>
        /// <param name="reqStartDate">The earliest date that will be added to dateValueList.
        /// If applyLimits==false, then this value is ignored.</param>
        /// <param name="reqEndDate">The latest date that will be added to dateValueList.
        /// If applyLimits==false, then this value is ignored.</param>
        /// <param name="blobData">The BLOB (byte array) that this method will convert into a List</param>
        /// <param name="dateValueList">The List of TimeSeriesValues that this method will create from the BLOB.</param>
        /// <param name="compressionCode">a generation number that indicates what compression technique to use</param>
        /// <returns>The number of time steps added to dateValueList</returns>
        private unsafe int ConvertBlobToList(
            TSDateCalculator.TimeStepUnitCode timeStepUnit, short timeStepQuantity,
            int timeStepCount, DateTime blobStartDate, Boolean applyLimits,
            int nReqValues, DateTime reqStartDate, DateTime reqEndDate,
            Byte[] blobData, ref List<TimeSeriesValue> dateValueList, int compressionCode)
        {
            int nValuesRead = 0;

            if (timeStepUnit == TSDateCalculator.TimeStepUnitCode.Irregular)
            {
                // IRREGULAR TIME SERIES

                // If we're not limiting the output list (i.e., we're returning every time step from
                // the BLOB), then set the size of the intermediate array to match the size of the BLOB.
                if (applyLimits == false)
                    nReqValues = timeStepCount;
                // Allocate an array of date/value pairs that TSBlobCoder method will fill
                TSDateValueStruct[] dateValueArray = new TSDateValueStruct[nReqValues];
                // Method in the TSBlobCoder class does the real work
                nValuesRead = TSBlobCoder.ConvertBlobToArrayIrregular(timeStepCount, applyLimits,
                                    nReqValues, reqStartDate, reqEndDate,
                                    blobData, dateValueArray, compressionCode);
                // resize the array so that the List that we make from it will have exactly the right size
                if(nValuesRead!=nReqValues)
                    Array.Resize<TSDateValueStruct>(ref dateValueArray, nValuesRead);
                // Convert the array of date/value pairs into the List that will be used by the caller
                dateValueList = dateValueArray
                        .Select(tsv => (TimeSeriesValue)tsv).ToList<TimeSeriesValue>();
            }
            else
            {
                // REGULAR TIME SERIES

                // If we're not limiting the output list (i.e., we're returning every time step from
                // the BLOB), then set the size of the intermediate array to match the size of the BLOB.
                if (applyLimits == false)
                    nReqValues = timeStepCount;
                // Allocate an array of values that TSBlobCoder method will fill
                double[] valueArray = new double[nReqValues];
                // Method in the TSBlobCoder class does the real work
                nValuesRead = TSBlobCoder.ConvertBlobToArrayRegular(timeStepUnit, timeStepQuantity,
                                     timeStepCount, blobStartDate, applyLimits,
                                     nReqValues, reqStartDate, reqEndDate,
                                     blobData, valueArray, compressionCode);
                // Allocate an array to hold the time series' date values
                DateTime[] dateArray = new DateTime[nValuesRead];
                // Fill the array with the date values corresponding to the time steps defined
                // for this time series in the database.
                TSDateCalculator.FillDateArray(timeStepUnit, timeStepQuantity, nValuesRead, dateArray, reqStartDate);
                // Allocate a List of date/value pairs that will be used by the caller
                dateValueList = new List<TimeSeriesValue>(nValuesRead);
                // Loop through all values, building the List of date/value pairs out of the
                // primitive array of dates and primitive array of values.
                int i;
                for (i = 0; i < nValuesRead; i++)
                {
                    dateValueList.Add(new TimeSeriesValue { Date = dateArray[i], Value = valueArray[i] });
                }
                nValuesRead = i;
            }
            return nValuesRead;
        }
Пример #10
0
        public void WriteTraceIrregular(
                    int connectionNumber, sbyte* pParamTableName, sbyte* pTraceTableName, 
                    int id, int traceNumber, TSDateValueStruct[] dateValueArray)
        {
            try
            {
                // Convert from simple character byte array to .Net String object
                String paramTableName = new String(pParamTableName);
                String traceTableName = new String(pTraceTableName);
                // Get the connection that we'll pass along.
                SqlConnection connx = GetConnectionFromId(connectionNumber);
                // Construct new TS object with SqlConnection object and table name
                TS ts = new TS(connx, TSLib.ConnxObject, paramTableName, traceTableName);

                ts.WriteTraceIrregular(id, true, null, traceNumber, dateValueArray);
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
            }
        }
Пример #11
0
        public int ReadDatesValues(
                int connectionNumber, sbyte *pParamTableName, sbyte *pTraceTableName, int id, int traceNumber,
                int nReqValues, ref TSDateValueStruct[] dateValueArray, DateTime reqStartDate, DateTime reqEndDate)
        {
            try
            {
                // Convert from simple character byte array to .Net String object
                String paramTableName = new String(pParamTableName);
                String traceTableName = new String(pTraceTableName);
                // Get the connection that we'll pass along.
                SqlConnection connx = GetConnectionFromId(connectionNumber);
                // Construct new TS object with SqlConnection object and table name
                TS ts = new TS(connx, TSLib.ConnxObject, paramTableName, traceTableName);

                int nValuesRead = 0;
                // Read the parameters of the time series so that we'll know if it's regular or irregular
                if (!ts.IsInitialized) ts.Initialize(id);

                // The operations will differ for regular and irregular time series
                if (ts.TimeStepUnit == TSDateCalculator.TimeStepUnitCode.Irregular)
                {
                    // IRREGULAR TIME SERIES

                    // Read the date/value array from the database
                    nValuesRead = ts.ReadValuesIrregular(id, traceNumber, nReqValues, dateValueArray, reqStartDate, reqEndDate);
                }
                else
                {
                    // REGULAR TIME SERIES

                    // Allocate an array to hold the time series' data values
                    double[] valueArray = new double[nReqValues];
                    // Read the data values from the database
                    nValuesRead = ts.ReadValuesRegular(id, traceNumber, nReqValues, valueArray, reqStartDate, reqEndDate);
                    // Allocate an array to hold the time series' date values
                    DateTime[] dateArray = new DateTime[nValuesRead];
                    // Fill the array with the date values corresponding to the time steps defined
                    // for this time series in the database.
                    ts.FillDateArray(id, nValuesRead, dateArray, reqStartDate);
                    // Loop through all values, filling the array of date/value pairs from the
                    // primitive array of dates and primitive array of values.
                    int i;
                    for (i = 0; i < nValuesRead; i++)
                    {
                        dateValueArray[i].Date = dateArray[i];
                        dateValueArray[i].Value = valueArray[i];
                        // So far we have ignored the requested end date.  However, at this
                        // stage we won't make the list any longer than was requested by the caller.
                        if (dateValueArray[i].Date >= reqEndDate)
                        {
                            i++;
                            break;
                        }
                    }
                    nValuesRead = i;
                }
                return nValuesRead;
            }
            catch (Exception e)
            {
                ErrorMessage = e.Message;
                return 0;
            }
        }