using System; using System.Data; using System.Data.Entity; using System.IO; using Application.Ringtoets.Storage.Converters; using Application.Ringtoets.Storage.DbContext; using Application.Ringtoets.Storage.Properties; using Core.Common.Base.Data; using Core.Common.Base.Storage; using Core.Common.Utils.Builders; using UtilsResources = Core.Common.Utils.Properties.Resources; namespace Application.Ringtoets.Storage { /// /// This class interacts with an SQLite database file using the Entity Framework. /// public class StorageSqLite : StorageToDatabaseFile, IStoreProject { /// /// Converts to a new in the database. /// /// Path to database file. /// to save. /// Returns the number of changes that were saved in . /// Thrown when is null. /// is invalid. /// Thrown when the database does not contain the table version. /// Thrown when was not created. /// Thrown when /// /// Saving the to the database failed. /// The connection to the database file failed. /// /// public int SaveProjectAs(string databaseFilePath, Project project) { ConnectToNew(databaseFilePath); using (var dbContext = new RingtoetsEntities(ConnectionString)) { ProjectEntityConverter.InsertProjectEntity(dbContext.ProjectEntities, project); try { return dbContext.SaveChanges(); } catch (DataException exception) { throw CreateUpdateStorageException(Resources.Error_Update_Database, exception); } catch (SystemException exception) { throw CreateUpdateStorageException(Resources.Error_During_Connection, exception); } } } /// /// Attempts to load the from the SQLite database. /// /// Path to database file. /// Returns a new instance of with the data from the database or null when not found. /// is invalid. /// Thrown when does not exist. /// Thrown when the database does not contain the table version. public Project LoadProject(string databaseFilePath) { Connect(databaseFilePath); using (var dbContext = new RingtoetsEntities(ConnectionString)) { return ProjectEntityConverter.GetProject(dbContext.ProjectEntities); } } /// /// Attempts to connect to existing storage file . /// /// Path to database file. /// is invalid. /// Thrown when does not exist. /// Thrown when the database does not contain the table version. protected override void Connect(string databaseFilePath) { base.Connect(databaseFilePath); if (!File.Exists(databaseFilePath)) { var message = new FileReaderErrorMessageBuilder(databaseFilePath).Build(UtilsResources.Error_File_does_not_exist); throw new CouldNotConnectException(message); } ConnectionString = SqLiteStorageConnection.BuildSqLiteEntityConnectionString(databaseFilePath); ValidateStorage(); } /// /// Creates a new (empty) Ringtoets database file. /// /// Path to database file. /// is invalid. /// Thrown when was not created. /// Thrown when executing DatabaseStructure script fails. /// Thrown when the database does not contain the table version. private void ConnectToNew(string databaseFilePath) { base.Connect(databaseFilePath); var creator = new StorageSqliteCreator(); creator.CreateDatabaseStructure(databaseFilePath); Connect(databaseFilePath); } /// /// Validates if the connected storage is a valid Ringtoets database. /// /// Thrown when ConnectionString has not been set. /// Thrown when the database does not contain the table version. private void ValidateStorage() { using (var dbContext = new RingtoetsEntities(ConnectionString)) { try { dbContext.Database.Initialize(true); dbContext.Versions.Load(); } catch { throw new StorageValidationException(string.Format(Resources.Error_Validating_Database_0, FilePath)); } } } } }