// 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; using System.Data.SQLite; using Core.Common.IO.Exceptions; using Core.Common.IO.Readers; using Core.Common.Utils.Builders; using Ringtoets.HydraRing.Data; 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 SQLiteDataReader 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; } /// /// 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 void PrepareReadLocation() { CloseDataReader(); HasNext = false; string locationsQuery = HydraulicBoundaryDatabaseQueryBuilder.GetRelevantLocationsQuery(); sqliteDataReader = CreateDataReader(locationsQuery, new SQLiteParameter { DbType = DbType.String }); MoveNext(); } public HrdLocation ReadLocation() { if (!HasNext) { return null; } try { return ReadHrdLocation(); } catch (InvalidCastException e) { var 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 (SQLiteDataReader dataReader = CreateDataReader(versionQuery, null)) { return !dataReader.Read() ? String.Empty : Convert.ToString(dataReader[GeneralTableDefinitions.GeneratedVersion]); } } catch (SQLiteException exception) { var message = new FileReaderErrorMessageBuilder(Path).Build(Resources.Error_HydraulicBoundaryLocation_read_from_database); throw new CriticalFileReadException(message, exception); } } /// /// Gets the region id from the metadata table. /// /// The region id found in the database, or 0 if the region 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 GetRegionId() { string versionQuery = HydraulicBoundaryDatabaseQueryBuilder.GetRegionIdQuery(); var sqliteParameter = new SQLiteParameter { DbType = DbType.String }; try { using (SQLiteDataReader dataReader = CreateDataReader(versionQuery, sqliteParameter)) { return !dataReader.Read() ? 0 : Convert.ToInt64(dataReader[GeneralTableDefinitions.RegionId]); } } catch (InvalidCastException exception) { var message = new FileReaderErrorMessageBuilder(Path). Build(Resources.HydraulicBoundaryDatabaseReader_Critical_Unexpected_value_on_column); throw new LineParseException(message, exception); } catch (SQLiteException exception) { var 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 (SQLiteDataReader dataReader = CreateDataReader(locationCountQuery, sqliteParameter)) { return !dataReader.Read() ? 0 : Convert.ToInt32(dataReader[HrdLocationsTableDefinitions.Count]); } } catch (InvalidCastException) { return 0; } catch (SQLiteException exception) { var 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 a value at column from the database. /// /// The expected type of value in the column with name . /// The name of the column to read from. /// The read value from the column with name . /// Thrown when the value in the column was not of type /// . private T Read(string columnName) { return (T) sqliteDataReader[columnName]; } /// /// 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 = Read(HrdLocationsTableDefinitions.HrdLocationId); var name = Read(HrdLocationsTableDefinitions.Name); var x = Read(HrdLocationsTableDefinitions.XCoordinate); var y = Read(HrdLocationsTableDefinitions.YCoordinate); MoveNext(); return new HrdLocation(id, name, x, y); } catch (InvalidCastException) { MoveNext(); throw; } } private void CloseDataReader() { if (sqliteDataReader != null) { sqliteDataReader.Dispose(); } } } }