Index: Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj
===================================================================
diff -u -r8dfec2e1be6d23c02919ff849906fc89822f99b3 -re41a8cc75ec6e93aee52452aa50f47638a044feb
--- Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj (.../Ringtoets.Common.IO.csproj) (revision 8dfec2e1be6d23c02919ff849906fc89822f99b3)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj (.../Ringtoets.Common.IO.csproj) (revision e41a8cc75ec6e93aee52452aa50f47638a044feb)
@@ -117,6 +117,7 @@
+
Index: Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/CriticalProfileProperties.cs
===================================================================
diff -u
--- Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/CriticalProfileProperties.cs (revision 0)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/CriticalProfileProperties.cs (revision e41a8cc75ec6e93aee52452aa50f47638a044feb)
@@ -0,0 +1,80 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of Ringtoets.
+//
+// Ringtoets is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using Core.Common.Base.IO;
+using Core.Common.IO.Readers;
+using Core.Common.Utils.Builders;
+using Ringtoets.Common.IO.Properties;
+using Ringtoets.Common.IO.SoilProfile.Schema;
+
+namespace Ringtoets.Common.IO.SoilProfile
+{
+ ///
+ /// This class describes properties which are critical when reading soil profiles from a data source.
+ /// If obtaining properties could not be obtained, then it is impossible to guarantee a correct import.
+ ///
+ internal class CriticalProfileProperties
+ {
+ ///
+ /// Creates a new instance of , which contains properties
+ /// that are critical for reading profiles. If these properties cannot be read, then something
+ /// went wrong while querying the database.
+ ///
+ /// The from which to obtain the critical properties.
+ /// Thrown when the values in the database could not be
+ /// casted to the expected column types.
+ public CriticalProfileProperties(IRowBasedDatabaseReader reader)
+ {
+ try
+ {
+ ProfileName = reader.Read(SoilProfileTableDefinitions.ProfileName);
+ LayerCount = reader.Read(SoilProfileTableDefinitions.LayerCount);
+ ProfileId = reader.Read(SoilProfileTableDefinitions.SoilProfileId);
+ }
+ catch (InvalidCastException e)
+ {
+ var messageBuilder = new FileReaderErrorMessageBuilder(reader.Path);
+ if (!string.IsNullOrEmpty(ProfileName))
+ {
+ messageBuilder.WithSubject(string.Format(Resources.SoilProfileReader_SoilProfileName_0_, ProfileName));
+ }
+ string message = messageBuilder.Build(Resources.SoilProfileReader_Critical_Unexpected_value_on_column);
+ throw new CriticalFileReadException(message, e);
+ }
+ }
+
+ ///
+ /// The name of the profile to read
+ ///
+ public string ProfileName { get; }
+
+ ///
+ /// The number of layers that the profile to read has
+ ///
+ public long LayerCount { get; }
+
+ ///
+ /// Gets the database identifier of the profile.
+ ///
+ public long ProfileId { get; }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/SoilProfile1DReader.cs
===================================================================
diff -u -r22cfdf3a1943df34a0e6cfd57c82faedfed781db -re41a8cc75ec6e93aee52452aa50f47638a044feb
--- Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/SoilProfile1DReader.cs (.../SoilProfile1DReader.cs) (revision 22cfdf3a1943df34a0e6cfd57c82faedfed781db)
+++ Ringtoets/Common/src/Ringtoets.Common.IO/SoilProfile/SoilProfile1DReader.cs (.../SoilProfile1DReader.cs) (revision e41a8cc75ec6e93aee52452aa50f47638a044feb)
@@ -139,50 +139,49 @@
/// Tries to read and create a .
///
/// The read .
- /// Thrown when reading properties of the profile failed.
+ /// Thrown when encountering an unrecoverable error
+ /// while reading the profile.
+ /// Thrown when reading properties of the profile
+ /// failed.
private SoilProfile1D TryReadSoilProfile()
{
- long profileId = ReadProfileId();
+ var criticalProperties = new CriticalProfileProperties(this);
var soilLayers = new List();
RequiredProfileProperties properties;
try
{
- properties = new RequiredProfileProperties(this);
+ properties = new RequiredProfileProperties(this, criticalProperties.ProfileName);
- for (var i = 1; i <= properties.LayerCount; i++)
+ for (var i = 1; i <= criticalProperties.LayerCount; i++)
{
- soilLayers.Add(ReadSoilLayerFrom(this, properties.ProfileName));
+ soilLayers.Add(ReadSoilLayerFrom(this, criticalProperties.ProfileName));
MoveNext();
}
}
catch (SoilProfileReadException)
{
- MoveToNextProfile(profileId);
+ MoveToNextProfile(criticalProperties.ProfileId);
throw;
}
try
{
- return new SoilProfile1D(profileId,
- properties.ProfileName,
+ return new SoilProfile1D(criticalProperties.ProfileId,
+ criticalProperties.ProfileName,
properties.Bottom,
soilLayers);
}
catch (ArgumentException exception)
{
+ MoveToNextProfile(criticalProperties.ProfileId);
throw new SoilProfileReadException(
Resources.SoilProfile1DReader_ReadSoilProfile_Failed_to_construct_profile_from_read_data,
- properties.ProfileName,
+ criticalProperties.ProfileName,
exception);
}
}
- private long ReadProfileId()
- {
- return dataReader.Read(SoilProfileTableDefinitions.SoilProfileId);
- }
-
private void PrepareReader()
{
string soilProfile1DQuery = SoilDatabaseQueryBuilder.GetSoilProfile1DQuery();
@@ -311,45 +310,31 @@
/// that are required to create a complete . If these properties
/// cannot be read, then the reader can proceed to the next profile.
///
- /// The to read the required profile property values from.
+ /// The to read the required
+ /// profile property values from.
+ /// The profile name used in generating exceptions messages
+ /// if casting failed.
/// Thrown when the values in the database could not be
/// casted to the expected column types.
- internal RequiredProfileProperties(IRowBasedDatabaseReader reader)
+ internal RequiredProfileProperties(IRowBasedDatabaseReader reader, string profileName)
{
- string readColumn = SoilProfileTableDefinitions.ProfileName;
try
{
- ProfileName = reader.Read(SoilProfileTableDefinitions.ProfileName);
-
- readColumn = SoilProfileTableDefinitions.Bottom;
- Bottom = reader.Read(readColumn);
-
- readColumn = SoilProfileTableDefinitions.LayerCount;
- LayerCount = reader.Read(readColumn);
+ Bottom = reader.Read(SoilProfileTableDefinitions.Bottom);
}
catch (InvalidCastException e)
{
string message = string.Format(Resources.SoilProfileReader_Profile_Name_0_has_invalid_value_on_Column_1,
- ProfileName,
- readColumn);
- throw new SoilProfileReadException(message, ProfileName, e);
+ profileName,
+ SoilProfileTableDefinitions.Bottom);
+ throw new SoilProfileReadException(message, profileName, e);
}
}
///
/// The bottom of the profile.
///
public double Bottom { get; }
-
- ///
- /// The name of the profile to read.
- ///
- public string ProfileName { get; }
-
- ///
- /// The number of layers that the profile has to read.
- ///
- public long LayerCount { get; }
}
}
}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Ringtoets.Common.IO.Test.csproj
===================================================================
diff -u -rf755184a931f4254129c6c3ccdd67d898562fc47 -re41a8cc75ec6e93aee52452aa50f47638a044feb
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Ringtoets.Common.IO.Test.csproj (.../Ringtoets.Common.IO.Test.csproj) (revision f755184a931f4254129c6c3ccdd67d898562fc47)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Ringtoets.Common.IO.Test.csproj (.../Ringtoets.Common.IO.Test.csproj) (revision e41a8cc75ec6e93aee52452aa50f47638a044feb)
@@ -110,6 +110,7 @@
+
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/SoilProfile/CriticalProfilePropertiesTest.cs
===================================================================
diff -u
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/SoilProfile/CriticalProfilePropertiesTest.cs (revision 0)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/SoilProfile/CriticalProfilePropertiesTest.cs (revision e41a8cc75ec6e93aee52452aa50f47638a044feb)
@@ -0,0 +1,127 @@
+// Copyright (C) Stichting Deltares 2017. All rights reserved.
+//
+// This file is part of Ringtoets.
+//
+// Ringtoets is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// All names, logos, and references to "Deltares" are registered trademarks of
+// Stichting Deltares and remain full property of Stichting Deltares at all times.
+// All rights reserved.
+
+using System;
+using Core.Common.Base.IO;
+using Core.Common.IO.Readers;
+using Core.Common.Utils.Builders;
+using NUnit.Framework;
+using Rhino.Mocks;
+using Ringtoets.Common.IO.SoilProfile;
+using Ringtoets.Common.IO.SoilProfile.Schema;
+
+namespace Ringtoets.Common.IO.Test.SoilProfile
+{
+ [TestFixture]
+ public class CriticalProfilePropertiesTest
+ {
+ private MockRepository mocks;
+
+ [SetUp]
+ public void SetUp()
+ {
+ mocks = new MockRepository();
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ mocks.VerifyAll();
+ }
+
+ [Test]
+ public void Constructor_WithReaderValuesValid_SetProperties()
+ {
+ // Setup
+ var reader = mocks.StrictMock();
+ const string profileName = "profile";
+ const int layerCount = 1;
+ const long soilProfileId = 1234;
+
+ reader.Expect(r => r.Read(SoilProfileTableDefinitions.ProfileName)).IgnoreArguments().Return(profileName);
+ reader.Expect(r => r.Read(SoilProfileTableDefinitions.LayerCount)).IgnoreArguments().Return(layerCount);
+ reader.Expect(r => r.Read(SoilProfileTableDefinitions.SoilProfileId)).IgnoreArguments().Return(soilProfileId);
+
+ mocks.ReplayAll();
+
+ // Call
+ var properties = new CriticalProfileProperties(reader);
+
+ // Assert
+ Assert.AreEqual(profileName, properties.ProfileName);
+ Assert.AreEqual(layerCount, properties.LayerCount);
+ Assert.AreEqual(soilProfileId, properties.ProfileId);
+ }
+
+ [Test]
+ public void Constructor_WithReaderInvalidProfileName_SetProperties()
+ {
+ // Setup
+ var reader = mocks.StrictMock();
+ const int layerCount = 1;
+ const string path = "A";
+ var invalidCastException = new InvalidCastException();
+
+ reader.Expect(r => r.Read(SoilProfileTableDefinitions.ProfileName)).IgnoreArguments().Throw(invalidCastException);
+ reader.Expect(r => r.Read(SoilProfileTableDefinitions.LayerCount)).IgnoreArguments().Return(layerCount).Repeat.Any();
+ reader.Expect(r => r.Path).Return(path);
+
+ mocks.ReplayAll();
+
+ // Call
+ TestDelegate test = () => new CriticalProfileProperties(reader);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreSame(invalidCastException, exception.InnerException);
+ string expectedMessage = new FileReaderErrorMessageBuilder(path)
+ .Build("Kritieke fout opgetreden bij het uitlezen van waardes uit kolommen in de database.");
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+
+ [Test]
+ public void Constructor_WithReaderInvalidLayerCount_SetProperties()
+ {
+ // Setup
+ var reader = mocks.StrictMock();
+ const string profileName = "profile";
+ const string path = "A";
+ var invalidCastException = new InvalidCastException();
+
+ reader.Expect(r => r.Read(SoilProfileTableDefinitions.ProfileName)).IgnoreArguments().Return(profileName).Repeat.Any();
+ reader.Expect(r => r.Read(SoilProfileTableDefinitions.LayerCount)).Throw(invalidCastException);
+ reader.Expect(r => r.Path).Return(path);
+
+ mocks.ReplayAll();
+
+ // Call
+ TestDelegate test = () => new CriticalProfileProperties(reader);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreSame(invalidCastException, exception.InnerException);
+ string expectedMessage = new FileReaderErrorMessageBuilder(path)
+ .WithSubject($"ondergrondschematisatie '{profileName}'")
+ .Build("Kritieke fout opgetreden bij het uitlezen van waardes uit kolommen in de database.");
+ Assert.AreEqual(expectedMessage, exception.Message);
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/SoilProfile/SoilProfile1DReaderTest.cs
===================================================================
diff -u -r80f04760977eeb1f2f2781ff9600ffa4d51b7060 -re41a8cc75ec6e93aee52452aa50f47638a044feb
--- Ringtoets/Common/test/Ringtoets.Common.IO.Test/SoilProfile/SoilProfile1DReaderTest.cs (.../SoilProfile1DReaderTest.cs) (revision 80f04760977eeb1f2f2781ff9600ffa4d51b7060)
+++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/SoilProfile/SoilProfile1DReaderTest.cs (.../SoilProfile1DReaderTest.cs) (revision e41a8cc75ec6e93aee52452aa50f47638a044feb)
@@ -165,9 +165,59 @@
// Assert
Assert.AreEqual(1, result.Count);
Assert.AreEqual("Profile", result[0].Name);
+
+ Assert.IsTrue(TestHelper.CanOpenFileForWrite(dbFile));
}
[Test]
+ public void ReadSoilProfile_LayerTopInvalidValue_ThrowsSoilProfileReadException()
+ {
+ // Setup
+ string dbFile = Path.Combine(testDataPath, "1dprofileWithInvalidTopLayer.soil");
+
+ using (var reader = new SoilProfile1DReader(dbFile))
+ {
+ reader.Initialize();
+
+ // Call
+ TestDelegate test = () => reader.ReadSoilProfile();
+
+ // Assert
+ var exception = Assert.Throws(test);
+ const string expectedMessage = "Het lezen van de ondergrondschematisatie 'INCORRECT' is mislukt. " +
+ "Geen geldige waarde in kolom 'Top'.";
+ Assert.AreEqual(expectedMessage, exception.Message);
+ Assert.AreEqual("INCORRECT", exception.ProfileName);
+ }
+
+ Assert.IsTrue(TestHelper.CanOpenFileForWrite(dbFile));
+ }
+
+ [Test]
+ public void ReadSoilProfile_BottomInvalidValue_ThrowsSoilProfileReadException()
+ {
+ // Setup
+ string dbFile = Path.Combine(testDataPath, "1dprofileWithInvalidBottom.soil");
+
+ using (var reader = new SoilProfile1DReader(dbFile))
+ {
+ reader.Initialize();
+
+ // Call
+ TestDelegate test = () => reader.ReadSoilProfile();
+
+ // Assert
+ var exception = Assert.Throws(test);
+ const string expectedMessage = "Het lezen van de ondergrondschematisatie 'Profile' is mislukt. " +
+ "Geen geldige waarde in kolom 'Bottom'.";
+ Assert.AreEqual(expectedMessage, exception.Message);
+ Assert.AreEqual("Profile", exception.ProfileName);
+ }
+
+ Assert.IsTrue(TestHelper.CanOpenFileForWrite(dbFile));
+ }
+
+ [Test]
public void ReadSoilProfile_BottomAboveLayers_ThrowsSoilProfileReadException()
{
// Setup
@@ -185,6 +235,8 @@
Assert.AreEqual("Het uitlezen van de ondergrondschematisatie is mislukt.", exception.Message);
Assert.AreEqual("Profile", exception.ProfileName);
}
+
+ Assert.IsTrue(TestHelper.CanOpenFileForWrite(dbFile));
}
[Test]
@@ -255,6 +307,8 @@
0.024752
}, profile.Layers.Select(l => l.PermeabilityCoefficientOfVariation));
}
+
+ Assert.IsTrue(TestHelper.CanOpenFileForWrite(dbFile));
}
}
}
\ No newline at end of file
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/SoilProfile1DReader/1dprofileWithInvalidBottom.soil
===================================================================
diff -u
Binary files differ
Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/test-data/SoilProfile1DReader/1dprofileWithInvalidTopLayer.soil
===================================================================
diff -u
Binary files differ