Commit 5254a8fa authored by Helgi Hafþórsson's avatar Helgi Hafþórsson
Browse files

cleanup

parent 48487de4
......@@ -15,6 +15,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Marsonsoft.Database.Tests",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Marsonsoft.Database.MySql", "src\Marsonsoft.Database.MySql\Marsonsoft.Database.MySql.csproj", "{1D5D70B3-364D-4625-AD79-C5BFD08AA9ED}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "codeAnalysis", "codeAnalysis", "{F452B515-F5E6-4393-B7A1-07EF1308E75E}"
ProjectSection(SolutionItems) = preProject
codeAnalysis\MarsonsoftRecommended.ruleset = codeAnalysis\MarsonsoftRecommended.ruleset
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
......
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Marsonsoft Recommended" Description="Based on the AllRules ruleset, excluding those deemed irrelvant." ToolsVersion="14.0">
<Include Path="AllRules.ruleset" Action="Default" />
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
<Rule Id="CA1000" Action="None" />
<Rule Id="CA1006" Action="None" />
<Rule Id="CA1014" Action="None" />
<Rule Id="CA1020" Action="None" />
<Rule Id="CA1021" Action="None" />
<Rule Id="CA1062" Action="None" />
<Rule Id="CA1065" Action="None" />
<Rule Id="CA1303" Action="None" />
<Rule Id="CA1308" Action="None" />
<Rule Id="CA1704" Action="None" />
<Rule Id="CA1707" Action="None" />
<Rule Id="CA1709" Action="None" />
<Rule Id="CA1710" Action="None" />
<Rule Id="CA1720" Action="None" />
<Rule Id="CA1726" Action="None" />
<Rule Id="CA1810" Action="None" />
<Rule Id="CA2000" Action="None" />
<Rule Id="CA2103" Action="None" />
<Rule Id="CA2122" Action="None" />
<Rule Id="CA2204" Action="None" />
<Rule Id="CA2210" Action="None" />
</Rules>
</RuleSet>
\ No newline at end of file
......@@ -20,7 +20,7 @@ namespace Marsonsoft.Database.MySql
DbProviderFactory = dbProviderFactory ?? throw new ArgumentNullException(nameof(dbProviderFactory));
ConnectionProvider = connectionProvider ?? throw new ArgumentNullException(nameof(connectionProvider));
TextValidator = new MySqlTextValidator();
Sql = new Sql();
Sql = new SqlFactory();
}
/// <summary>
......@@ -39,8 +39,8 @@ namespace Marsonsoft.Database.MySql
public ITextValidator TextValidator { get; private set; }
/// <summary>
/// Gets the <see cref="ISql"/> instance of this data environment.
/// Gets the <see cref="ISqlFactory"/> instance of this data environment.
/// </summary>
public ISql Sql { get; private set; }
public ISqlFactory Sql { get; private set; }
}
}
......@@ -2,18 +2,18 @@
namespace Marsonsoft.Database.MySql
{
public static class DataEnvironmentProviderExtensions
{
public static void AddMySql(this DataEnvironmentProvider dataEnvironmentProvider)
{
try
{
dataEnvironmentProvider.Add<DataEnvironment>();
}
catch (ArgumentException)
{
// Silently continue in case of previously added
}
}
}
public static class DataEnvironmentProviderExtensions
{
public static void AddMySql(this DataEnvironmentProvider dataEnvironmentProvider)
{
try
{
dataEnvironmentProvider.Add(typeof(DataEnvironment));
}
catch (ArgumentException)
{
// Silently continue if type has already been added.
}
}
}
}
......@@ -20,6 +20,9 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>..\..\codeAnalysis\MarsonsoftRecommended.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
<DocumentationFile>bin\Debug\Marsonsoft.Database.MySql.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
......@@ -28,6 +31,8 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Marsonsoft.Database.MySql.xml</DocumentationFile>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
......@@ -46,7 +51,7 @@
<Compile Include="MySqlExceptionNumber.cs" />
<Compile Include="MySqlTextValidator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Sql.cs" />
<Compile Include="SqlFactory.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Marsonsoft.Database\Marsonsoft.Database.csproj">
......
namespace Marsonsoft.Database.MySql
{
public class Sql : SqlAnsi92
public class SqlFactory : SqlFactoryAnsi92
{
protected override string QuoteIdentifier(string identifier)
{
......
......@@ -21,7 +21,7 @@ namespace Marsonsoft.Database.Oracle
DbProviderFactory = dbProviderFactory ?? throw new ArgumentNullException(nameof(dbProviderFactory));
ConnectionProvider = connectionProvider ?? throw new ArgumentNullException(nameof(connectionProvider));
TextValidator = new OracleTextValidator();
Sql = new SqlAnsi92();
Sql = new SqlFactoryAnsi92();
}
/// <summary>
......@@ -40,8 +40,8 @@ namespace Marsonsoft.Database.Oracle
public ITextValidator TextValidator { get; private set; }
/// <summary>
/// Gets the <see cref="ISql"/> instance of this data environment.
/// Gets the <see cref="ISqlFactory"/> instance of this data environment.
/// </summary>
public ISql Sql { get; private set; }
public ISqlFactory Sql { get; private set; }
}
}
......@@ -8,11 +8,11 @@ namespace Marsonsoft.Database.Oracle
{
try
{
dataEnvironmentProvider.Add<DataEnvironment>();
dataEnvironmentProvider.Add(typeof(DataEnvironment));
}
catch (ArgumentException)
{
// Silently continue in case of previously added
// Silently continue if type has already been added.
}
}
}
......
......@@ -20,6 +20,9 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>..\..\codeAnalysis\MarsonsoftRecommended.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
<DocumentationFile>bin\Debug\Marsonsoft.Database.Oracle.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
......@@ -28,6 +31,8 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Marsonsoft.Database.Oracle.xml</DocumentationFile>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
......
......@@ -7,170 +7,170 @@ using System.Reflection;
namespace Marsonsoft.Database
{
/// <summary>
/// Provides objects implementing <see cref="IDataEnvironment"/>.
/// </summary>
public class DataEnvironmentProvider
{
private static readonly DataEnvironmentProvider defaultInstance = new DataEnvironmentProvider();
private readonly IConnectionStringInfoProvider connectionStringInfoProvider;
private readonly Dictionary<string, Type> dataEnvironmentDictionary = new Dictionary<string, Type>();
/// <summary>
/// Initializes a new instance of the <see cref="DataEnvironmentProvider"/> class.
/// </summary>
/// <param name="infoProvider">The information provider to use.</param>
/// <exception cref="System.ArgumentNullException">infoProvider</exception>
public DataEnvironmentProvider(IConnectionStringInfoProvider infoProvider)
{
connectionStringInfoProvider = infoProvider ?? throw new ArgumentNullException(nameof(infoProvider));
}
/// <summary>
/// Initializes a new instance of the <see cref="DataEnvironmentProvider"/> class using values from the configuration file.
/// </summary>
private DataEnvironmentProvider()
: this(new ConfigConnectionStringInfoProvider())
{
}
/// <summary>
/// Gets the default instance. The default instance uses values from the configuration file.
/// </summary>
public static DataEnvironmentProvider Default
{
get
{
return defaultInstance;
}
}
/// <summary>
/// Gets the connection string information provider.
/// </summary>
public IConnectionStringInfoProvider ConnsectionStringInfoProvider
{
get
{
return connectionStringInfoProvider;
}
}
public void Add<T>() where T : IDataEnvironment
{
Add(typeof(T));
}
public void Add<T>(string providerInvariantName) where T : IDataEnvironment
{
dataEnvironmentDictionary.Add(providerInvariantName, typeof(T));
}
public void Add(Type type)
{
if (!typeof(IDataEnvironment).IsAssignableFrom(type))
{
throw new ArgumentException($"Type must be assignable to {nameof(IDataEnvironment)}.", nameof(type));
}
var providerNames = GetAllProviderNamesSupportedBy(type);
foreach (var providerName in providerNames)
{
dataEnvironmentDictionary.Add(providerName, type);
}
}
public void Add(string providerInvariantName, Type type)
{
if (!typeof(IDataEnvironment).IsAssignableFrom(type))
{
throw new ArgumentException($"Type must be assignable to {nameof(IDataEnvironment)}.", nameof(type));
}
dataEnvironmentDictionary.Add(providerInvariantName, type);
}
/// <summary>
/// Gets an environment for the specified data provider and connection string.
/// </summary>
/// <param name="dataProviderName">Name of the data provider (<see cref="DbProviderFactory"/>) to use.</param>
/// <param name="connectionString">The connection string to use.</param>
/// <returns>An object implementing <see cref="IDataEnvironment"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="connectionString"/> or <paramref name="connectionString"/></exception>
public IDataEnvironment GetByConnectionSetting(string dataProviderName, string connectionString)
{
if (dataProviderName == null)
{
throw new ArgumentNullException(nameof(dataProviderName));
}
if (connectionString == null)
{
throw new ArgumentNullException(nameof(connectionString));
}
return CreateDataEnvironment(dataProviderName, connectionString);
}
/// <summary>
/// Gets the default <see cref="IDataEnvironment"/>.
/// </summary>
/// <returns>An object implementing <see cref="IDataEnvironment"/>.</returns>
/// <exception cref="InvalidOperationException">No default data provider name was found.</exception>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public IDataEnvironment GetDefault()
{
ConnectionStringInfo defaultInfo = connectionStringInfoProvider.ConnectionStringInfos.FirstOrDefault(p => p.Name == connectionStringInfoProvider.DefaultName);
string providerName = defaultInfo?.ProviderName ?? connectionStringInfoProvider.DefaultProviderName;
if (string.IsNullOrEmpty(providerName))
{
throw new InvalidOperationException("No default provider name was found.");
}
return CreateDataEnvironment(providerName, defaultInfo.ConnectionString);
}
/// <summary>
/// Gets an environment for the specified connection string name.
/// </summary>
/// <param name="name">The name of the connection string.</param>
/// <returns>An object implementing <see cref="IDataEnvironment"/>.</returns>
/// <remarks>
/// The connection string settings identified by <paramref name="name"/> will be used to set the <see cref="IDataEnvironment.DbProviderFactory"/> of the
/// resulting environment and to set the default connection string used by <see cref="IDataEnvironment.ConnectionProvider"/>.
/// </remarks>
/// <exception cref="System.ArgumentException">A connection string with the value specified in <paramref name="name"/> was not found.</exception>
public IDataEnvironment GetByConnectionStringName(string name)
{
ConnectionStringInfo info = connectionStringInfoProvider.ConnectionStringInfos.FirstOrDefault(p => p.Name == name);
if (info == null)
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "No connection string with name '{0}' found.", name));
}
return CreateDataEnvironment(info.ProviderName, info.ConnectionString);
}
private static IEnumerable<string> GetAllProviderNamesSupportedBy(Type dataEnvironmentType)
{
return
from attribute in dataEnvironmentType.GetCustomAttributes<ProviderSupportAttribute>(true)
select attribute.ProviderName;
}
private IDataEnvironment CreateDataEnvironment(string providerInvariantName, string connectionString)
{
if (!dataEnvironmentDictionary.TryGetValue(providerInvariantName, out Type dataEnvironmentType))
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "No type implementing {0} was found supporting provider '{1}'.", nameof(IDataEnvironment), providerInvariantName));
}
DbProviderFactory dbProviderFactory = DbProviderFactories.GetFactory(providerInvariantName);
IConnectionProvider connectionProvider = new ConnectionProvider(dbProviderFactory, connectionString);
return Activator.CreateInstance(dataEnvironmentType, dbProviderFactory, connectionProvider) as IDataEnvironment;
}
}
/// <summary>
/// Provides objects implementing <see cref="IDataEnvironment"/>.
/// </summary>
public class DataEnvironmentProvider
{
private static readonly DataEnvironmentProvider defaultInstance = new DataEnvironmentProvider();
private readonly IConnectionStringInfoProvider connectionStringInfoProvider;
private readonly Dictionary<string, Type> dataEnvironmentDictionary = new Dictionary<string, Type>();
/// <summary>
/// Initializes a new instance of the <see cref="DataEnvironmentProvider"/> class.
/// </summary>
/// <param name="infoProvider">The information provider to use.</param>
/// <exception cref="System.ArgumentNullException">infoProvider</exception>
public DataEnvironmentProvider(IConnectionStringInfoProvider infoProvider)
{
connectionStringInfoProvider = infoProvider ?? throw new ArgumentNullException(nameof(infoProvider));
}
/// <summary>
/// Initializes a new instance of the <see cref="DataEnvironmentProvider"/> class using values from the configuration file.
/// </summary>
private DataEnvironmentProvider()
: this(new ConfigConnectionStringInfoProvider())
{
}
/// <summary>
/// Gets the default instance. The default instance uses values from the configuration file.
/// </summary>
public static DataEnvironmentProvider Default
{
get
{
return defaultInstance;
}
}
/// <summary>
/// Gets the connection string information provider.
/// </summary>
public IConnectionStringInfoProvider ConnsectionStringInfoProvider
{
get
{
return connectionStringInfoProvider;
}
}
/// <summary>
/// Adds an environment type to the list of types provided. The <see cref="DbProviderFactory"/> types supported are
/// automatically detected by looking for the <see cref="ProviderSupportAttribute"/> attributes of the type.
/// </summary>
/// <param name="type">The environment type, implementing <see cref="IDataEnvironment"/>, that should be added.</param>
public void Add(Type type)
{
ValidateTypeToAdd(type);
var providerNames = GetAllProviderNamesSupportedBy(type);
foreach (var providerName in providerNames)
{
dataEnvironmentDictionary.Add(providerName, type);
}
}
/// <summary>
/// Adds an environment type to the list of types provided using the specified provider invariant name as an e
/// </summary>
/// <param name="providerInvariantName"></param>
/// <param name="type"></param>
public void Add(string providerInvariantName, Type type)
{
ValidateTypeToAdd(type);
dataEnvironmentDictionary.Add(providerInvariantName, type);
}
private static void ValidateTypeToAdd(Type type)
{
if (!typeof(IDataEnvironment).IsAssignableFrom(type))
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Type must be assignable to {0}.", nameof(IDataEnvironment)), nameof(type));
}
}
/// <summary>
/// Gets an environment for the specified data provider and connection string.
/// </summary>
/// <param name="dataProviderName">Name of the data provider (<see cref="DbProviderFactory"/>) to use.</param>
/// <param name="connectionString">The connection string to use.</param>
/// <returns>An object implementing <see cref="IDataEnvironment"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="connectionString"/> or <paramref name="connectionString"/></exception>
public IDataEnvironment GetByConnectionSetting(string dataProviderName, string connectionString)
{
if (dataProviderName == null)
{
throw new ArgumentNullException(nameof(dataProviderName));
}
if (connectionString == null)
{
throw new ArgumentNullException(nameof(connectionString));
}
return CreateDataEnvironment(dataProviderName, connectionString);
}
/// <summary>
/// Gets the default <see cref="IDataEnvironment"/>.
/// </summary>
/// <returns>An object implementing <see cref="IDataEnvironment"/>.</returns>
/// <exception cref="InvalidOperationException">No default data provider name was found.</exception>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public IDataEnvironment GetDefault()
{
ConnectionStringInfo defaultInfo = connectionStringInfoProvider.ConnectionStringInfos.FirstOrDefault(p => p.Name == connectionStringInfoProvider.DefaultName);
string providerName = defaultInfo?.ProviderName ?? connectionStringInfoProvider.DefaultProviderName;
if (string.IsNullOrEmpty(providerName))
{
throw new InvalidOperationException("No default provider name was found.");
}
return CreateDataEnvironment(providerName, defaultInfo.ConnectionString);
}
/// <summary>
/// Gets an environment for the specified connection string name.
/// </summary>
/// <param name="name">The name of the connection string.</param>
/// <returns>An object implementing <see cref="IDataEnvironment"/>.</returns>
/// <remarks>
/// The connection string settings identified by <paramref name="name"/> will be used to set the <see cref="IDataEnvironment.DbProviderFactory"/> of the
/// resulting environment and to set the default connection string used by <see cref="IDataEnvironment.ConnectionProvider"/>.
/// </remarks>
/// <exception cref="System.ArgumentException">A connection string with the value specified in <paramref name="name"/> was not found.</exception>
public IDataEnvironment GetByConnectionStringName(string name)
{
ConnectionStringInfo info = connectionStringInfoProvider.ConnectionStringInfos.FirstOrDefault(p => p.Name == name);
if (info == null)
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "No connection string with name '{0}' found.", name));
}
return CreateDataEnvironment(info.ProviderName, info.ConnectionString);
}
private static IEnumerable<string> GetAllProviderNamesSupportedBy(Type dataEnvironmentType)
{
return
from attribute in dataEnvironmentType.GetCustomAttributes<ProviderSupportAttribute>(true)
select attribute.ProviderName;
}
private IDataEnvironment CreateDataEnvironment(string providerInvariantName, string connectionString)
{
if (!dataEnvironmentDictionary.TryGetValue(providerInvariantName, out Type dataEnvironmentType))
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "No type implementing {0} was found supporting provider '{1}'.", nameof(IDataEnvironment), providerInvariantName));
}
DbProviderFactory dbProviderFactory = DbProviderFactories.GetFactory(providerInvariantName);
IConnectionProvider connectionProvider = new ConnectionProvider(dbProviderFactory, connectionString);
return Activator.CreateInstance(dataEnvironmentType, dbProviderFactory, connectionProvider) as IDataEnvironment;
}
}
}
......@@ -23,8 +23,8 @@ namespace Marsonsoft.Database
ITextValidator TextValidator { get; }
/// <summary>
/// Gets the <see cref="ISql"/> instance of this data environment.
/// Gets the <see cref="ISqlFactory"/> instance of this data environment.
/// </summary>
ISql Sql { get; }
ISqlFactory Sql { get; }
}
}
......@@ -3,14 +3,14 @@
/// <summary>
/// Represents the ability to create SQL elements.
/// </summary>
public interface ISql
public interface ISqlFactory
{
/// <summary>
/// Returns a valid SQL identifier from the specified argument.
/// </summary>
/// <param name="identifier">The identifier to create.</param>
/// <param name="name">The name to create an identifier from.</param>
/// <returns>A valid SQL identifier.</returns>
string Identifier(string identifier);
string Identifier(string name);
/// <summary>
/// Returns a valid SQL identifier for the specified table name.
......
......@@ -20,6 +20,9 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>..\..\codeAnalysis\MarsonsoftRecommended.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
<DocumentationFile>bin\Debug\Marsonsoft.Database.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
......@@ -28,6 +31,8 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>