// 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();
}
}
}
}