// 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.IO; using Core.Common.IO.Exceptions; using Core.Common.IO.Readers; using Core.Common.Utils.Builders; using Ringtoets.HydraRing.IO.Properties; namespace Ringtoets.HydraRing.IO.HydraulicBoundaryDatabaseContext { /// /// This class reads a SqLite database file and constructs /// instances from this database. /// public class HydraulicBoundarySqLiteDatabaseReader : SqLiteDatabaseReaderBase { private IDataReader sqliteDataReader; /// /// 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 HydraulicBoundarySqLiteDatabaseReader(string databaseFilePath) : base(databaseFilePath) {} /// /// Gets a value indicating whether or not more hydraulic boundary locations can /// be read using the . /// public bool HasNext { get; private set; } public void PrepareReadLocation() { CloseDataReader(); HasNext = false; string locationsQuery = HydraulicBoundaryDatabaseQueryBuilder.GetRelevantLocationsQuery(); sqliteDataReader = CreateDataReader(locationsQuery); MoveNext(); } /// /// Reads the next location from the database. /// /// New instance of , based on the data read from /// the database or null if no data is available. /// Thrown when the database returned incorrect /// values for required properties. public HrdLocation ReadLocation() { if (!HasNext) { return null; } try { return ReadHrdLocation(); } catch (ConversionException e) { string message = new FileReaderErrorMessageBuilder(Path). Build(Resources.HydraulicBoundaryDatabaseReader_Critical_Unexpected_value_on_column); throw new LineParseException(message, e); } } /// /// Gets the database version from the metadata table. /// /// The version found in the database, or if the version /// cannot be found. /// Thrown when a query could not be executed on the database schema. public string GetVersion() { string versionQuery = HydraulicBoundaryDatabaseQueryBuilder.GetVersionQuery(); try { using (IDataReader dataReader = CreateDataReader(versionQuery, null)) { return !dataReader.Read() ? string.Empty : Convert.ToString(dataReader[GeneralTableDefinitions.GeneratedVersion]); } } catch (SQLiteException exception) { string message = new FileReaderErrorMessageBuilder(Path).Build(Resources.Error_HydraulicBoundaryLocation_read_from_database); throw new CriticalFileReadException(message, exception); } } /// /// Gets the track id from the metadata table. /// /// The track id found in the database, or 0 if the track id /// cannot be found. /// Thrown when the database returned incorrect /// values for required properties. /// Thrown when a query could not be executed on the database schema. public long GetTrackId() { string trackQuery = HydraulicBoundaryDatabaseQueryBuilder.GetTrackIdQuery(); var sqliteParameter = new SQLiteParameter { DbType = DbType.String }; try { using (IDataReader dataReader = CreateDataReader(trackQuery, sqliteParameter)) { return !dataReader.Read() ? 0 : Convert.ToInt64(dataReader[GeneralTableDefinitions.TrackId]); } } catch (InvalidCastException exception) { string message = new FileReaderErrorMessageBuilder(Path). Build(Resources.HydraulicBoundaryDatabaseReader_Critical_Unexpected_value_on_column); throw new LineParseException(message, exception); } catch (SQLiteException exception) { string message = new FileReaderErrorMessageBuilder(Path).Build(Resources.Error_HydraulicBoundaryLocation_read_from_database); throw new CriticalFileReadException(message, exception); } } /// /// Gets the amount of locations that can be read from the database. /// /// The amount of locations that can be read. /// Thrown when a query could not be executed on the database schema. public int GetLocationCount() { string locationCountQuery = HydraulicBoundaryDatabaseQueryBuilder.GetRelevantLocationsCountQuery(); var sqliteParameter = new SQLiteParameter { DbType = DbType.String }; try { using (IDataReader dataReader = CreateDataReader(locationCountQuery, sqliteParameter)) { return !dataReader.Read() ? 0 : Convert.ToInt32(dataReader[HrdLocationsTableDefinitions.Count]); } } catch (InvalidCastException) { return 0; } catch (SQLiteException exception) { string message = new FileReaderErrorMessageBuilder(Path).Build(Resources.Error_HydraulicBoundaryLocation_read_from_database); throw new CriticalFileReadException(message, exception); } } public override void Dispose() { CloseDataReader(); base.Dispose(); } /// /// Moves the reader to the next record in the database. /// private void MoveNext() { HasNext = MoveNext(sqliteDataReader); } /// /// Reads the current row into a new instance of . /// /// A new instance of , based upon the current row. /// Thrown when the database returned incorrect values for /// required properties. private HrdLocation ReadHrdLocation() { try { var id = sqliteDataReader.Read(HrdLocationsTableDefinitions.HrdLocationId); var name = sqliteDataReader.Read(HrdLocationsTableDefinitions.Name); var x = sqliteDataReader.Read(HrdLocationsTableDefinitions.XCoordinate); var y = sqliteDataReader.Read(HrdLocationsTableDefinitions.YCoordinate); MoveNext(); return new HrdLocation(id, name, x, y); } catch (InvalidCastException) { MoveNext(); throw; } } private void CloseDataReader() { sqliteDataReader?.Dispose(); } } }