// Copyright (C) Stichting Deltares 2016. 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.SQLite; using Core.Common.IO.Exceptions; using Core.Common.IO.Readers; using Core.Common.Utils.Builders; using Ringtoets.Piping.Data; using Ringtoets.Piping.IO.Builders; using Ringtoets.Piping.IO.Exceptions; using Ringtoets.Piping.IO.Properties; namespace Ringtoets.Piping.IO.SoilProfile { /// /// This class reads a DSoil database file and reads from this database. /// public class StochasticSoilProfileReader : SqLiteDatabaseReaderBase { private SQLiteDataReader 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 . /// The database version could not be read. /// The database version is incorrect. /// public StochasticSoilProfileReader(string databaseFilePath) : base(databaseFilePath) { VerifyVersion(databaseFilePath); InitializeReader(); } /// /// Gets a value indicating whether or not more stochastic soil profiles can be read using /// the . /// public bool HasNext { get; private set; } /// /// Reads the information for the next stochastic soil profile from the database and creates a /// 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. /// Thrown when the database returned incorrect values for required properties. public StochasticSoilProfile ReadStochasticSoilProfile(long stochasticSoilModelId) { if (!HasNext) { return null; } MoveToStochasticSoilModelId(stochasticSoilModelId); try { StochasticSoilProfile stochasticSoilProfile = ReadStochasticSoilProfileProbability(); MoveToNextStochasticSoilModelId(stochasticSoilModelId); return stochasticSoilProfile; } catch (SystemException exception) { if (exception is FormatException || exception is OverflowException || exception is InvalidCastException) { var message = new FileReaderErrorMessageBuilder(Path).Build(Resources.StochasticSoilProfileDatabaseReader_StochasticSoilProfile_has_invalid_value); throw new StochasticSoilProfileReadException(message, exception); } throw; } } public override void Dispose() { if (dataReader != null) { dataReader.Dispose(); } base.Dispose(); } /// /// Prepares a new data reader with queries for obtaining the profiles and updates the reader /// so that it points to the first row of the result set. /// /// A query could not be executed on the database schema. private void InitializeReader() { CreateDataReader(); MoveNext(); } /// /// Moves the reader to the next record in the database. /// private void MoveNext() { HasNext = MoveNext(dataReader); } private void CreateDataReader() { var stochasticSoilProfileQuery = SoilDatabaseQueryBuilder.GetAllStochasticSoilProfileQuery(); try { dataReader = CreateDataReader(stochasticSoilProfileQuery); } catch (SQLiteException exception) { CloseConnection(); var message = new FileReaderErrorMessageBuilder(Path).Build(Resources.StochasticSoilModelDatabaseReader_Failed_to_read_database); throw new CriticalFileReadException(message, exception); } } private void MoveToStochasticSoilModelId(long stochasticSoilModelId) { while (HasNext && ReadStochasticSoilModelId() < stochasticSoilModelId) { MoveNext(); } } private void MoveToNextStochasticSoilModelId(long stochasticSoilModelId) { while (HasNext && ReadStochasticSoilModelId() == stochasticSoilModelId) { MoveNext(); } } private void VerifyVersion(string databaseFilePath) { using (var versionReader = new SoilDatabaseVersionReader(databaseFilePath)) { try { versionReader.VerifyVersion(); } catch (CriticalFileReadException) { CloseConnection(); throw; } } } private long ReadStochasticSoilModelId() { return Convert.ToInt64(dataReader[StochasticSoilProfileDatabaseColumns.StochasticSoilModelId]); } private StochasticSoilProfile ReadStochasticSoilProfileProbability() { var valueProbability = dataReader[StochasticSoilProfileDatabaseColumns.Probability]; var probability = (valueProbability.Equals(DBNull.Value)) ? 0 : Convert.ToDouble(valueProbability); var soilProfile1DId = ReadSoilProfile1DId(probability); if (soilProfile1DId != null) { return soilProfile1DId; } var soilProfile2DId = ReadSoilProfile2DId(probability); if (soilProfile2DId != null) { return soilProfile2DId; } var message = new FileReaderErrorMessageBuilder(Path).Build(Resources.StochasticSoilProfileDatabaseReader_StochasticSoilProfile_has_invalid_value); throw new StochasticSoilProfileReadException(message); } private StochasticSoilProfile ReadSoilProfile2DId(double probability) { var valueSoilProfile2DId = dataReader[StochasticSoilProfileDatabaseColumns.SoilProfile2DId]; if (!valueSoilProfile2DId.Equals(DBNull.Value)) { var soilProfileId = Convert.ToInt64(valueSoilProfile2DId); return new StochasticSoilProfile(probability, SoilProfileType.SoilProfile2D, soilProfileId); } return null; } private StochasticSoilProfile ReadSoilProfile1DId(double probability) { var valueSoilProfile1DId = dataReader[StochasticSoilProfileDatabaseColumns.SoilProfile1DId]; if (!valueSoilProfile1DId.Equals(DBNull.Value)) { var soilProfileId = Convert.ToInt64(valueSoilProfile1DId); return new StochasticSoilProfile(probability, SoilProfileType.SoilProfile1D, soilProfileId); } return null; } } }