Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilDatabaseQueryBuilder.cs =================================================================== diff -u -r86e6bb44ba1ccbec534f3fcf379481ea8d45d67f -r64c21c2c91a3cef9df279e58efda8e45a9d598f7 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilDatabaseQueryBuilder.cs (.../SoilDatabaseQueryBuilder.cs) (revision 86e6bb44ba1ccbec534f3fcf379481ea8d45d67f) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Builders/SoilDatabaseQueryBuilder.cs (.../SoilDatabaseQueryBuilder.cs) (revision 64c21c2c91a3cef9df279e58efda8e45a9d598f7) @@ -68,16 +68,21 @@ /// from the database. public static string GetStochasticSoilModelOfMechanismCountQuery() { - return String.Format(@"SELECT COUNT('1') AS {6} " + - "FROM {0} M " + - "INNER JOIN {1} S USING({3}) " + - "INNER JOIN {2} SSM USING({4}) " + - "WHERE M.{5} = @{5};", + return String.Format(@"SELECT COUNT('1') AS {8} " + + "FROM (" + + "SELECT '1' FROM {0} M " + + "INNER JOIN {1} S USING({4}) " + + "INNER JOIN {2} SSM USING({5}) " + + "INNER JOIN {3} SP USING({6}) " + + "WHERE M.{7} = @{7} GROUP BY {5}" + + ");", MechanismDatabaseColumns.TableName, SegmentDatabaseColumns.TableName, StochasticSoilModelDatabaseColumns.TableName, + SegmentPointsDatabaseColumns.TableName, MechanismDatabaseColumns.MechanismId, StochasticSoilModelDatabaseColumns.StochasticSoilModelId, + SegmentPointsDatabaseColumns.SegmentId, MechanismDatabaseColumns.MechanismName, StochasticSoilModelDatabaseColumns.Count ); Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/StochasticSoilModelReader.cs =================================================================== diff -u -rd82fa09fe9ae053ce7702ba89ef23ae029640d1b -r64c21c2c91a3cef9df279e58efda8e45a9d598f7 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/StochasticSoilModelReader.cs (.../StochasticSoilModelReader.cs) (revision d82fa09fe9ae053ce7702ba89ef23ae029640d1b) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/StochasticSoilModelReader.cs (.../StochasticSoilModelReader.cs) (revision 64c21c2c91a3cef9df279e58efda8e45a9d598f7) @@ -38,6 +38,7 @@ public class StochasticSoilModelReader : SqLiteDatabaseReaderBase { private const string pipingMechanismName = "Piping"; + private readonly string filePath; private SQLiteDataReader dataReader; /// @@ -53,6 +54,7 @@ /// public StochasticSoilModelReader(string databaseFilePath) : base(databaseFilePath) { + filePath = databaseFilePath; VerifyVersion(databaseFilePath); InitializeReader(); } @@ -124,9 +126,31 @@ MoveNext(); } while (HasNext && ReadStochasticSoilModelSegment().Id == currentSegmentSoilModelId); + AddStochasticSoilProfiles(stochasticSoilModelSegment); + return stochasticSoilModelSegment; } + private void AddStochasticSoilProfiles(StochasticSoilModel stochasticSoilModelSegment) + { + using (var stochasticSoilProfileReader = new StochasticSoilProfileReader(filePath)) + { + while (stochasticSoilProfileReader.HasNext) + { + AddStochasticSoilProfile(stochasticSoilModelSegment, stochasticSoilProfileReader); + } + } + } + + private static void AddStochasticSoilProfile(StochasticSoilModel stochasticSoilModelSegment, StochasticSoilProfileReader stochasticSoilProfileReader) + { + var stochasticSoilProfile = stochasticSoilProfileReader.ReadStochasticSoilProfile(stochasticSoilModelSegment.Id); + if (stochasticSoilProfile != null) + { + stochasticSoilModelSegment.StochasticSoilProfiles.Add(stochasticSoilProfile); + } + } + /// /// Prepares a new data reader with queries for obtaining the models and updates the reader /// so that it points to the first row of the result set. Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/StochasticSoilProfileReader.cs =================================================================== diff -u -rcdc41931db8cd6fbebe910c08d315d1b7066a6d2 -r64c21c2c91a3cef9df279e58efda8e45a9d598f7 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/StochasticSoilProfileReader.cs (.../StochasticSoilProfileReader.cs) (revision cdc41931db8cd6fbebe910c08d315d1b7066a6d2) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/StochasticSoilProfileReader.cs (.../StochasticSoilProfileReader.cs) (revision 64c21c2c91a3cef9df279e58efda8e45a9d598f7) @@ -66,16 +66,19 @@ /// instance of the information. /// /// Identifier of the next to look for. - /// The next from the database, or null if no more soil profiles can be read. + /// The next from the database, or null if no more stochastic soil profiles can be read. /// Thrown when the database returned incorrect values for required properties. public StochasticSoilProfile ReadStochasticSoilProfile(long stochasticSoilModelId) { if (!HasNext) { return null; } - MoveToStochasticSoilModelId(stochasticSoilModelId); + if (!MoveToStochasticSoilModelId(stochasticSoilModelId)) + { + return null; + } try { StochasticSoilProfile stochasticSoilProfile = ReadStochasticSoilProfileProbability(); @@ -136,19 +139,26 @@ } } - private void MoveToStochasticSoilModelId(long stochasticSoilModelId) + private bool MoveToStochasticSoilModelId(long stochasticSoilModelId) { while (HasNext && ReadStochasticSoilModelId() < stochasticSoilModelId) { MoveNext(); } + if (ReadStochasticSoilModelId() == stochasticSoilModelId) + { + return true; + } + MoveToNextStochasticSoilModelId(stochasticSoilModelId); + return false; } private void MoveToNextStochasticSoilModelId(long stochasticSoilModelId) { - while (HasNext && ReadStochasticSoilModelId() == stochasticSoilModelId) + MoveNext(); + if (HasNext) { - MoveNext(); + HasNext = ReadStochasticSoilModelId() == stochasticSoilModelId; } } Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilDatabaseQueryBuilderTest.cs =================================================================== diff -u -r86e6bb44ba1ccbec534f3fcf379481ea8d45d67f -r64c21c2c91a3cef9df279e58efda8e45a9d598f7 --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilDatabaseQueryBuilderTest.cs (.../SoilDatabaseQueryBuilderTest.cs) (revision 86e6bb44ba1ccbec534f3fcf379481ea8d45d67f) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Builders/SoilDatabaseQueryBuilderTest.cs (.../SoilDatabaseQueryBuilderTest.cs) (revision 64c21c2c91a3cef9df279e58efda8e45a9d598f7) @@ -64,11 +64,12 @@ public void GetStochasticSoilModelOfMechanismCountQuery_Always_ReturnsExpectedValues() { // Setup - const string expectedQuery = "SELECT COUNT('1') AS nrOfRows " + - "FROM Mechanism M " + + const string expectedQuery = "SELECT COUNT('1') AS nrOfRows FROM (" + + "SELECT '1' FROM Mechanism M " + "INNER JOIN Segment S USING(ME_ID) " + "INNER JOIN StochasticSoilModel SSM USING(SSM_ID) " + - "WHERE M.ME_Name = @ME_Name;"; + "INNER JOIN SegmentPoints SP USING(SE_ID) " + + "WHERE M.ME_Name = @ME_Name GROUP BY SSM_ID);"; // Call string query = SoilDatabaseQueryBuilder.GetStochasticSoilModelOfMechanismCountQuery(); Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/SoilProfile/StochasticSoilModelReaderTest.cs =================================================================== diff -u -rd82fa09fe9ae053ce7702ba89ef23ae029640d1b -r64c21c2c91a3cef9df279e58efda8e45a9d598f7 --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/SoilProfile/StochasticSoilModelReaderTest.cs (.../StochasticSoilModelReaderTest.cs) (revision d82fa09fe9ae053ce7702ba89ef23ae029640d1b) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/SoilProfile/StochasticSoilModelReaderTest.cs (.../StochasticSoilModelReaderTest.cs) (revision 64c21c2c91a3cef9df279e58efda8e45a9d598f7) @@ -20,8 +20,9 @@ // All rights reserved. using System; +using System.Collections.Generic; using System.IO; -using Core.Common.Base.Geometry; +using System.Linq; using Core.Common.IO.Exceptions; using Core.Common.IO.Readers; using Core.Common.TestUtil; @@ -190,7 +191,7 @@ } [Test] - public void ReadStochasticSoilProfile_InvalidSegmentPoint_ThrowsStochasticSoilModelReadException() + public void ReadStochasticSoilModel_InvalidSegmentPoint_ThrowsStochasticSoilModelReadException() { // Setup string dbName = "invalidSegmentPoint.soil"; @@ -212,16 +213,12 @@ } [Test] - public void ReadStochasticSoilProfile_CompleteDatabase_ReturnsExpectedValues() + public void ReadStochasticSoilModel_EmptyDatabase_ReturnsNull() { // Setup - string dbName = "complete.soil"; + var dbName = "emptyschema.soil"; string dbFile = Path.Combine(testDataPath, dbName); - const string expectedSegmentName = "36005_Piping"; - const string expectedSegmentSoilModelName = "36005_Piping"; - const long expectedSegmentSoilModelId = 2; - const long expectedSegmentSoilModelPoints = 1797; - const int expectedNrOfModels = 3; + const int expectedNrOfModels = 0; using (var stochasticSoilModelDatabaseReader = new StochasticSoilModelReader(dbFile)) { @@ -231,41 +228,221 @@ StochasticSoilModel stochasticSoilModel = stochasticSoilModelDatabaseReader.ReadStochasticSoilModel(); // Assert - Assert.IsNotNull(stochasticSoilModel); + Assert.IsNull(stochasticSoilModel); Assert.AreEqual(expectedNrOfModels, nrOfModels); - Assert.AreEqual(expectedSegmentName, stochasticSoilModel.SegmentName); - Assert.AreEqual(expectedSegmentSoilModelName, stochasticSoilModel.Name); - Assert.AreEqual(expectedSegmentSoilModelId, stochasticSoilModel.Id); - Assert.AreEqual(expectedSegmentSoilModelPoints, stochasticSoilModel.Geometry.Count); - CollectionAssert.AllItemsAreInstancesOfType(stochasticSoilModel.Geometry, typeof(Point2D)); - CollectionAssert.AllItemsAreInstancesOfType(stochasticSoilModel.StochasticSoilProfiles, typeof(StochasticSoilProfile)); - Assert.IsTrue(stochasticSoilModelDatabaseReader.HasNext); + Assert.IsFalse(stochasticSoilModelDatabaseReader.HasNext); } - Assert.IsTrue(TestHelper.CanOpenFileForWrite(dbFile)); } [Test] - public void ReadStochasticSoilProfile_EmptyDatabase_ReturnsNull() + public void ReadStochasticSoilModel_ModelWithoutProfile_ThreeModelsWithSecondWithoutProfiles() { // Setup - var dbName = "emptyschema.soil"; + var dbName = "modelWithoutProfile.soil"; string dbFile = Path.Combine(testDataPath, dbName); - const int expectedNrOfModels = 0; + const int expectedNrOfModels = 3; using (var stochasticSoilModelDatabaseReader = new StochasticSoilModelReader(dbFile)) { int nrOfModels = stochasticSoilModelDatabaseReader.PipingStochasticSoilModelCount; + var readModels = new List(); + while (stochasticSoilModelDatabaseReader.HasNext) + { + // Call + readModels.Add(stochasticSoilModelDatabaseReader.ReadStochasticSoilModel()); + } - // Call - StochasticSoilModel stochasticSoilModel = stochasticSoilModelDatabaseReader.ReadStochasticSoilModel(); + // Assert + var expectedSegmentAndModelNames = new[] + { + "36005_Piping", + "36006_Piping", + "36007_Piping" + }; + var expectedModelIds = new[] + { + 2, + 4, + 6 + }; + var expectedSegmentPointCount = new[] + { + 1797, + 144, + 606 + }; + var expectedProfileCount = new[] + { + 10, + 0, + 8 + }; + Assert.AreEqual(expectedNrOfModels, nrOfModels); + CollectionAssert.AreEqual(expectedSegmentAndModelNames, readModels.Select(m => m.SegmentName)); + CollectionAssert.AreEqual(expectedSegmentAndModelNames, readModels.Select(m => m.Name)); + CollectionAssert.AreEqual(expectedModelIds, readModels.Select(m => m.Id)); + CollectionAssert.AreEqual(expectedSegmentPointCount, readModels.Select(m => m.Geometry.Count)); + CollectionAssert.AreEqual(expectedProfileCount, readModels.Select(m => m.StochasticSoilProfiles.Count)); + + Assert.IsFalse(stochasticSoilModelDatabaseReader.HasNext); + } + + Assert.IsTrue(TestHelper.CanOpenFileForWrite(dbFile)); + } + + [Test] + public void ReadStochasticSoilModel_CompleteDatabase_ThreeModelsWithProfiles() + { + // Setup + string dbName = "complete.soil"; + string dbFile = Path.Combine(testDataPath, dbName); + const int expectedNrOfModels = 3; + + using (var stochasticSoilModelDatabaseReader = new StochasticSoilModelReader(dbFile)) + { + int nrOfModels = stochasticSoilModelDatabaseReader.PipingStochasticSoilModelCount; + var readModels = new List(); + while (stochasticSoilModelDatabaseReader.HasNext) + { + // Call + readModels.Add(stochasticSoilModelDatabaseReader.ReadStochasticSoilModel()); + } + // Assert - Assert.IsNull(stochasticSoilModel); + var expectedSegmentAndModelNames = new[] + { + "36005_Piping", + "36006_Piping", + "36007_Piping" + }; + var expectedModelIds = new[] + { + 2, + 4, + 6 + }; + var expectedSegmentPointCount = new[] + { + 1797, + 144, + 606 + }; + var expectedProfileCount = new[] + { + 10, + 6, + 8 + }; Assert.AreEqual(expectedNrOfModels, nrOfModels); + + CollectionAssert.AreEqual(expectedSegmentAndModelNames, readModels.Select(m => m.SegmentName)); + CollectionAssert.AreEqual(expectedSegmentAndModelNames, readModels.Select(m => m.Name)); + CollectionAssert.AreEqual(expectedModelIds, readModels.Select(m => m.Id)); + CollectionAssert.AreEqual(expectedSegmentPointCount, readModels.Select(m => m.Geometry.Count)); + CollectionAssert.AreEqual(expectedProfileCount, readModels.Select(m => m.StochasticSoilProfiles.Count)); + Assert.IsFalse(stochasticSoilModelDatabaseReader.HasNext); } + Assert.IsTrue(TestHelper.CanOpenFileForWrite(dbFile)); } + + [Test] + public void Count_ThreeModelsOneModelWithoutSegmentPoints_ReturnsTwo() + { + // Setup + string dbName = "modelWithoutSegmentPoints.soil"; + string dbFile = Path.Combine(testDataPath, dbName); + + using (var stochasticSoilModelDatabaseReader = new StochasticSoilModelReader(dbFile)) + { + int nrOfModels = stochasticSoilModelDatabaseReader.PipingStochasticSoilModelCount; + + Assert.AreEqual(2, nrOfModels); + } + + Assert.IsTrue(TestHelper.CanOpenFileForWrite(dbFile)); + } + + [Test] + public void ReadStochasticSoilModel_ThreeModelsOneModelWithoutSegmentPointsUsingCount_ReturnsTwoModels() + { + // Setup + string dbName = "modelWithoutSegmentPoints.soil"; + string dbFile = Path.Combine(testDataPath, dbName); + + using (var stochasticSoilModelDatabaseReader = new StochasticSoilModelReader(dbFile)) + { + var readModels = new List(); + for (int i = 0; i < stochasticSoilModelDatabaseReader.PipingStochasticSoilModelCount; i++) + { + // Call + readModels.Add(stochasticSoilModelDatabaseReader.ReadStochasticSoilModel()); + } + + // Assert + CheckModelWithoutSegmentPoints(readModels); + Assert.IsFalse(stochasticSoilModelDatabaseReader.HasNext); + } + + Assert.IsTrue(TestHelper.CanOpenFileForWrite(dbFile)); + } + + [Test] + public void ReadStochasticSoilModel_ThreeModelsOneModelWithoutSegmentPointsUsingHasNext_ReturnsTwoModels() + { + // Setup + string dbName = "modelWithoutSegmentPoints.soil"; + string dbFile = Path.Combine(testDataPath, dbName); + + using (var stochasticSoilModelDatabaseReader = new StochasticSoilModelReader(dbFile)) + { + var readModels = new List(); + while (stochasticSoilModelDatabaseReader.HasNext) + { + // Call + readModels.Add(stochasticSoilModelDatabaseReader.ReadStochasticSoilModel()); + } + + // Assert + CheckModelWithoutSegmentPoints(readModels); + Assert.IsFalse(stochasticSoilModelDatabaseReader.HasNext); + } + + Assert.IsTrue(TestHelper.CanOpenFileForWrite(dbFile)); + } + + private static void CheckModelWithoutSegmentPoints(List readModels) + { + var expectedSegmentAndModelNames = new[] + { + "36005_Piping", + "36007_Piping" + }; + var expectedModelIds = new[] + { + 2, + 6 + }; + var expectedSegmentPointCount = new[] + { + 1797, + 606 + }; + var expectedProfileCount = new[] + { + 10, + 8 + }; + + Assert.AreEqual(2, readModels.Count); + CollectionAssert.AreEqual(expectedSegmentAndModelNames, readModels.Select(m => m.SegmentName)); + CollectionAssert.AreEqual(expectedSegmentAndModelNames, readModels.Select(m => m.Name)); + CollectionAssert.AreEqual(expectedModelIds, readModels.Select(m => m.Id)); + CollectionAssert.AreEqual(expectedSegmentPointCount, readModels.Select(m => m.Geometry.Count)); + CollectionAssert.AreEqual(expectedProfileCount, readModels.Select(m => m.StochasticSoilProfiles.Count)); + } } } \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/StochasticSoilModelDatabaseReader/modelWithoutProfile.soil =================================================================== diff -u Binary files differ Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/StochasticSoilModelDatabaseReader/modelWithoutSegmentPoints.soil =================================================================== diff -u Binary files differ