// 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.Collections.Generic; using System.Data; using System.Data.SQLite; using System.IO; using Core.Common.Utils; using Ringtoets.HydraRing.Calculation.Exceptions; using Ringtoets.HydraRing.Calculation.Properties; using Ringtoets.HydraRing.IO; namespace Ringtoets.HydraRing.Calculation.Readers { /// /// Class for reading the output database of a Hydra-Ring calculation. /// internal class HydraRingDatabaseReader : IDisposable { private const string sectionIdParameterName = "@sectionId"; private readonly string workingDirectory; private SQLiteDataReader reader; private SQLiteCommand command; private SQLiteConnection connection; private Dictionary results; /// /// Creates a new instance of . /// /// The path to the directory which contains the /// output of the Hydra-Ring calculation. /// The query to perform when reading the database. /// The section id to get the output for. /// Thrown when /// or is null. /// Thrown when /// /// is zero-length, or /// contains only whitespace, or /// contains illegal characters, or /// contains a colon which is not part of a volume identifier, or /// is too long. /// /// /// Thrown when the reader encounters /// an error while connecting to the database. public HydraRingDatabaseReader(string workingDirectory, string query, int sectionId) { if (workingDirectory == null) { throw new ArgumentNullException(nameof(workingDirectory)); } if (query == null) { throw new ArgumentNullException(nameof(query)); } IOUtils.ValidateFilePath(workingDirectory); this.workingDirectory = workingDirectory; connection = CreateConnection(); CreateCommand(query, sectionId); OpenConnection(); GetReader(); } /// /// Executes the query on the database. /// /// Thrown when /// an error encounters while reading the database. public void Execute() { results = new Dictionary(); if (reader.Read()) { for (var i = 0; i < reader.FieldCount; i++) { results.Add(reader.GetName(i), reader[i]); } } else { throw new HydraRingDatabaseReaderException(Resources.HydraRingDatabaseReader_Execute_No_result_found_in_output_file); } } /// /// Reads the object of the given column. /// /// The name of the column to read. /// The object that is stored in the given column. /// Thrown when /// is null. public object ReadColumn(string columnName) { if (columnName == null) { throw new ArgumentNullException(nameof(columnName)); } return results[columnName]; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { reader?.Dispose(); connection?.Dispose(); command?.Dispose(); } } private void GetReader() { reader = command.ExecuteReader(); } /// /// Opens the connection. /// /// Thrown when /// the connection could not be opened. private void OpenConnection() { connection.Open(); } private void CreateCommand(string query, int sectionId) { command = new SQLiteCommand(query, connection); command.Parameters.Add(new SQLiteParameter { DbType = DbType.Int64, ParameterName = sectionIdParameterName, Value = sectionId }); } private SQLiteConnection CreateConnection() { string databaseFile = Path.Combine(workingDirectory, HydraRingFileConstants.OutputDatabaseFileName); string connectionStringBuilder = new SQLiteConnectionStringBuilder { FailIfMissing = true, DataSource = databaseFile, ReadOnly = true }.ConnectionString; return new SQLiteConnection(connectionStringBuilder); } } }