Rename IEmbeddedDatabaseCreator to IDatabaseCreator and refactor implementations

This commit is contained in:
Ronald Barendse
2021-09-17 12:02:41 +02:00
parent b82fc3350f
commit 785630922e
11 changed files with 114 additions and 74 deletions

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using NPoco;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Infrastructure.Persistence.SqlSyntax;
namespace Umbraco.Cms.Infrastructure.Persistence
@@ -11,7 +10,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence
public class DbProviderFactoryCreator : IDbProviderFactoryCreator
{
private readonly Func<string, DbProviderFactory> _getFactory;
private readonly IDictionary<string, IEmbeddedDatabaseCreator> _embeddedDatabaseCreators;
private readonly IDictionary<string, IDatabaseCreator> _databaseCreators;
private readonly IDictionary<string, ISqlSyntaxProvider> _syntaxProviders;
private readonly IDictionary<string, IBulkSqlInsertProvider> _bulkSqlInsertProviders;
private readonly IDictionary<string, IProviderSpecificMapperFactory> _providerSpecificMapperFactories;
@@ -20,11 +19,11 @@ namespace Umbraco.Cms.Infrastructure.Persistence
Func<string, DbProviderFactory> getFactory,
IEnumerable<ISqlSyntaxProvider> syntaxProviders,
IEnumerable<IBulkSqlInsertProvider> bulkSqlInsertProviders,
IEnumerable<IEmbeddedDatabaseCreator> embeddedDatabaseCreators,
IEnumerable<IDatabaseCreator> databaseCreators,
IEnumerable<IProviderSpecificMapperFactory> providerSpecificMapperFactories)
{
_getFactory = getFactory;
_embeddedDatabaseCreators = embeddedDatabaseCreators.ToDictionary(x => x.ProviderName);
_databaseCreators = databaseCreators.ToDictionary(x => x.ProviderName);
_syntaxProviders = syntaxProviders.ToDictionary(x => x.ProviderName);
_bulkSqlInsertProviders = bulkSqlInsertProviders.ToDictionary(x => x.ProviderName);
_providerSpecificMapperFactories = providerSpecificMapperFactories.ToDictionary(x => x.ProviderName);
@@ -60,11 +59,11 @@ namespace Umbraco.Cms.Infrastructure.Persistence
return result;
}
public void CreateDatabase(string providerName)
public void CreateDatabase(string providerName, string connectionString)
{
if (_embeddedDatabaseCreators.TryGetValue(providerName, out var creator))
if (_databaseCreators.TryGetValue(providerName, out var creator))
{
creator.Create();
creator.Create(connectionString);
}
}

View File

@@ -0,0 +1,9 @@
namespace Umbraco.Cms.Infrastructure.Persistence
{
public interface IDatabaseCreator
{
string ProviderName { get; }
void Create(string connectionString);
}
}

View File

@@ -9,7 +9,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence
DbProviderFactory CreateFactory(string providerName);
ISqlSyntaxProvider GetSqlSyntaxProvider(string providerName);
IBulkSqlInsertProvider CreateBulkSqlInsertProvider(string providerName);
void CreateDatabase(string providerName);
void CreateDatabase(string providerName, string connectionString);
NPocoMapperCollection ProviderSpecificMappers(string providerName);
}
}

View File

@@ -1,9 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Persistence
{
public interface IEmbeddedDatabaseCreator
{
string ProviderName { get; }
string ConnectionString { get; set; }
void Create();
}
}

View File

