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