Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingSoilProfile.cs
===================================================================
diff -u -rf7d48349feba2a41391fac27dc3fef3028df091d -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingSoilProfile.cs (.../PipingSoilProfile.cs) (revision f7d48349feba2a41391fac27dc3fef3028df091d)
+++ Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingSoilProfile.cs (.../PipingSoilProfile.cs) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -20,6 +20,7 @@
/// The name of the profile.
/// The bottom level of the profile.
/// The collection of layers that should be part of the profile.
+ /// Thrown when is null or contains no layers.
public PipingSoilProfile(string name, double bottom, IEnumerable layers)
{
Name = name;
@@ -41,6 +42,7 @@
/// Gets an ordered (by , descending) of
/// for the .
///
+ /// Thrown when the value is null or contains no layers.
public IEnumerable Layers
{
get
Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/Segment2D.cs
===================================================================
diff -u -r602479eb3666493485aee246d56b08958a6fc958 -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/src/Ringtoets.Piping.Data/Segment2D.cs (.../Segment2D.cs) (revision 602479eb3666493485aee246d56b08958a6fc958)
+++ Ringtoets/Piping/src/Ringtoets.Piping.Data/Segment2D.cs (.../Segment2D.cs) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -14,6 +14,8 @@
///
/// The first of the .
/// The second of the .
+ /// Thrown when either the or
+ /// point is null.
public Segment2D(Point2D first, Point2D second)
{
if (first == null || second == null)
@@ -100,7 +102,7 @@
}
}
- protected bool Equals(Segment2D other)
+ private bool Equals(Segment2D other)
{
return FirstPoint.Equals(other.FirstPoint) && SecondPoint.Equals(other.SecondPoint) ||
FirstPoint.Equals(other.SecondPoint) && SecondPoint.Equals(other.FirstPoint);
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs
===================================================================
diff -u -r2a49b7243807fe0b95136efd55652201164a6c74 -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs (.../SoilLayer2D.cs) (revision 2a49b7243807fe0b95136efd55652201164a6c74)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilLayer2D.cs (.../SoilLayer2D.cs) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -50,7 +50,8 @@
/// Gets the outer loop of the as a of ,
/// for which each of the segments are connected to the next.
///
- /// Thrown when the does not form a loop.
+ /// Thrown when the in
+ /// do not form a loop.
public IEnumerable OuterLoop
{
get
@@ -81,7 +82,8 @@
/// Adds an inner loop to the geometry.
///
/// The innerloop to add.
- /// Thrown when the does not form a loop.
+ /// Thrown when the in
+ /// do not form a loop.
internal void AddInnerLoop(IEnumerable innerLoop)
{
var loop = innerLoop.ToArray();
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilProfileBuilder1D.cs
===================================================================
diff -u -r97c9e382dffcf32dc34d2e05e6a8a475b833ebd4 -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilProfileBuilder1D.cs (.../SoilProfileBuilder1D.cs) (revision 97c9e382dffcf32dc34d2e05e6a8a475b833ebd4)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilProfileBuilder1D.cs (.../SoilProfileBuilder1D.cs) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -1,4 +1,5 @@
-using System.Collections.ObjectModel;
+using System;
+using System.Collections.ObjectModel;
using Ringtoets.Piping.Data;
namespace Ringtoets.Piping.IO.Builders
@@ -23,6 +24,7 @@
/// Creates a new instances of the based on the layer definitions.
///
/// A new .
+ /// Thrown when no layers have been added through .
public PipingSoilProfile Build()
{
return new PipingSoilProfile(name, bottom, layers);
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/PipingSoilProfileReadException.cs
===================================================================
diff -u -ra950714ad9510756331d862aa35695fa0b2ed03b -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/PipingSoilProfileReadException.cs (.../PipingSoilProfileReadException.cs) (revision a950714ad9510756331d862aa35695fa0b2ed03b)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Exceptions/PipingSoilProfileReadException.cs (.../PipingSoilProfileReadException.cs) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -1,6 +1,6 @@
using System;
-
using Ringtoets.Piping.Data;
+using Ringtoets.Piping.IO.SoilProfile;
namespace Ringtoets.Piping.IO.Exceptions
{
@@ -12,27 +12,41 @@
///
/// Initializes a new instance of the class.
///
- public PipingSoilProfileReadException()
+ /// The name of the profile for which this exception was thrown.
+ public PipingSoilProfileReadException(string profileName)
{
+ ProfileName = profileName;
}
///
/// Initializes a new instance of the class
/// with a specified error message.
///
+ /// The name of the profile for which this exception was thrown.
/// The message that describes the error.
- public PipingSoilProfileReadException(string message)
+ public PipingSoilProfileReadException(string profileName, string message)
: base(message)
{
+ ProfileName = profileName;
}
///
/// Initializes a new instance of the class with a specified error message
/// and a reference to the inner exception that is the cause of this exception.
///
+ /// The name of the profile for which this exception was thrown.
/// The error message that explains the reason for the exception.
/// The exception that is the cause of the current exception, or a
/// null reference if no inner exception is specified.
- public PipingSoilProfileReadException(string message, Exception innerException) : base(message, innerException) { }
+ public PipingSoilProfileReadException(string profileName, string message, Exception innerException)
+ : base(message, innerException)
+ {
+ ProfileName = profileName;
+ }
+
+ ///
+ /// The name of the profile for which this exception was thrown.
+ ///
+ public string ProfileName { get; private set; }
}
}
\ No newline at end of file
Fisheye: Tag 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35 refers to a dead (removed) revision in file `Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSoilLayer2DReader.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Fisheye: Tag 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35 refers to a dead (removed) revision in file `Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSoilProfileReader.cs'.
Fisheye: No comparison available. Pass `N' to diff?
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs
===================================================================
diff -u -rf69d756f50ae1464a1a11f0780b6d6aa646f3114 -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision f69d756f50ae1464a1a11f0780b6d6aa646f3114)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -205,11 +205,11 @@
}
///
- /// Looks up a localized string similar to Database bevat een onverwachte waarde in kolom {0}..
+ /// Looks up a localized string similar to Kritieke fout opgetreden bij het uitlezen van waarden uit kolommen in de database..
///
- public static string PipingSoilProfileReader_Critical_Unexpected_value_on_column_0_ {
+ public static string PipingSoilProfileReader_Critical_Unexpected_value_on_column {
get {
- return ResourceManager.GetString("PipingSoilProfileReader_Critical_Unexpected_value_on_column_0_", resourceCulture);
+ return ResourceManager.GetString("PipingSoilProfileReader_Critical_Unexpected_value_on_column", resourceCulture);
}
}
@@ -285,5 +285,14 @@
return ResourceManager.GetString("SoilLayer2D_Error_Loop_contains_disconnected_segments", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to Het XML document dat de geometrie beschrijft voor de laag is niet valide..
+ ///
+ public static string SoilLayer2DReader_Geometry_contains_no_valid_xml {
+ get {
+ return ResourceManager.GetString("SoilLayer2DReader_Geometry_contains_no_valid_xml", resourceCulture);
+ }
+ }
}
}
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx
===================================================================
diff -u -rf69d756f50ae1464a1a11f0780b6d6aa646f3114 -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx (.../Resources.resx) (revision f69d756f50ae1464a1a11f0780b6d6aa646f3114)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx (.../Resources.resx) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -186,10 +186,13 @@
De segmenten van de geometrie van de laag vormen geen lus.
-
- Database bevat een onverwachte waarde in kolom {0}.
+
+ Kritieke fout opgetreden bij het uitlezen van waarden uit kolommen in de database.
Punten voor een lijn moeten uitelkaar liggen om een lijn te kunnen vormen.
+
+ Het XML document dat de geometrie beschrijft voor de laag is niet valide.
+
\ No newline at end of file
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Ringtoets.Piping.IO.csproj
===================================================================
diff -u -r2a49b7243807fe0b95136efd55652201164a6c74 -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/Ringtoets.Piping.IO.csproj (.../Ringtoets.Piping.IO.csproj) (revision 2a49b7243807fe0b95136efd55652201164a6c74)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Ringtoets.Piping.IO.csproj (.../Ringtoets.Piping.IO.csproj) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -52,15 +52,20 @@
-
-
+
+
+
+
+
+
True
True
Resources.resx
+
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/CriticalProfileProperties.cs
===================================================================
diff -u
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/CriticalProfileProperties.cs (revision 0)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/CriticalProfileProperties.cs (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -0,0 +1,33 @@
+using System;
+using Ringtoets.Piping.IO.Exceptions;
+using Ringtoets.Piping.IO.Properties;
+
+namespace Ringtoets.Piping.IO.SoilProfile
+{
+ internal class CriticalProfileProperties
+ {
+ internal readonly string ProfileName;
+ internal readonly long LayerCount;
+
+ ///
+ /// 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.
+ ///
+ ///
+ /// Thrown when the values in the database could not be
+ /// casted to the expected column types.
+ internal CriticalProfileProperties(IRowBasedReader reader)
+ {
+ try
+ {
+ ProfileName = reader.Read(SoilProfileDatabaseColumns.ProfileName);
+ LayerCount = reader.Read(SoilProfileDatabaseColumns.LayerCount);
+ }
+ catch (InvalidCastException e)
+ {
+ throw new CriticalFileReadException(Resources.PipingSoilProfileReader_Critical_Unexpected_value_on_column, e);
+ }
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/IRowBasedReader.cs
===================================================================
diff -u
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/IRowBasedReader.cs (revision 0)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/IRowBasedReader.cs (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -0,0 +1,32 @@
+using System;
+using Ringtoets.Piping.IO.Exceptions;
+
+namespace Ringtoets.Piping.IO.SoilProfile
+{
+ internal interface IRowBasedReader
+ {
+ ///
+ /// Moves the reader to the next record in the database.
+ ///
+ void MoveNext();
+
+ ///
+ /// Reads a value at column from the database.
+ ///
+ /// The expected type of value in the column with name .
+ /// The name of the column to read from.
+ /// The read value from the column with name .
+ /// Thrown when the value in the column was not of type .
+ T Read(string columnName);
+
+ ///
+ /// Reads the value in the column with name from the
+ /// current row that's being pointed at.
+ ///
+ /// The type of object to read.
+ /// The name of the column to read from.
+ /// The value in the column, or null if the value was .
+ /// Thrown when the value in the column could not be casted to type .
+ T? ReadOrNull(string columnName) where T : struct;
+ }
+}
\ No newline at end of file
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/PipingSoilProfileReader.cs
===================================================================
diff -u
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/PipingSoilProfileReader.cs (revision 0)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/PipingSoilProfileReader.cs (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -0,0 +1,393 @@
+using System;
+using System.Data;
+using System.Data.SQLite;
+using System.IO;
+using Ringtoets.Piping.Data;
+using Ringtoets.Piping.IO.Exceptions;
+using Ringtoets.Piping.IO.Properties;
+
+namespace Ringtoets.Piping.IO.SoilProfile
+{
+ ///
+ /// This class reads a SqLite database file and constructs instances from this database.
+ ///
+ public class PipingSoilProfileReader : IRowBasedReader, IDisposable
+ {
+ private const string databaseRequiredVersion = "15.0.5.0";
+ private const string pipingMechanismName = "Piping";
+ private const string mechanismParameterName = "mechanism";
+
+ private readonly string databaseFileName;
+
+ private SQLiteConnection connection;
+ private SQLiteDataReader dataReader;
+
+ ///
+ /// Creates a new instance of which will use the
+ /// as its source. The reader will not point to any record at the start. Use to start reading
+ /// profiles.
+ ///
+ /// The path of the database file to open.
+ /// Thrown when:
+ ///
+ /// - The contains invalid characters.
+ /// - No file could be found at .
+ /// - Preparing the queries to read from the database failed.
+ ///
+ ///
+ public PipingSoilProfileReader(string databaseFilePath)
+ {
+ try
+ {
+ FileUtils.ValidateFilePath(databaseFilePath);
+ }
+ catch (ArgumentException e)
+ {
+ throw new CriticalFileReadException(e.Message, e);
+ }
+ if (!File.Exists(databaseFilePath))
+ {
+ throw new CriticalFileReadException(string.Format(Resources.Error_File_0_does_not_exist, databaseFilePath));
+ }
+
+ databaseFileName = Path.GetFileName(databaseFilePath);
+ OpenConnection(databaseFilePath);
+ SetReaderToFirstRecord();
+ }
+
+ ///
+ /// Gets the total number of profiles that can be read from the database.
+ ///
+ public int Count { get; private set; }
+
+ ///
+ /// Gets the value true if profiles can be read using the .
+ /// false otherwise.
+ ///
+ public bool HasNext { get; private set; }
+
+ ///
+ /// Reads the information for the next profile from the database and creates a instance
+ /// of the information.
+ ///
+ /// The next from the database, or null if no more profiles can be read.
+ /// Thrown when reading the profile in the database contained a non-parsable geometry.
+ /// Thrown when the database returned incorrect values for required properties.
+ public PipingSoilProfile ReadProfile()
+ {
+ if (!HasNext)
+ {
+ return null;
+ }
+
+ try
+ {
+ return ReadPipingSoilProfile();
+ }
+ catch (InvalidCastException e)
+ {
+ throw new CriticalFileReadException(Resources.PipingSoilProfileReader_Critical_Unexpected_value_on_column, e);
+ }
+ }
+
+ ///
+ /// Reads a from the database.
+ ///
+ /// A new .
+ /// Thrown when a recoverable error occurred while reading from the database.
+ /// Thrown when recovering from the failed.
+ private PipingSoilProfile ReadPipingSoilProfile()
+ {
+ try
+ {
+ var dimensionValue = Read(SoilProfileDatabaseColumns.Dimension);
+ return dimensionValue == 1 ? SoilProfile1DReader.ReadFrom(this) : SoilProfile2DReader.ReadFrom(this);
+ }
+ catch (PipingSoilProfileReadException e)
+ {
+ MoveToNextProfile(e.ProfileName);
+ throw;
+ }
+ }
+
+ private void MoveToNextProfile(string profileName)
+ {
+ while (Read(SoilProfileDatabaseColumns.ProfileName).Equals(profileName))
+ {
+ MoveNext();
+ }
+ }
+
+ public void Dispose()
+ {
+ if (dataReader != null)
+ {
+ dataReader.Dispose();
+ }
+ connection.Close();
+ connection.Dispose();
+ }
+
+ ///
+ /// Moves the reader to the next record in the database.
+ ///
+ public void MoveNext()
+ {
+ HasNext = dataReader.Read() || (dataReader.NextResult() && dataReader.Read());
+ }
+
+ ///
+ /// Reads the value in the column with name from the
+ /// current row that's being pointed at.
+ ///
+ /// The type of object to read.
+ /// The name of the column to read from.
+ /// The value in the column, or null if the value was .
+ /// Thrown when the value in the column could not be casted to type .
+ public T? ReadOrNull(string columnName) where T : struct
+ {
+ var valueObject = dataReader[columnName];
+ if (valueObject.Equals(DBNull.Value))
+ {
+ return null;
+ }
+ return (T) valueObject;
+ }
+
+ ///
+ /// Reads a value at column from the database.
+ ///
+ /// The expected type of value in the column with name .
+ /// The name of the column to read from.
+ /// The read value from the column with name .
+ /// Thrown when the value in the column was not of type .
+ public T Read(string columnName)
+ {
+ return (T) dataReader[columnName];
+ }
+
+ private void SetReaderToFirstRecord()
+ {
+ InitializeDataReader();
+ MoveNext();
+ }
+
+ /// Thrown when opening the connection failed.
+ private void OpenConnection(string dbFile)
+ {
+ var connectionStringBuilder = new SQLiteConnectionStringBuilder
+ {
+ FailIfMissing = true,
+ DataSource = dbFile,
+ ReadOnly = true,
+ ForeignKeys = true
+ };
+
+ connection = new SQLiteConnection(connectionStringBuilder.ConnectionString);
+ connection.Open();
+ }
+
+ ///
+ /// Prepares the two queries required for obtaining all the SoilProfile1D and SoilProfile2D with an x defined
+ /// to take an intersection from. Since two separate queries are used, the will
+ /// have two result sets which the method takes into account.
+ ///
+ private void InitializeDataReader()
+ {
+ string versionQuery = string.Format(
+ "SELECT Value FROM _Metadata WHERE Key = 'VERSION' AND Value = '{0}';",
+ databaseRequiredVersion
+ );
+
+ string countQuery = string.Format(string.Join(
+ " ",
+ "SELECT",
+ "(SELECT COUNT(*)",
+ "FROM Mechanism as m",
+ "JOIN MechanismPointLocation as mpl ON mpl.ME_ID = m.ME_ID",
+ "JOIN SoilProfile2D as p2 ON p2.SP2D_ID = mpl.SP2D_ID",
+ "WHERE m.ME_Name = @{0})",
+ " + ",
+ "(SELECT COUNT(*)",
+ "FROM SoilProfile1D) as {1};"), mechanismParameterName, SoilProfileDatabaseColumns.ProfileCount);
+
+ string materialPropertiesQuery = string.Format(
+ string.Join(" ",
+ "(SELECT",
+ "m.MA_ID,",
+ "sum(case when pn.PN_Name = 'AbovePhreaticLevel' then pv.PV_Value end) {0},",
+ "sum(case when pn.PN_Name = 'BelowPhreaticLevel' then pv.PV_Value end) {1},",
+ "sum(case when pn.PN_Name = 'DryUnitWeight' then pv.PV_Value end) {2}",
+ "FROM ParameterNames as pn",
+ "JOIN ParameterValues as pv ON pn.PN_ID = pv.PN_ID",
+ "JOIN Materials as m ON m.MA_ID = pv.MA_ID",
+ "GROUP BY m.MA_ID) as mat ON l.MA_ID = mat.MA_ID"),
+ SoilProfileDatabaseColumns.AbovePhreaticLevel,
+ SoilProfileDatabaseColumns.BelowPhreaticLevel,
+ SoilProfileDatabaseColumns.DryUnitWeight);
+
+ string layer1DCountQuery = string.Format(
+ string.Join(" ",
+ "(SELECT SP1D_ID, COUNT(*) as {0}",
+ "FROM SoilLayer1D",
+ "GROUP BY SP1D_ID) lc ON lc.SP1D_ID = p.SP1D_ID"), SoilProfileDatabaseColumns.LayerCount);
+
+ string layer2DCountQuery = string.Format(
+ string.Join(" ",
+ "(SELECT SP2D_ID, COUNT(*) as {0}",
+ "FROM SoilLayer2D",
+ "GROUP BY SP2D_ID) lc ON lc.SP2D_ID = p.SP2D_ID"), SoilProfileDatabaseColumns.LayerCount);
+
+ string layer1DPropertiesQuery = string.Format(
+ string.Join(" ",
+ "(SELECT",
+ "pv.SL1D_ID,",
+ "sum(case when pn.PN_Name = 'IsAquifer' then pv.PV_Value end) {0}",
+ "FROM ParameterNames as pn",
+ "JOIN LayerParameterValues as pv ON pn.PN_ID = pv.PN_ID",
+ "GROUP BY pv.SL1D_ID) as lpv ON lpv.SL1D_ID = l.SL1D_ID"
+ ), SoilProfileDatabaseColumns.IsAquifer);
+
+ string layer2DPropertiesQuery = string.Format(
+ string.Join(" ",
+ "(SELECT",
+ "pv.SL2D_ID,",
+ "sum(case when pn.PN_Name = 'IsAquifer' then pv.PV_Value end) {0}",
+ "FROM ParameterNames as pn",
+ "JOIN LayerParameterValues as pv ON pn.PN_ID = pv.PN_ID",
+ "GROUP BY pv.SL2D_ID) as lpv ON lpv.SL2D_ID = l.SL2D_ID"
+ ), SoilProfileDatabaseColumns.IsAquifer);
+
+ var query1D = string.Format(
+ string.Join(" ", "SELECT",
+ "1 as {0},",
+ "p.SP1D_Name as {1},",
+ "lc.{2},",
+ "p.BottomLevel as {3},",
+ "l.TopLevel as {4},",
+ "{5},",
+ "{6},",
+ "{7},",
+ "{8}",
+ "FROM SoilProfile1D as p",
+ "JOIN {9}",
+ "JOIN SoilLayer1D as l ON l.SP1D_ID = p.SP1D_ID",
+ "LEFT JOIN {10}",
+ "LEFT JOIN {11}",
+ "ORDER BY ProfileName;"),
+ SoilProfileDatabaseColumns.Dimension,
+ SoilProfileDatabaseColumns.ProfileName,
+ SoilProfileDatabaseColumns.LayerCount,
+ SoilProfileDatabaseColumns.Bottom,
+ SoilProfileDatabaseColumns.Top,
+ SoilProfileDatabaseColumns.AbovePhreaticLevel,
+ SoilProfileDatabaseColumns.BelowPhreaticLevel,
+ SoilProfileDatabaseColumns.DryUnitWeight,
+ SoilProfileDatabaseColumns.IsAquifer,
+ layer1DCountQuery,
+ materialPropertiesQuery,
+ layer1DPropertiesQuery);
+
+ var query2D = string.Format(
+ string.Join(" ",
+ "SELECT",
+ "2 as {0},",
+ "p.SP2D_Name as {1},",
+ "lc.{2},",
+ "l.GeometrySurface as {3}, ",
+ "mpl.X as {4},",
+ "{5},",
+ "{6},",
+ "{7},",
+ "{8}",
+ "FROM Mechanism as m",
+ "JOIN MechanismPointLocation as mpl ON mpl.ME_ID = m.ME_ID",
+ "JOIN SoilProfile2D as p ON p.SP2D_ID = mpl.SP2D_ID",
+ "JOIN {9}",
+ "JOIN SoilLayer2D as l ON l.SP2D_ID = p.SP2D_ID",
+ "LEFT JOIN {10}",
+ "LEFT JOIN {11}",
+ "WHERE m.ME_Name = @{12}",
+ "ORDER BY ProfileName;"),
+ SoilProfileDatabaseColumns.Dimension,
+ SoilProfileDatabaseColumns.ProfileName,
+ SoilProfileDatabaseColumns.LayerCount,
+ SoilProfileDatabaseColumns.LayerGeometry,
+ SoilProfileDatabaseColumns.IntersectionX,
+ SoilProfileDatabaseColumns.AbovePhreaticLevel,
+ SoilProfileDatabaseColumns.BelowPhreaticLevel,
+ SoilProfileDatabaseColumns.DryUnitWeight,
+ SoilProfileDatabaseColumns.IsAquifer,
+ layer2DCountQuery,
+ materialPropertiesQuery,
+ layer2DPropertiesQuery,
+ mechanismParameterName);
+
+ CreateDataReader(versionQuery + countQuery + query2D + query1D, new SQLiteParameter
+ {
+ DbType = DbType.String,
+ Value = pipingMechanismName,
+ ParameterName = mechanismParameterName
+ });
+ }
+
+ ///
+ /// Creates a new data reader to use in this class.
+ ///
+ /// Thrown when
+ ///
+ /// - Version of the database doesn't match the required version.
+ /// - Version of the database could not be read.
+ /// - Amount of profiles in database could not be read.
+ /// - A query could not be executed on the database schema.
+ ///
+ ///
+ private void CreateDataReader(string queryString, params SQLiteParameter[] parameters)
+ {
+ using (var query = new SQLiteCommand(connection)
+ {
+ CommandText = queryString
+ })
+ {
+ query.Parameters.AddRange(parameters);
+
+ try
+ {
+ dataReader = query.ExecuteReader();
+ CheckVersion();
+ GetCount();
+ }
+ catch (SQLiteException e)
+ {
+ Dispose();
+ var exception = new CriticalFileReadException(string.Format(Resources.Error_SoilProfile_read_from_database, databaseFileName), e);
+ throw exception;
+ }
+ }
+ }
+
+ ///
+ /// Checks the version read from the metadata table against the .
+ ///
+ /// Thrown when versions don't match.
+ private void CheckVersion()
+ {
+ if (!dataReader.HasRows)
+ {
+ Dispose();
+ throw new CriticalFileReadException(string.Format(
+ Resources.PipingSoilProfileReader_Database_file_0_incorrect_version_requires_1,
+ databaseFileName,
+ databaseRequiredVersion));
+ }
+ dataReader.NextResult();
+ }
+
+ private void GetCount()
+ {
+ dataReader.Read();
+ Count = (int) Read(SoilProfileDatabaseColumns.ProfileCount);
+ dataReader.NextResult();
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilLayer2DReader.cs
===================================================================
diff -u
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilLayer2DReader.cs (revision 0)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilLayer2DReader.cs (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -0,0 +1,234 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Xml;
+using Ringtoets.Piping.Data;
+using Ringtoets.Piping.IO.Builders;
+using Ringtoets.Piping.IO.Properties;
+
+namespace Ringtoets.Piping.IO.SoilProfile
+{
+ ///
+ /// This class is responsible for reading an array of bytes and interpret this as a XML document, which contains information about
+ /// the geometry of a .
+ ///
+ internal class SoilLayer2DReader
+ {
+ private const string outerLoopElementName = "OuterLoop";
+ private const string innerLoopElementName = "InnerLoop";
+ private const string endPointElementName = "EndPoint";
+ private const string headPointElementName = "HeadPoint";
+ private const string geometryCurveElementName = "GeometryCurve";
+ private const string xElementName = "X";
+ private const string zElementName = "Z";
+
+ private readonly XmlTextReader xmlTextReader;
+
+ ///
+ /// Constructs a new , which uses the as the source of the
+ /// geometry for a .
+ ///
+ /// An array of which contains the information of a
+ /// in an XML document.
+ /// Thrown when is null.
+ internal SoilLayer2DReader(byte[] geometry)
+ {
+ try
+ {
+ xmlTextReader = new XmlTextReader(new MemoryStream(geometry));
+ }
+ catch (ArgumentNullException e)
+ {
+ throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml, e);
+ }
+ }
+
+ ///
+ /// Reads the XML document and from this obtains the required information and constructs a based
+ /// on this information.
+ ///
+ /// A new with information taken from the XML document.
+ /// Thrown when:
+ ///
+ /// - Reading from the XML document of the failed.
+ /// - The segments do not form a loop for either the inner or outer loop.
+ ///
+ ///
+ internal SoilLayer2D Read()
+ {
+ var pipingSoilLayer = new SoilLayer2D();
+
+ try
+ {
+ while (xmlTextReader.Read())
+ {
+ List outerLoop;
+ List innerLoop;
+ if (TryParseLoop(outerLoopElementName, out outerLoop))
+ {
+ pipingSoilLayer.OuterLoop = outerLoop;
+ }
+ if (TryParseLoop(innerLoopElementName, out innerLoop))
+ {
+ pipingSoilLayer.AddInnerLoop(innerLoop);
+ }
+ }
+ }
+ catch (XmlException e)
+ {
+ throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml, e);
+ }
+ catch (ArgumentException e)
+ {
+ throw new SoilLayer2DConversionException(e.Message, e);
+ }
+
+ return pipingSoilLayer;
+ }
+
+ ///
+ /// Tries to parse the element with the given , which the reader should be currently pointing at, as a loop.
+ ///
+ /// The name of the element which the reader should be currently pointing at.
+ /// The result of parsing the element as a loop. null if the current element's name does not match .
+ /// True if the reader currently points to an element with name . False otherwise.
+ /// Thrown when not both HeadPoint and EndPoint are defined in
+ /// the GeometryCurve XML element.
+ private bool TryParseLoop(string elementName, out List loop)
+ {
+ loop = null;
+
+ if (IsElementWithName(elementName))
+ {
+ loop = new List();
+
+ if (!IsEmptyElement())
+ {
+ while (xmlTextReader.Read() && !IsEndElementWithName(elementName))
+ {
+ Segment2D segment;
+ if (TryParseSegment(out segment))
+ {
+ loop.Add(segment);
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Tries to parse a GeometryCurve XML element to a .
+ ///
+ /// The segment reference in which to put the parsed .
+ /// true if a segment could be parsed. false otherwise.
+ /// Thrown when not both HeadPoint and EndPoint are defined in
+ /// the GeometryCurve XML element.
+ private bool TryParseSegment(out Segment2D segment)
+ {
+ segment = null;
+ if (IsElementWithName(geometryCurveElementName) || IsElementWithName(endPointElementName))
+ {
+ var points = new Point2D[2];
+ var index = 0;
+ while (xmlTextReader.Read() && !IsEndElementWithName(geometryCurveElementName))
+ {
+ Point2D point;
+ if (TryParsePoint(out point))
+ {
+ points[index] = point;
+ index++;
+ }
+ }
+ try
+ {
+ segment = new Segment2D(points[0], points[1]);
+ return true;
+ }
+ catch (ArgumentException e)
+ {
+ throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml, e);
+ }
+ }
+ return false;
+ }
+
+ ///
+ /// Finds out whether the element which the reader is currently pointing at is empty.
+ ///
+ /// True if the element is empty. False otherwise.
+ private bool IsEmptyElement()
+ {
+ return xmlTextReader.IsEmptyElement;
+ }
+
+ ///
+ /// Tries to parse the element which the reader is currently pointing at as a point.
+ ///
+ /// The result of parsing the element as a point. null if current element is not a head or end point.
+ /// True if the reader currently points to an element with name or . False otherwise.
+ private bool TryParsePoint(out Point2D point)
+ {
+ point = null;
+
+ if (IsElementWithName(headPointElementName) || IsElementWithName(endPointElementName))
+ {
+ var pointValues = ReadChildValues();
+ point = new Point2D
+ {
+ X = double.Parse(pointValues[xElementName], CultureInfo.InvariantCulture),
+ Y = double.Parse(pointValues[zElementName], CultureInfo.InvariantCulture)
+ };
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Reads the name and values for the children of the current element and puts them in a name indexed dictionary.
+ ///
+ /// A . For each entry, key is equal to child element name and value is equal to the value of the child element's text node.
+ private Dictionary ReadChildValues()
+ {
+ string elementName = xmlTextReader.Name;
+ var nodeSibblings = new Dictionary();
+
+ while (xmlTextReader.Read() && !IsEndElementWithName(elementName))
+ {
+ if (xmlTextReader.NodeType == XmlNodeType.Element)
+ {
+ nodeSibblings[xmlTextReader.Name] = xmlTextReader.ReadString();
+ }
+ }
+
+ return nodeSibblings;
+ }
+
+ ///
+ /// Checks whether the element the reader is currently pointing at is of type and has a name equal to .
+ ///
+ /// The name which the element should have.
+ /// True if the current element has type and its name is equal to .
+ private bool IsElementWithName(string name)
+ {
+ var isElement = xmlTextReader.NodeType == XmlNodeType.Element;
+ var isPoint = xmlTextReader.Name == name;
+
+ return isElement && isPoint;
+ }
+ ///
+ /// Checks whether the element the reader is currently pointing at is of type and has a name equal to .
+ ///
+ /// The name which the end element should have.
+ /// True if the current element has type and its name is equal to .
+ private bool IsEndElementWithName(string name)
+ {
+ var isElement = xmlTextReader.NodeType == XmlNodeType.EndElement;
+ var isPoint = xmlTextReader.Name == name;
+
+ return isElement && isPoint;
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfile1DReader.cs
===================================================================
diff -u
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfile1DReader.cs (revision 0)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfile1DReader.cs (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -0,0 +1,142 @@
+using System;
+using System.Data.SQLite;
+using Ringtoets.Piping.Data;
+using Ringtoets.Piping.IO.Builders;
+using Ringtoets.Piping.IO.Exceptions;
+using Ringtoets.Piping.IO.Properties;
+
+namespace Ringtoets.Piping.IO.SoilProfile
+{
+ internal static class SoilProfile1DReader
+ {
+ ///
+ /// Reads a 1D profile from the given .
+ ///
+ ///
+ ///
+ /// Thrown when reading the profile encountered an unrecoverable error.
+ /// Thrown when reading the profile encountered a recoverable error.
+ internal static PipingSoilProfile ReadFrom(IRowBasedReader reader)
+ {
+ var criticalProperties = new CriticalProfileProperties(reader);
+ var requiredProperties = new RequiredProfileProperties(reader, criticalProperties.ProfileName);
+
+ var soilProfileBuilder = new SoilProfileBuilder1D(criticalProperties.ProfileName, requiredProperties.Bottom);
+
+ for (var i = 1; i <= criticalProperties.LayerCount; i++)
+ {
+ SoilLayer1D soilLayer = ReadSoilLayerFrom(reader, criticalProperties.ProfileName);
+ soilProfileBuilder.Add(soilLayer.AsPipingSoilLayer());
+ reader.MoveNext();
+ }
+
+ return Build(soilProfileBuilder, criticalProperties.ProfileName);
+ }
+
+ ///
+ /// Builds a from the given .
+ ///
+ /// Thrown when building the failed.
+ private static PipingSoilProfile Build(SoilProfileBuilder1D soilProfileBuilder, string profileName)
+ {
+ try
+ {
+ return soilProfileBuilder.Build();
+ }
+ catch (ArgumentException e)
+ {
+ throw new PipingSoilProfileReadException(profileName, e.Message, e);
+ }
+ }
+
+ ///
+ /// Reads a from the given .
+ ///
+ /// Thrown when reading properties of the layers failed.
+ private static SoilLayer1D ReadSoilLayerFrom(IRowBasedReader reader, string profileName)
+ {
+ var properties = new LayerProperties(reader, profileName);
+
+ var pipingSoilLayer = new SoilLayer1D(properties.Top)
+ {
+ IsAquifer = properties.IsAquifer,
+ BelowPhreaticLevel = properties.BelowPhreaticLevel,
+ AbovePhreaticLevel = properties.AbovePhreaticLevel,
+ DryUnitWeight = properties.DryUnitWeight
+ };
+ return pipingSoilLayer;
+ }
+
+ private class RequiredProfileProperties
+ {
+ internal readonly double Bottom;
+
+ ///
+ /// Creates a new instance of , which contains properties
+ /// 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 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(IRowBasedReader reader, string profileName)
+ {
+ string readColumn = SoilProfileDatabaseColumns.Bottom;
+ try
+ {
+ Bottom = reader.Read(readColumn);
+ }
+ catch (InvalidCastException e)
+ {
+ var message = string.Format(Resources.PipingSoilProfileReader_Profile_0_has_invalid_value_on_column_1_, profileName, readColumn);
+ throw new PipingSoilProfileReadException(profileName, message, e);
+ }
+ }
+ }
+
+ private class LayerProperties
+ {
+ internal readonly double Top;
+ internal readonly double? IsAquifer;
+ internal readonly double? BelowPhreaticLevel;
+ internal readonly double? AbovePhreaticLevel;
+ internal readonly double? DryUnitWeight;
+
+ ///
+ /// Creates a new instance of , which contains properties
+ /// 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 layer 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 LayerProperties(IRowBasedReader reader, string profileName)
+ {
+ string readColumn = SoilProfileDatabaseColumns.Top;
+ try
+ {
+ Top = reader.Read(readColumn);
+
+ readColumn = SoilProfileDatabaseColumns.IsAquifer;
+ IsAquifer = reader.ReadOrNull(readColumn);
+
+ readColumn = SoilProfileDatabaseColumns.BelowPhreaticLevel;
+ BelowPhreaticLevel = reader.ReadOrNull(readColumn);
+
+ readColumn = SoilProfileDatabaseColumns.AbovePhreaticLevel;
+ AbovePhreaticLevel = reader.ReadOrNull(readColumn);
+
+ readColumn = SoilProfileDatabaseColumns.DryUnitWeight;
+ DryUnitWeight = reader.ReadOrNull(readColumn);
+ }
+ catch (InvalidCastException e)
+ {
+ var message = string.Format(Resources.PipingSoilProfileReader_Profile_0_has_invalid_value_on_column_1_, profileName, readColumn);
+ throw new PipingSoilProfileReadException(profileName, message, e);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfile2DReader.cs
===================================================================
diff -u
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfile2DReader.cs (revision 0)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfile2DReader.cs (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -0,0 +1,182 @@
+using System;
+using System.Data.SQLite;
+using Ringtoets.Piping.Data;
+using Ringtoets.Piping.IO.Builders;
+using Ringtoets.Piping.IO.Exceptions;
+using Ringtoets.Piping.IO.Properties;
+
+namespace Ringtoets.Piping.IO.SoilProfile
+{
+ internal static class SoilProfile2DReader
+ {
+
+ ///
+ /// Reads information for a profile from the database and creates a based on the information.
+ ///
+ /// A new with information from the database.
+ /// Thrown when reading the profile encountered an unrecoverable error.
+ /// Thrown when
+ ///
+ /// - a layer's geometry could not be parsed as XML;
+ /// - the parsed geometry did not contain loops;
+ /// - after reading the layers, no layers were added to be build;
+ /// - unexpected values were encountered for layer properties
+ ///
+ ///
+ internal static PipingSoilProfile ReadFrom(IRowBasedReader reader)
+ {
+ var criticalProperties = new CriticalProfileProperties(reader);
+ var requiredProperties = new RequiredProfileProperties(reader, criticalProperties.ProfileName);
+
+ try
+ {
+ var soilProfileBuilder = new SoilProfileBuilder2D(criticalProperties.ProfileName, requiredProperties.IntersectionX);
+
+ for (int i = 1; i <= criticalProperties.LayerCount; i++)
+ {
+ var pipingSoilLayer2D = ReadPiping2DSoilLayer(reader, criticalProperties.ProfileName);
+ soilProfileBuilder.Add(pipingSoilLayer2D);
+ reader.MoveNext();
+ }
+
+ return soilProfileBuilder.Build();
+ }
+ catch (SoilProfileBuilderException e)
+ {
+ throw new PipingSoilProfileReadException(criticalProperties.ProfileName, e.Message, e);
+ }
+ catch (ArgumentException e)
+ {
+ throw new PipingSoilProfileReadException(criticalProperties.ProfileName, e.Message, e);
+ }
+ }
+
+ ///
+ /// Reads a soil layer from a 2d profile in the database.
+ ///
+ /// The to read the layer property values from.
+ /// The profile name used in generating exceptions messages if casting failed.
+ /// A new instance, based on the information read from the database.
+ /// Thrown when:
+ ///
+ /// - A column for a layer property did not contain a value of the expected type.
+ /// - Thrown when the read geometry does not contain segments that form form a loop for either the inner or outer loop.
+ ///
+ private static SoilLayer2D ReadPiping2DSoilLayer(IRowBasedReader reader, string profileName)
+ {
+ LayerProperties properties = new LayerProperties(reader, profileName);
+
+ SoilLayer2D pipingSoilLayer;
+ try
+ {
+ var geometryValue = ReadGeometryFrom(reader, profileName);
+ pipingSoilLayer = new SoilLayer2DReader(geometryValue).Read();
+ }
+ catch (SoilLayer2DConversionException e)
+ {
+ throw new PipingSoilProfileReadException(profileName, e.Message, e);
+ }
+
+ if (pipingSoilLayer != null)
+ {
+ pipingSoilLayer.IsAquifer = properties.IsAquifer;
+ pipingSoilLayer.BelowPhreaticLevel = properties.BelowPhreaticLevel;
+ pipingSoilLayer.AbovePhreaticLevel = properties.AbovePhreaticLevel;
+ pipingSoilLayer.DryUnitWeight = properties.DryUnitWeight;
+ }
+ return pipingSoilLayer;
+ }
+
+ ///
+ /// Reads the geometry for a layer from the current
+ ///
+ /// The to read the geometry value from.
+ /// The profile name used in generating exceptions messages if casting failed.
+ ///
+ private static byte[] ReadGeometryFrom(IRowBasedReader reader, string profileName)
+ {
+ try
+ {
+ return reader.Read(SoilProfileDatabaseColumns.LayerGeometry);
+ }
+ catch (InvalidCastException e)
+ {
+ var message = string.Format(
+ Resources.PipingSoilProfileReader_Profile_0_has_invalid_value_on_column_1_,
+ profileName,
+ SoilProfileDatabaseColumns.LayerGeometry
+ );
+ throw new PipingSoilProfileReadException(profileName, message, e);
+ }
+ }
+
+
+ private class RequiredProfileProperties
+ {
+ internal readonly double IntersectionX;
+
+ ///
+ /// Creates a new instance of , which contains properties
+ /// 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 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(IRowBasedReader reader, string profileName)
+ {
+ string readColumn = SoilProfileDatabaseColumns.IntersectionX;
+ try
+ {
+ IntersectionX = reader.Read(readColumn);
+ }
+ catch (InvalidCastException e)
+ {
+ var message = string.Format(Resources.PipingSoilProfileReader_Profile_0_has_invalid_value_on_column_1_, profileName, readColumn);
+ throw new PipingSoilProfileReadException(profileName, message, e);
+ }
+ }
+ }
+
+ private class LayerProperties
+ {
+ internal readonly double? IsAquifer;
+ internal readonly double? BelowPhreaticLevel;
+ internal readonly double? AbovePhreaticLevel;
+ internal readonly double? DryUnitWeight;
+
+ ///
+ /// Creates a new instance of , which contains properties
+ /// 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 layer 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 LayerProperties(IRowBasedReader reader, string profileName)
+ {
+ string readColumn = SoilProfileDatabaseColumns.IsAquifer;
+ try
+ {
+ IsAquifer = reader.ReadOrNull(readColumn);
+
+ readColumn = SoilProfileDatabaseColumns.BelowPhreaticLevel;
+ BelowPhreaticLevel = reader.ReadOrNull(readColumn);
+
+ readColumn = SoilProfileDatabaseColumns.AbovePhreaticLevel;
+ AbovePhreaticLevel = reader.ReadOrNull(readColumn);
+
+ readColumn = SoilProfileDatabaseColumns.DryUnitWeight;
+ DryUnitWeight = reader.ReadOrNull(readColumn);
+ }
+ catch (InvalidCastException e)
+ {
+ var message = string.Format(Resources.PipingSoilProfileReader_Profile_0_has_invalid_value_on_column_1_, profileName, readColumn);
+ throw new PipingSoilProfileReadException(profileName, message, e);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfileDatabaseColumns.cs
===================================================================
diff -u
--- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfileDatabaseColumns.cs (revision 0)
+++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfileDatabaseColumns.cs (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -0,0 +1,18 @@
+namespace Ringtoets.Piping.IO.SoilProfile
+{
+ public static class SoilProfileDatabaseColumns
+ {
+ public const string ProfileCount = "ProfileCount";
+ public const string Dimension = "Dimension";
+ public const string IsAquifer = "IsAquifer";
+ public const string ProfileName = "ProfileName";
+ public const string IntersectionX = "IntersectionX";
+ public const string Bottom = "Bottom";
+ public const string Top = "Top";
+ public const string LayerGeometry = "LayerGeometry";
+ public const string AbovePhreaticLevel = "AbovePhreaticLevel";
+ public const string BelowPhreaticLevel = "BelowPhreaticLevel";
+ public const string DryUnitWeight = "DryUnitWeight";
+ public const string LayerCount = "LayerCount";
+ }
+}
\ No newline at end of file
Index: Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/PipingSoilProfilesImporter.cs
===================================================================
diff -u -rf69d756f50ae1464a1a11f0780b6d6aa646f3114 -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/PipingSoilProfilesImporter.cs (.../PipingSoilProfilesImporter.cs) (revision f69d756f50ae1464a1a11f0780b6d6aa646f3114)
+++ Ringtoets/Piping/src/Ringtoets.Piping.Plugin/FileImporter/PipingSoilProfilesImporter.cs (.../PipingSoilProfilesImporter.cs) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -6,8 +6,8 @@
using Core.Common.Base;
using log4net;
using Ringtoets.Piping.Data;
-using Ringtoets.Piping.IO;
using Ringtoets.Piping.IO.Exceptions;
+using Ringtoets.Piping.IO.SoilProfile;
using WtiFormsResources = Ringtoets.Piping.Forms.Properties.Resources;
using ApplicationResources = Ringtoets.Piping.Plugin.Properties.Resources;
@@ -119,18 +119,10 @@
return GetProfileReadResult(path, soilProfileReader);
}
}
- catch (PipingSoilProfileReadException e)
+ catch (CriticalFileReadException e)
{
HandleException(path, e);
}
- catch (FileNotFoundException e)
- {
- HandleException(path, e);
- }
- catch (ArgumentException e)
- {
- HandleException(path, e);
- }
return new PipingReadResult(true);
}
Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/PipingSoilProfileReadExceptionTest.cs
===================================================================
diff -u -ra950714ad9510756331d862aa35695fa0b2ed03b -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/PipingSoilProfileReadExceptionTest.cs (.../PipingSoilProfileReadExceptionTest.cs) (revision a950714ad9510756331d862aa35695fa0b2ed03b)
+++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Exceptions/PipingSoilProfileReadExceptionTest.cs (.../PipingSoilProfileReadExceptionTest.cs) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -7,45 +7,51 @@
public class PipingSoilProfileReadExceptionTest
{
[Test]
- public void DefaultConstructor_InnerExceptionNullAndMessageDefault()
+ public void Constructor_WithProfileName_InnerExceptionNullMessageDefaultAndProfileNameSet()
{
// Setup
+ var profileName = "name";
var expectedMessage = String.Format("Exception of type '{0}' was thrown.", typeof(PipingSoilProfileReadException).FullName);
// Call
- var exception = new PipingSoilProfileReadException();
+ var exception = new PipingSoilProfileReadException(profileName);
// Assert
Assert.IsNull(exception.InnerException);
+ Assert.AreEqual(profileName, exception.ProfileName);
Assert.AreEqual(expectedMessage, exception.Message);
}
[Test]
public void Constructor_WithCustomMessage_InnerExceptionNullAndMessageSetToCustom()
{
// Setup
- var expectedMessage ="Some exception message";
+ var profileName = "name";
+ var expectedMessage = "Some exception message";
// Call
- var exception = new PipingSoilProfileReadException(expectedMessage);
+ var exception = new PipingSoilProfileReadException(profileName, expectedMessage);
// Assert
Assert.IsNull(exception.InnerException);
+ Assert.AreEqual(profileName, exception.ProfileName);
Assert.AreEqual(expectedMessage, exception.Message);
}
[Test]
public void Constructor_WithCustomMessageAndInnerException_InnerExceptionSetAndMessageSetToCustom()
{
// Setup
+ var profileName = "name";
var expectedMessage = "Some exception message";
var expectedInnerException = new Exception();
// Call
- var exception = new PipingSoilProfileReadException(expectedMessage, expectedInnerException);
+ var exception = new PipingSoilProfileReadException(profileName, expectedMessage, expectedInnerException);
// Assert
Assert.AreSame(expectedInnerException, exception.InnerException);
+ Assert.AreEqual(profileName, exception.ProfileName);
Assert.AreEqual(expectedMessage, exception.Message);
}
}
Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilLayer2DReaderTest.cs
===================================================================
diff -u -rf69d756f50ae1464a1a11f0780b6d6aa646f3114 -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilLayer2DReaderTest.cs (.../PipingSoilLayer2DReaderTest.cs) (revision f69d756f50ae1464a1a11f0780b6d6aa646f3114)
+++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilLayer2DReaderTest.cs (.../PipingSoilLayer2DReaderTest.cs) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -7,6 +7,8 @@
using NUnit.Framework;
using Ringtoets.Piping.Data;
+using Ringtoets.Piping.IO.Builders;
+using Ringtoets.Piping.IO.SoilProfile;
namespace Ringtoets.Piping.IO.Test
{
@@ -18,32 +20,32 @@
public void Constructor_AnyByteArray_ReturnsNewInstance(int size)
{
// Call
- var result = new PipingSoilLayer2DReader(new byte[size]);
+ var result = new SoilLayer2DReader(new byte[size]);
// Assert
Assert.NotNull(result);
}
[Test]
- public void Read_MalformedXmlDocument_ThrowsXmlException()
+ public void Read_MalformedXmlDocument_ThrowsSoilLayer2DConversionException()
{
// Setup
var xmlDoc = GetBytes("test");
- var reader = new PipingSoilLayer2DReader(xmlDoc);
+ var reader = new SoilLayer2DReader(xmlDoc);
// Call
TestDelegate test = () => reader.Read();
// Assert
- Assert.Throws(test);
+ Assert.Throws(test);
}
[Test]
public void Read_XmlDocumentWithoutSaneContent_ReturnsLayerWithoutOuterLoopAndEmptyInnerLoops()
{
// Setup
var xmlDoc = GetBytes("");
- var reader = new PipingSoilLayer2DReader(xmlDoc);
+ var reader = new SoilLayer2DReader(xmlDoc);
// Call
var result = reader.Read();
@@ -59,7 +61,7 @@
{
// Setup
var xmlDoc = GetBytes("");
- var reader = new PipingSoilLayer2DReader(xmlDoc);
+ var reader = new SoilLayer2DReader(xmlDoc);
// Call
var result = reader.Read();
@@ -75,7 +77,7 @@
{
// Setup
var xmlDoc = GetBytes("");
- var reader = new PipingSoilLayer2DReader(xmlDoc);
+ var reader = new SoilLayer2DReader(xmlDoc);
// Call
var result = reader.Read();
@@ -92,7 +94,7 @@
{
// Setup
var xmlDoc = GetBytes("");
- var reader = new PipingSoilLayer2DReader(xmlDoc);
+ var reader = new SoilLayer2DReader(xmlDoc);
// Call
var result = reader.Read();
@@ -147,7 +149,7 @@
x1String, y1String, x2String, y2String);
var bytes = GetBytes(sometempvarforbassie);
var xmlDoc = bytes;
- var reader = new PipingSoilLayer2DReader(xmlDoc);
+ var reader = new SoilLayer2DReader(xmlDoc);
// Call
var result = reader.Read();
@@ -185,7 +187,7 @@
"{0}0.1{1}" +
"{2}0.1{3}" +
"", x1String, y1String, x2String, y2String));
- var reader = new PipingSoilLayer2DReader(xmlDoc);
+ var reader = new SoilLayer2DReader(xmlDoc);
// Call
var result = reader.Read();
@@ -198,31 +200,31 @@
}
[Test]
- public void Read_XmlDocumentSinglePointOuterLoopGeometryCurve_ThrowsXmlException()
+ public void Read_XmlDocumentSinglePointOuterLoopGeometryCurve_ThrowsSoilLayer2DConversionException()
{
// Setup
var xmlDoc = GetBytes("10.11.1");
- var reader = new PipingSoilLayer2DReader(xmlDoc);
+ var reader = new SoilLayer2DReader(xmlDoc);
// Call
TestDelegate test = () => { reader.Read(); };
// Assert
- Assert.Throws(test);
+ Assert.Throws(test);
}
[Test]
- public void Read_XmlDocumentSinglePointInnerLoopGeometryCurve_ThrowsXmlException()
+ public void Read_XmlDocumentSinglePointInnerLoopGeometryCurve_ThrowsSoilLayer2DConversionException()
{
// Setup
var xmlDoc = GetBytes("00.11.1");
- var reader = new PipingSoilLayer2DReader(xmlDoc);
+ var reader = new SoilLayer2DReader(xmlDoc);
// Call
TestDelegate test = () => { reader.Read(); };
// Assert
- Assert.Throws(test);
+ Assert.Throws(test);
}
[Test]
@@ -238,7 +240,7 @@
"" +
"");
- var reader = new PipingSoilLayer2DReader(xmlDoc);
+ var reader = new SoilLayer2DReader(xmlDoc);
// Call
var result = reader.Read();
Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilProfileReaderTest.cs
===================================================================
diff -u -r2a49b7243807fe0b95136efd55652201164a6c74 -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilProfileReaderTest.cs (.../PipingSoilProfileReaderTest.cs) (revision 2a49b7243807fe0b95136efd55652201164a6c74)
+++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingSoilProfileReaderTest.cs (.../PipingSoilProfileReaderTest.cs) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -8,6 +8,7 @@
using Ringtoets.Piping.Data;
using Ringtoets.Piping.IO.Exceptions;
using Ringtoets.Piping.IO.Properties;
+using Ringtoets.Piping.IO.SoilProfile;
using Ringtoets.Piping.IO.Test.TestHelpers;
namespace Ringtoets.Piping.IO.Test
@@ -17,7 +18,7 @@
private readonly string testDataPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Piping.IO, "PipingSoilProfilesReader");
[Test]
- public void Constructor_NonExistingPath_ThrowsFileNotFoundException()
+ public void Constructor_NonExistingPath_ThrowsCriticalFileReadException()
{
// Setup
var testFile = Path.Combine(testDataPath, "none.soil");
@@ -26,27 +27,27 @@
TestDelegate test = () => new PipingSoilProfileReader(testFile).Dispose();
// Assert
- var exception = Assert.Throws(test);
+ var exception = Assert.Throws(test);
Assert.AreEqual(String.Format(Resources.Error_File_0_does_not_exist, testFile), exception.Message);
}
[Test]
[TestCase(null)]
[TestCase("")]
- public void Constructor_FileNullOrEmpty_ThrowsArgumentException(string fileName)
+ public void Constructor_FileNullOrEmpty_ThrowsCriticalFileReadException(string fileName)
{
// Call
TestDelegate test = () => new PipingSoilProfileReader(fileName).Dispose();
// Assert
- var exception = Assert.Throws(test);
+ var exception = Assert.Throws(test);
Assert.AreEqual(Resources.Error_Path_must_be_specified, exception.Message);
}
[Test]
[TestCase("text.txt")]
[TestCase("empty.soil")]
- public void Constructor_IncorrectFormatFileOrInvalidSchema_ThrowsPipingSoilProfileReadException(string dbName)
+ public void Constructor_IncorrectFormatFileOrInvalidSchema_ThrowsPipingCriticalFileReadException(string dbName)
{
// Setup
var dbFile = Path.Combine(testDataPath, dbName);
@@ -58,13 +59,13 @@
TestDelegate test = () => new PipingSoilProfileReader(dbFile).Dispose();
// Assert
- var exception = Assert.Throws(test);
+ var exception = Assert.Throws(test);
Assert.AreEqual(String.Format(Resources.Error_SoilProfile_read_from_database, dbName), exception.Message);
Assert.IsTrue(FileHelper.CanOpenFileForWrite(dbFile));
}
[Test]
- public void Constructor_IncorrectVersion_ThrowsPipingSoilProfileReadException()
+ public void Constructor_IncorrectVersion_ThrowsCriticalFileReadException()
{
// Setup
var version = "15.0.5.0";
@@ -78,7 +79,7 @@
TestDelegate test = () => new PipingSoilProfileReader(dbFile).Dispose();
// Assert
- var exception = Assert.Throws(test);
+ var exception = Assert.Throws(test);
Assert.AreEqual(String.Format(Resources.PipingSoilProfileReader_Database_file_0_incorrect_version_requires_1, dbName, version), exception.Message);
Assert.IsTrue(FileHelper.CanOpenFileForWrite(dbFile));
}
@@ -137,8 +138,7 @@
// Assert
var exception = Assert.Throws(profile);
- var message = String.Format(Resources.PipingSoilProfileReader_CouldNotParseGeometryOfLayer_0_InProfile_1_, 1, "Profile");
- Assert.AreEqual(message, exception.Message);
+ Assert.AreEqual(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml, exception.Message);
// Call
var pipingSoilProfile = pipingSoilProfilesReader.ReadProfile();
@@ -163,7 +163,7 @@
// Assert
var exception = Assert.Throws(profile);
- var message = String.Format(Resources.PipingSoilProfileReader_CouldNotParseGeometryOfLayer_0_InProfile_1_, 1, "Profile");
+ var message = String.Format(Resources.Error_Can_not_determine_1D_profile_with_vertical_segments_at_x, 85.2);
Assert.AreEqual(message, exception.Message);
// Call
Index: Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/PipingSoilProfilesImporterTest.cs
===================================================================
diff -u -rf69d756f50ae1464a1a11f0780b6d6aa646f3114 -r069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35
--- Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/PipingSoilProfilesImporterTest.cs (.../PipingSoilProfilesImporterTest.cs) (revision f69d756f50ae1464a1a11f0780b6d6aa646f3114)
+++ Ringtoets/Piping/test/Ringtoets.Piping.Plugin.Test/FileImporter/PipingSoilProfilesImporterTest.cs (.../PipingSoilProfilesImporterTest.cs) (revision 069921ae1e06e13d8e5e19dd9caa5e8f7b9e1f35)
@@ -137,7 +137,7 @@
{
// Setup
var file = "/";
- string validFilePath = Path.Combine(testDataPath, file);
+ string invalidFilePath = Path.Combine(testDataPath, file);
var mocks = new MockRepository();
var observer = mocks.StrictMock();
@@ -158,13 +158,13 @@
object importedItem = null;
// Call
- Action call = () => importedItem = importer.ImportItem(validFilePath, observableList);
+ Action call = () => importedItem = importer.ImportItem(invalidFilePath, observableList);
// Assert
TestHelper.AssertLogMessages(call, messages =>
{
string[] messageArray = messages.ToArray();
- var message = string.Format(ApplicationResources.PipingSoilProfilesImporter_Critical_error_reading_File_0_Cause_1_, validFilePath, String.Empty);
+ var message = string.Format(ApplicationResources.PipingSoilProfilesImporter_Critical_error_reading_File_0_Cause_1_, invalidFilePath, String.Empty);
StringAssert.StartsWith(message, messageArray[0]);
});
Assert.AreSame(observableList, importedItem);