@@ -1,14 +0,0 @@
namespace Umbraco.Cms.Infrastructure.Persistence
{
public class NoopEmbeddedDatabaseCreator : IEmbeddedDatabaseCreator
{
public string ProviderName => Cms.Core.Constants.DatabaseProviders.SqlServer;
public string ConnectionString { get; set; }
public void Create()
{
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using System.Data.SqlClient;
using System.IO;
using Umbraco.Cms.Core;
namespace Umbraco.Cms.Infrastructure.Persistence
{
public class SqlServerDatabaseCreator : IDatabaseCreator
{
public string ProviderName => Constants.DatabaseProviders.SqlServer;
public void Create(string connectionString)
{
var builder = new SqlConnectionStringBuilder(connectionString);
// Get connection string without database specific information
var masterBuilder = new SqlConnectionStringBuilder(builder.ConnectionString)
{
AttachDBFilename = string.Empty,
InitialCatalog = string.Empty
};
var masterConnectionString = masterBuilder.ConnectionString;
string fileName = builder.AttachDBFilename,
database = builder.InitialCatalog;
// Create database
if (!string.IsNullOrEmpty(fileName) && !File.Exists(fileName))
{
if (string.IsNullOrWhiteSpace(database))
{
// Use a temporary database name
database = "Umbraco-" + Guid.NewGuid();
}
using var connection = new SqlConnection(masterConnectionString);
connection.Open();
using var command = new SqlCommand(
$"CREATE DATABASE [{database}] ON (NAME='{database}', FILENAME='{fileName}');" +
$"ALTER DATABASE [{database}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;" +
$"EXEC sp_detach_db @dbname='{database}';",
connection);
command.ExecuteNonQuery();
connection.Close();
}
else if (!string.IsNullOrEmpty(database))
{
using var connection = new SqlConnection(masterConnectionString);
connection.Open();
using var command = new SqlCommand(
$"IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = '{database}') " +
$"CREATE DATABASE [{database}];",
connection);
command.ExecuteNonQuery();
connection.Close();
}
}
}
}

View File

@@ -3,12 +3,12 @@ using System.Data.Common;
using System.Linq;
using Microsoft.Extensions.Options;
using NPoco;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Infrastructure.Persistence.SqlSyntax;
namespace Umbraco.Cms.Infrastructure.Persistence
{
[Obsolete("This is only used for integration tests and should be moved into a test project.")]
public class SqlServerDbProviderFactoryCreator : IDbProviderFactoryCreator
{
private readonly Func<string, DbProviderFactory> _getFactory;
@@ -23,35 +23,29 @@ namespace Umbraco.Cms.Infrastructure.Persistence
public DbProviderFactory CreateFactory(string providerName)
{
if (string.IsNullOrEmpty(providerName)) return null;
return _getFactory(providerName);
}
// gets the sql syntax provider that corresponds, from attribute
public ISqlSyntaxProvider GetSqlSyntaxProvider(string providerName)
{
return providerName switch
=> providerName switch
{
Cms.Core.Constants.DbProviderNames.SqlCe => throw new NotSupportedException("SqlCe is not supported"),
Cms.Core.Constants.DbProviderNames.SqlServer => new SqlServerSyntaxProvider(_globalSettings),
_ => throw new InvalidOperationException($"Unknown provider name \"{providerName}\""),
};
}
public IBulkSqlInsertProvider CreateBulkSqlInsertProvider(string providerName)
{
switch (providerName)
=> providerName switch
{
case Cms.Core.Constants.DbProviderNames.SqlCe:
throw new NotSupportedException("SqlCe is not supported");
case Cms.Core.Constants.DbProviderNames.SqlServer:
return new SqlServerBulkSqlInsertProvider();
default:
return new BasicBulkSqlInsertProvider();
}
}
Cms.Core.Constants.DbProviderNames.SqlCe => throw new NotSupportedException("SqlCe is not supported"),
Cms.Core.Constants.DbProviderNames.SqlServer => new SqlServerBulkSqlInsertProvider(),
_ => new BasicBulkSqlInsertProvider(),
};
public void CreateDatabase(string providerName)
=> throw new NotSupportedException("Embedded databases are not supported");
public void CreateDatabase(string providerName, string connectionString)
=> throw new NotSupportedException("Embedded databases are not supported"); // TODO But LocalDB is?
public NPocoMapperCollection ProviderSpecificMappers(string providerName)
=> new NPocoMapperCollection(() => Enumerable.Empty<IMapper>());

View File

@@ -0,0 +1,16 @@
using Umbraco.Cms.Infrastructure.Persistence;
using Constants = Umbraco.Cms.Core.Constants;
namespace Umbraco.Cms.Persistence.SqlCe
{
public class SqlCeDatabaseCreator : IDatabaseCreator
{
public string ProviderName => Constants.DatabaseProviders.SqlCe;
public void Create(string connectionString)
{
using var engine = new System.Data.SqlServerCe.SqlCeEngine(connectionString);
engine.CreateDatabase();
}
}
}

View File

@@ -1,18 +0,0 @@
using Umbraco.Cms.Infrastructure.Migrations.Install;
using Umbraco.Cms.Infrastructure.Persistence;
using Constants = Umbraco.Cms.Core.Constants;
namespace Umbraco.Cms.Persistence.SqlCe
{
public class SqlCeEmbeddedDatabaseCreator : IEmbeddedDatabaseCreator
{
public string ProviderName => Constants.DatabaseProviders.SqlCe;
public string ConnectionString { get; set; } = DatabaseBuilder.EmbeddedDatabaseConnectionString;
public void Create()
{
var engine = new System.Data.SqlServerCe.SqlCeEngine(ConnectionString);
engine.CreateDatabase();
}
}
}

View File

@@ -23,7 +23,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence
{
private IDbProviderFactoryCreator DbProviderFactoryCreator => GetRequiredService<IDbProviderFactoryCreator>();
private IUmbracoDatabaseFactory UmbracoDatabaseFactory => GetRequiredService<IUmbracoDatabaseFactory>();
private IEmbeddedDatabaseCreator EmbeddedDatabaseCreator => GetRequiredService<IEmbeddedDatabaseCreator>();
private IDatabaseCreator EmbeddedDatabaseCreator => GetRequiredService<IDatabaseCreator>();
public DatabaseBuilderTests()
{
@@ -42,10 +42,10 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence
if (File.Exists(filePath))
File.Delete(filePath);
EmbeddedDatabaseCreator.ConnectionString = $"Datasource=|DataDirectory|{dbFile};Flush Interval=1";
var connectionString = $"Datasource=|DataDirectory|{dbFile};Flush Interval=1";
UmbracoDatabaseFactory.Configure(EmbeddedDatabaseCreator.ConnectionString, Constants.DbProviderNames.SqlCe);
DbProviderFactoryCreator.CreateDatabase(Constants.DbProviderNames.SqlCe);
UmbracoDatabaseFactory.Configure(connectionString, Constants.DbProviderNames.SqlCe);
DbProviderFactoryCreator.CreateDatabase(Constants.DbProviderNames.SqlCe, connectionString);
UmbracoDatabaseFactory.CreateDatabase();
// test get database type (requires an actual database)

View File

@@ -150,7 +150,7 @@ namespace Umbraco.Extensions
DbProviderFactories.GetFactory,
factory.GetServices<ISqlSyntaxProvider>(),
factory.GetServices<IBulkSqlInsertProvider>(),
factory.GetServices<IEmbeddedDatabaseCreator>(),
factory.GetServices<IDatabaseCreator>(),
factory.GetServices<IProviderSpecificMapperFactory>()
));
@@ -357,17 +357,17 @@ namespace Umbraco.Extensions
Type sqlCeSyntaxProviderType = umbSqlCeAssembly.GetType("Umbraco.Cms.Persistence.SqlCe.SqlCeSyntaxProvider");
Type sqlCeBulkSqlInsertProviderType = umbSqlCeAssembly.GetType("Umbraco.Cms.Persistence.SqlCe.SqlCeBulkSqlInsertProvider");
Type sqlCeEmbeddedDatabaseCreatorType = umbSqlCeAssembly.GetType("Umbraco.Cms.Persistence.SqlCe.SqlCeEmbeddedDatabaseCreator");
Type sqlCeDatabaseCreatorType = umbSqlCeAssembly.GetType("Umbraco.Cms.Persistence.SqlCe.SqlCeDatabaseCreator");
Type sqlCeSpecificMapperFactory = umbSqlCeAssembly.GetType("Umbraco.Cms.Persistence.SqlCe.SqlCeSpecificMapperFactory");
if (!(sqlCeSyntaxProviderType is null
|| sqlCeBulkSqlInsertProviderType is null
|| sqlCeEmbeddedDatabaseCreatorType is null
|| sqlCeDatabaseCreatorType is null
|| sqlCeSpecificMapperFactory is null))
{
builder.Services.AddSingleton(typeof(ISqlSyntaxProvider), sqlCeSyntaxProviderType);
builder.Services.AddSingleton(typeof(IBulkSqlInsertProvider), sqlCeBulkSqlInsertProviderType);
builder.Services.AddSingleton(typeof(IEmbeddedDatabaseCreator), sqlCeEmbeddedDatabaseCreatorType);
builder.Services.AddSingleton(typeof(IDatabaseCreator), sqlCeDatabaseCreatorType);
builder.Services.AddSingleton(typeof(IProviderSpecificMapperFactory), sqlCeSpecificMapperFactory);
}
@@ -397,7 +397,7 @@ namespace Umbraco.Extensions
builder.Services.AddSingleton<ISqlSyntaxProvider, SqlServerSyntaxProvider>();
builder.Services.AddSingleton<IBulkSqlInsertProvider, SqlServerBulkSqlInsertProvider>();
builder.Services.AddSingleton<IEmbeddedDatabaseCreator, NoopEmbeddedDatabaseCreator>();
builder.Services.AddSingleton<IDatabaseCreator, SqlServerDatabaseCreator>();
return builder;
}