// 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 System.Data; using System.Data.SQLite; using Core.Common.Base.Geometry; 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 reads a DSoil database file and reads stochastic soil model from this database. /// public class StochasticSoilModelReader : SqLiteDatabaseReaderBase { private IDataReader dataReader; /// /// Creates a new instance of , /// which will use the as its source. /// /// The path of the database file to open. /// Thrown when: /// /// The contains invalid characters. /// No file could be found at . /// /// public StochasticSoilModelReader(string databaseFilePath) : base(databaseFilePath) {} /// /// Gets a value indicating whether or not more stochastic soil models can be read using /// the . /// public bool HasNext { get; private set; } /// /// Validates the database. /// /// Thrown when: /// /// The database version could not be read; /// The database version is incorrect; /// Required information for constraint evaluation could not be read; /// The database segment names are not unique; /// Failed to fetch stochastic soil models from the database. /// /// public void Validate() { VerifyVersion(Path); VerifyConstraints(Path); InitializeReader(); } /// /// Reads the information for the next stochastic soil model from the database and creates a /// instance of the information. /// /// The next from the database, or null /// if no more soil models can be read. /// Thrown when the database returned incorrect /// values for required properties. public StochasticSoilModel ReadStochasticSoilModel() { try { return TryReadStochasticSoilModel(); } catch (SystemException exception) when (exception is FormatException || exception is OverflowException || exception is InvalidCastException) { string message = new FileReaderErrorMessageBuilder(Path).Build(Resources.StochasticSoilProfileDatabaseReader_StochasticSoilProfile_has_invalid_value); throw new CriticalFileReadException(message, exception); } } protected override void Dispose(bool disposing) { if (dataReader != null) { dataReader.Close(); dataReader.Dispose(); dataReader = null; } base.Dispose(disposing); } private StochasticSoilModel TryReadStochasticSoilModel() { if (!HasNext) { return null; } StochasticSoilModel stochasticSoilModel = CreateStochasticSoilModel(); long currentSegmentSoilModelId = ReadStochasticSoilModelSegmentId(); do { stochasticSoilModel.Geometry.Add(ReadSegmentPoint()); MoveNext(); } while (HasNext && ReadStochasticSoilModelSegmentId() == currentSegmentSoilModelId); return stochasticSoilModel; } private Point2D ReadSegmentPoint() { double coordinateX = Convert.ToDouble(dataReader[SegmentPointsTableDefinitions.CoordinateX]); double coordinateY = Convert.ToDouble(dataReader[SegmentPointsTableDefinitions.CoordinateY]); return new Point2D(coordinateX, coordinateY); } private long ReadStochasticSoilModelSegmentId() { return Convert.ToInt64(dataReader[StochasticSoilModelTableDefinitions.StochasticSoilModelId]); } private StochasticSoilModel CreateStochasticSoilModel() { string stochasticSoilModelName = Convert.ToString(dataReader[StochasticSoilModelTableDefinitions.StochasticSoilModelName]); return new StochasticSoilModel { Name = stochasticSoilModelName }; } /// /// Initializes a new . /// /// Thrown when failed to fetch stochastic soil models from the database. private void InitializeReader() { CreateDataReader(); MoveNext(); } private void MoveNext() { HasNext = MoveNext(dataReader); } /// /// Creates a new . /// /// Thrown when failed to fetch stochastic soil models from the database. private void CreateDataReader() { string stochasticSoilModelSegmentsQuery = SoilDatabaseQueryBuilder.GetStochasticSoilModelOfMechanismQuery(); try { dataReader = CreateDataReader(stochasticSoilModelSegmentsQuery); } catch (SQLiteException exception) { string message = new FileReaderErrorMessageBuilder(Path).Build(Resources.StochasticSoilModelDatabaseReader_Failed_to_read_database); throw new CriticalFileReadException(message, exception); } } /// /// Verifies that the database at has the required version. /// /// The path of the database file to open. /// Thrown when: /// /// The database version could not be read; /// The database version is incorrect. /// /// private static void VerifyVersion(string databaseFilePath) { using (var reader = new SoilDatabaseVersionReader(databaseFilePath)) { reader.VerifyVersion(); } } /// /// Verifies that the database at meets required constraints. /// /// The path of the database file to open. /// Thrown when: /// /// Required information for constraint evaluation could not be read; /// The database segment names are not unique. /// /// private static void VerifyConstraints(string databaseFilePath) { using (var reader = new SoilDatabaseConstraintsReader(databaseFilePath)) { reader.VerifyConstraints(); } } } }