Index: Ringtoets/HydraRing/src/Ringtoets.HydraRing.IO/HydraulicLocationConfigurationDatabase/HydraulicLocationConfigurationDatabaseReader.cs =================================================================== diff -u -rff28b61980b68b15722adaf34f3c71321dd1b47e -r8e4f3d24c6dc2bb0536a5585358732bb74b7f9bf --- Ringtoets/HydraRing/src/Ringtoets.HydraRing.IO/HydraulicLocationConfigurationDatabase/HydraulicLocationConfigurationDatabaseReader.cs (.../HydraulicLocationConfigurationDatabaseReader.cs) (revision ff28b61980b68b15722adaf34f3c71321dd1b47e) +++ Ringtoets/HydraRing/src/Ringtoets.HydraRing.IO/HydraulicLocationConfigurationDatabase/HydraulicLocationConfigurationDatabaseReader.cs (.../HydraulicLocationConfigurationDatabaseReader.cs) (revision 8e4f3d24c6dc2bb0536a5585358732bb74b7f9bf) @@ -58,9 +58,21 @@ /// /// The track id to read the location configurations for. /// A read hydraulic location configuration database. + /// Thrown when hydraulic location configuration database + /// could not be read. + /// Thrown when the database returned incorrect values for + /// required properties. public ReadHydraulicLocationConfigurationDatabase Read(long trackId) { - return new ReadHydraulicLocationConfigurationDatabase(GetLocationIdsByTrackId(trackId)); + bool isScenarioInformationPresent = IsScenarioInformationTablePresent(); + IEnumerable configurationSettings = + isScenarioInformationPresent + ? GetConfigurationSettings() + : Enumerable.Empty(); + + return new ReadHydraulicLocationConfigurationDatabase(GetLocationIdsByTrackId(trackId), + isScenarioInformationPresent, + configurationSettings); } /// @@ -130,5 +142,106 @@ return locationLookup.Select(lookup => new ReadHydraulicLocationMapping(lookup.Key, lookup.Value)).ToArray(); } + + /// + /// Gets the hydraulic location configuration settings from the database. + /// + /// A collection of the read hydraulic configuration database settings. + /// Thrown when the database query failed. + /// Thrown when the database returned incorrect values for + /// required properties. + private IEnumerable GetConfigurationSettings() + { + try + { + return GetConfigurationSettingsFromDatabase(); + } + catch (SQLiteException exception) + { + string message = new FileReaderErrorMessageBuilder(Path).Build(Resources.HydraulicLocationConfigurationDatabaseReader_Critical_Unexpected_Exception); + throw new CriticalFileReadException(message, exception); + } + } + + /// + /// Determines whether the table related to the scenario information is present in the database. + /// + /// true if the table is present; false otherwise. + /// Thrown when the database query failed. + /// Thrown when the information could not be read from the database file.. + private bool IsScenarioInformationTablePresent() + { + const string validationQuery = "SELECT COUNT() = 1 AS IsScenarioInformationPresent FROM sqlite_master WHERE type = 'table' AND name='ScenarioInformation'"; + using (IDataReader dataReader = CreateDataReader(validationQuery)) + { + if (dataReader.Read()) + { + return Convert.ToBoolean(dataReader["IsScenarioInformationPresent"]); + } + + string message = new FileReaderErrorMessageBuilder(Path).Build(Resources.HydraulicBoundaryDatabaseReader_Critical_Unexpected_value_on_column); + throw new CriticalFileReadException(message); + } + } + + /// + /// Gets the hydraulic location configuration settings from the database. + /// + /// A collection of the read hydraulic configuration database settings. + /// Thrown when the database query failed. + /// Thrown when the database returned incorrect values for + /// required properties. + private IEnumerable GetConfigurationSettingsFromDatabase() + { + const string query = "SELECT * FROM ScenarioInformation"; + var readSettings = new List(); + using (IDataReader dataReader = CreateDataReader(query)) + { + while (MoveNext(dataReader)) + { + readSettings.Add(ReadSetting(dataReader)); + } + } + + return readSettings; + } + + /// + /// Reads the hydraulic location configuration setting from the database. + /// + /// The which is used to read the data. + /// The read . + /// Thrown when the settings could not be read. + /// Thrown when the database returned incorrect values for + /// required properties. + private ReadHydraulicLocationConfigurationDatabaseSettings ReadSetting(IDataReader reader) + { + try + { + var scenarioName = reader.Read("ScenarioName"); + var year = reader.Read("Year"); + var scope = reader.Read("Scope"); + var seaLevel = reader.Read("SeaLevel"); + var riverDischarge = reader.Read("RiverDischarge"); + var lakeLevel = reader.Read("LakeLevel"); + var windDirection = reader.Read("WindDirection"); + var windSpeed = reader.Read("WindSpeed"); + var comment = reader.Read("Comment"); + + return new ReadHydraulicLocationConfigurationDatabaseSettings(scenarioName, year, scope, + seaLevel, riverDischarge, lakeLevel, + windDirection, windSpeed, comment); + } + catch (ConversionException e) + { + string message = new FileReaderErrorMessageBuilder(Path).Build(Resources.HydraulicBoundaryDatabaseReader_Critical_Unexpected_value_on_column); + throw new LineParseException(message, e); + } + catch (ArgumentException e) + { + string message = new FileReaderErrorMessageBuilder(Path).Build(Resources.HydraulicBoundaryDatabaseReader_Critical_Unexpected_value_on_column); + throw new CriticalFileReadException(message, e); + } + } } } \ No newline at end of file Index: Ringtoets/HydraRing/src/Ringtoets.HydraRing.IO/HydraulicLocationConfigurationDatabase/ReadHydraulicLocationConfigurationDatabase.cs =================================================================== diff -u -r7cf555dac4d0ea4187b0771e62a7fdd65ee10a92 -r8e4f3d24c6dc2bb0536a5585358732bb74b7f9bf --- Ringtoets/HydraRing/src/Ringtoets.HydraRing.IO/HydraulicLocationConfigurationDatabase/ReadHydraulicLocationConfigurationDatabase.cs (.../ReadHydraulicLocationConfigurationDatabase.cs) (revision 7cf555dac4d0ea4187b0771e62a7fdd65ee10a92) +++ Ringtoets/HydraRing/src/Ringtoets.HydraRing.IO/HydraulicLocationConfigurationDatabase/ReadHydraulicLocationConfigurationDatabase.cs (.../ReadHydraulicLocationConfigurationDatabase.cs) (revision 8e4f3d24c6dc2bb0536a5585358732bb74b7f9bf) @@ -33,14 +33,34 @@ /// /// The location id mappings of the read hydraulic location /// configuration database. - internal ReadHydraulicLocationConfigurationDatabase(IEnumerable locationIdMappings) + /// Indicator whether scenario information is present in the hydraulic location + /// configuration database. + /// The hydraulic location configuration settings + /// of the read hydraulic location database. + /// Thrown when + /// ic null. + internal ReadHydraulicLocationConfigurationDatabase(IEnumerable locationIdMappings, + bool isScenarioInformationPresent, + IEnumerable readHydraulicLocationConfigurationDatabaseSettings) { LocationIdMappings = locationIdMappings; + IsScenarioInformationPresent = isScenarioInformationPresent; + ReadHydraulicLocationConfigurationDatabaseSettings = readHydraulicLocationConfigurationDatabaseSettings; } /// /// Gets the location id mappings of the read hydraulic location configuration database. /// public IEnumerable LocationIdMappings { get; } + + /// + /// Gets whether the scenario information is present in the hydraulic location configuration database. + /// + public bool IsScenarioInformationPresent { get; } + + /// + /// Gets the settings of the read hydraulic location configuration database. + /// + public IEnumerable ReadHydraulicLocationConfigurationDatabaseSettings { get; } } } \ No newline at end of file Index: Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.Test/HydraulicLocationConfigurationDatabase/HydraulicLocationConfigurationDatabaseReaderTest.cs =================================================================== diff -u -r7cf555dac4d0ea4187b0771e62a7fdd65ee10a92 -r8e4f3d24c6dc2bb0536a5585358732bb74b7f9bf --- Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.Test/HydraulicLocationConfigurationDatabase/HydraulicLocationConfigurationDatabaseReaderTest.cs (.../HydraulicLocationConfigurationDatabaseReaderTest.cs) (revision 7cf555dac4d0ea4187b0771e62a7fdd65ee10a92) +++ Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.Test/HydraulicLocationConfigurationDatabase/HydraulicLocationConfigurationDatabaseReaderTest.cs (.../HydraulicLocationConfigurationDatabaseReaderTest.cs) (revision 8e4f3d24c6dc2bb0536a5585358732bb74b7f9bf) @@ -20,6 +20,7 @@ // All rights reserved. using System; +using System.Collections.Generic; using System.Data.SQLite; using System.IO; using System.Linq; @@ -60,7 +61,7 @@ public void Constructor_ValidFile_ExpectedValues() { // Setup - string dbFile = Path.Combine(testDataPath, "complete.sqlite"); + string dbFile = Path.Combine(testDataPath, "hlcdWithoutScenarioInformation.sqlite"); // Call using (var hydraulicBoundaryDatabaseReader = new HydraulicLocationConfigurationDatabaseReader(dbFile)) @@ -73,10 +74,10 @@ [Test] [TestCase(18169, 1000, 1801000)] [TestCase(6, 1000, 0)] - public void Read_ValidFile_ExpectedValues(int trackId, int hrdLocationId, int expectedLocationId) + public void Read_ValidFileWithoutScenarioInformation_ExpectedValues(int trackId, int hrdLocationId, int expectedLocationId) { // Setup - string dbFile = Path.Combine(testDataPath, "complete.sqlite"); + string dbFile = Path.Combine(testDataPath, "hlcdWithoutScenarioInformation.sqlite"); using (var hydraulicBoundaryDatabaseReader = new HydraulicLocationConfigurationDatabaseReader(dbFile)) { @@ -88,10 +89,123 @@ .Select(m => m.HlcdLocationId) .SingleOrDefault(); Assert.AreEqual(expectedLocationId, actualLocationId); + Assert.IsFalse(readHydraulicLocationConfigurationDatabase.IsScenarioInformationPresent); + CollectionAssert.IsEmpty(readHydraulicLocationConfigurationDatabase.ReadHydraulicLocationConfigurationDatabaseSettings); } } [Test] + [TestCase(18169, 1000, 1801000)] + [TestCase(6, 1000, 0)] + public void Read_ValidFileWithScenarioInformation_ExpectedValues(int trackId, int hrdLocationId, int expectedLocationId) + { + // Setup + string dbFile = Path.Combine(testDataPath, "hlcdWithScenarioInformation.sqlite"); + + using (var hydraulicBoundaryDatabaseReader = new HydraulicLocationConfigurationDatabaseReader(dbFile)) + { + // Call + ReadHydraulicLocationConfigurationDatabase readHydraulicLocationConfigurationDatabase = hydraulicBoundaryDatabaseReader.Read(trackId); + + // Assert + long actualLocationId = readHydraulicLocationConfigurationDatabase.LocationIdMappings.Where(m => m.HrdLocationId == hrdLocationId) + .Select(m => m.HlcdLocationId) + .SingleOrDefault(); + Assert.AreEqual(expectedLocationId, actualLocationId); + Assert.IsTrue(readHydraulicLocationConfigurationDatabase.IsScenarioInformationPresent); + IEnumerable readHydraulicLocationConfigurationDatabaseSettings = + readHydraulicLocationConfigurationDatabase.ReadHydraulicLocationConfigurationDatabaseSettings; + Assert.AreEqual(2, readHydraulicLocationConfigurationDatabaseSettings.Count()); + + CollectionAssert.AreEqual(new[] + { + "ScenarioName WBI2017", + "ScenarioName WBI2018" + }, readHydraulicLocationConfigurationDatabaseSettings.Select(s => s.ScenarioName)); + CollectionAssert.AreEqual(new[] + { + 2023, + 2024 + }, readHydraulicLocationConfigurationDatabaseSettings.Select(s => s.Year)); + CollectionAssert.AreEqual(new[] + { + "Scope WBI2017", + "Scope WBI2018" + }, readHydraulicLocationConfigurationDatabaseSettings.Select(s => s.Scope)); + CollectionAssert.AreEqual(new[] + { + "SeaLevel WBI2017", + "SeaLevel WBI2018" + }, readHydraulicLocationConfigurationDatabaseSettings.Select(s => s.SeaLevel)); + CollectionAssert.AreEqual(new[] + { + "RiverDischarge WBI2017", + "RiverDischarge WBI2018" + }, readHydraulicLocationConfigurationDatabaseSettings.Select(s => s.RiverDischarge)); + CollectionAssert.AreEqual(new[] + { + "LakeLevel WBI2017", + "LakeLevel WBI2018" + }, readHydraulicLocationConfigurationDatabaseSettings.Select(s => s.LakeLevel)); + CollectionAssert.AreEqual(new[] + { + "WindDirection WBI2017", + "WindDirection WBI2018" + }, readHydraulicLocationConfigurationDatabaseSettings.Select(s => s.WindDirection)); + CollectionAssert.AreEqual(new[] + { + "WindSpeed WBI2017", + "WindSpeed WBI2018" + }, readHydraulicLocationConfigurationDatabaseSettings.Select(s => s.WindSpeed)); + CollectionAssert.AreEqual(new[] + { + "Comment WBI2017", + "Comment WBI2018" + }, readHydraulicLocationConfigurationDatabaseSettings.Select(s => s.Comment)); + } + } + + [Test] + public void Read_FileWithScenarioInformationAndMissingColumns_ThrowsCriticalFileReadException() + { + // Setup + const int trackId = 18169; + string dbFile = Path.Combine(testDataPath, "hlcdWithScenarioInformationMissingColumn.sqlite"); + + using (var hydraulicBoundaryDatabaseReader = new HydraulicLocationConfigurationDatabaseReader(dbFile)) + { + // Call + TestDelegate test = () => hydraulicBoundaryDatabaseReader.Read(trackId); + + // Assert + string expectedMessage = new FileReaderErrorMessageBuilder(dbFile).Build("Kritieke fout opgetreden bij het uitlezen van waardes uit kolommen in de database."); + var exception = Assert.Throws(test); + Assert.AreEqual(expectedMessage, exception.Message); + Assert.IsInstanceOf(exception.InnerException); + } + } + + [Test] + public void Read_FileWithScenarioInformationAndInvalidData_ThrowsLineParseException() + { + // Setup + const int trackId = 18169; + string dbFile = Path.Combine(testDataPath, "hlcdWithScenarioInformationInvalidData.sqlite"); + + using (var hydraulicBoundaryDatabaseReader = new HydraulicLocationConfigurationDatabaseReader(dbFile)) + { + // Call + TestDelegate test = () => hydraulicBoundaryDatabaseReader.Read(trackId); + + // Assert + string expectedMessage = new FileReaderErrorMessageBuilder(dbFile).Build("Kritieke fout opgetreden bij het uitlezen van waardes uit kolommen in de database."); + var exception = Assert.Throws(test); + Assert.AreEqual(expectedMessage, exception.Message); + Assert.IsInstanceOf(exception.InnerException); + } + } + + [Test] public void Read_AmbiguousLocations_ReturnsFirstLocationIdAndLogsWarning() { // Setup Index: Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.Test/HydraulicLocationConfigurationDatabase/ReadHydraulicLocationConfigurationDatabaseTest.cs =================================================================== diff -u -r7cf555dac4d0ea4187b0771e62a7fdd65ee10a92 -r8e4f3d24c6dc2bb0536a5585358732bb74b7f9bf --- Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.Test/HydraulicLocationConfigurationDatabase/ReadHydraulicLocationConfigurationDatabaseTest.cs (.../ReadHydraulicLocationConfigurationDatabaseTest.cs) (revision 7cf555dac4d0ea4187b0771e62a7fdd65ee10a92) +++ Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.Test/HydraulicLocationConfigurationDatabase/ReadHydraulicLocationConfigurationDatabaseTest.cs (.../ReadHydraulicLocationConfigurationDatabaseTest.cs) (revision 8e4f3d24c6dc2bb0536a5585358732bb74b7f9bf) @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Linq; +using Core.Common.TestUtil; using NUnit.Framework; using Ringtoets.HydraRing.IO.HydraulicLocationConfigurationDatabase; @@ -33,13 +34,18 @@ public void Constructor_ExpectedValues() { // Setup + var random = new Random(21); + bool isScenarioInformationPresent = random.NextBoolean(); IEnumerable locationIdMappings = Enumerable.Empty(); + IEnumerable databaseSettings = Enumerable.Empty(); // Call - var readDatabase = new ReadHydraulicLocationConfigurationDatabase(locationIdMappings); + var readDatabase = new ReadHydraulicLocationConfigurationDatabase(locationIdMappings, isScenarioInformationPresent, databaseSettings); // Assert Assert.AreSame(locationIdMappings, readDatabase.LocationIdMappings); + Assert.AreEqual(isScenarioInformationPresent, readDatabase.IsScenarioInformationPresent); + Assert.AreSame(databaseSettings, readDatabase.ReadHydraulicLocationConfigurationDatabaseSettings); } } } \ No newline at end of file Index: Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.Test/test-data/HydraulicLocationConfigurationDatabase/complete.sqlite =================================================================== diff -u -rf8c28b3b04cdabb62ea37772efcb1f4ebbbf2b9e -r8e4f3d24c6dc2bb0536a5585358732bb74b7f9bf Binary files differ Index: Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.Test/test-data/HydraulicLocationConfigurationDatabase/hlcdWithScenarioInformation.sqlite =================================================================== diff -u Binary files differ Index: Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.Test/test-data/HydraulicLocationConfigurationDatabase/hlcdWithScenarioInformationInvalidData.sqlite =================================================================== diff -u Binary files differ Index: Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.Test/test-data/HydraulicLocationConfigurationDatabase/hlcdWithScenarioInformationMissingColumn.sqlite =================================================================== diff -u Binary files differ Index: Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.Test/test-data/HydraulicLocationConfigurationDatabase/hlcdWithoutScenarioInformation.sqlite =================================================================== diff -u Binary files differ Index: Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.TestUtil/ReadHydraulicLocationConfigurationDatabaseTestFactory.cs =================================================================== diff -u -raffab28216d928fc119f636dca96f4b4d742e9c6 -r8e4f3d24c6dc2bb0536a5585358732bb74b7f9bf --- Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.TestUtil/ReadHydraulicLocationConfigurationDatabaseTestFactory.cs (.../ReadHydraulicLocationConfigurationDatabaseTestFactory.cs) (revision affab28216d928fc119f636dca96f4b4d742e9c6) +++ Ringtoets/HydraRing/test/Ringtoets.HydraRing.IO.TestUtil/ReadHydraulicLocationConfigurationDatabaseTestFactory.cs (.../ReadHydraulicLocationConfigurationDatabaseTestFactory.cs) (revision 8e4f3d24c6dc2bb0536a5585358732bb74b7f9bf) @@ -52,7 +52,9 @@ public static ReadHydraulicLocationConfigurationDatabase Create(IEnumerable locationIds) { return new ReadHydraulicLocationConfigurationDatabase(locationIds.Select(locationId => new ReadHydraulicLocationMapping(locationId, locationId + 100)) - .ToArray()); + .ToList(), + false, + Enumerable.Empty()); } } } \ No newline at end of file