Skip to content

Commit

Permalink
Merge pull request #1 from aspirio187/master
Browse files Browse the repository at this point in the history
Connection support MySql database
  • Loading branch information
samadh90 authored Apr 2, 2022
2 parents 1594edf + ef86ff7 commit 07321f6
Show file tree
Hide file tree
Showing 7 changed files with 669 additions and 117 deletions.
40 changes: 39 additions & 1 deletion Connection/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,33 @@ namespace DevHopTools.Connection
{
public class Command
{
/// <summary>
/// The SQL Query or the stored procedure's name
/// </summary>
internal string Query { get; private set; }

/// <summary>
/// Boolean declaration if this <see cref="Command"/> is a Stored Procedure or not
/// </summary>
internal bool IsStoredProcedure { get; private set; }

/// <summary>
/// Dictionnary with key of type <see cref="string"/> and value of type <see cref="Parameter"/>
/// </summary>
internal IDictionary<string, Parameter> Parameters { get; private set; }

/// <summary>
/// Retrieve the Parameter based on its name
/// </summary>
/// <param name="parameterName">The parameter name from <see cref="Parameters"/></param>
/// <returns>A <see cref="Parameter"/> object from <see cref="Parameters"/> dictionnary</returns>
/// <exception cref="InvalidOperationException"></exception>
public object this[string parameterName]
{
get
{
if (!Parameters.ContainsKey(parameterName))
throw new InvalidOperationException("the key does not exist!");
throw new InvalidOperationException($"The parameter \"{parameterName}\" does not exist!");

//if(Parameters[parameterName].Direction == Direction.Input)
// throw new InvalidOperationException("the direction is Input, there no change after call the procedure!");
Expand All @@ -23,6 +40,14 @@ public object this[string parameterName]
}
}

/// <summary>
/// Create an instance of <see cref="Command"/> object
/// </summary>
/// <param name="query">The SQL Query or stored procedure's name.</param>
/// <param name="isStoredProcedure">
/// true If <paramref name="query"/> is a stored procedure. false Otherwise.
/// </param>
/// <exception cref="ArgumentException"></exception>
public Command(string query, bool isStoredProcedure = false)
{
if (string.IsNullOrWhiteSpace(query))
Expand All @@ -33,11 +58,24 @@ public Command(string query, bool isStoredProcedure = false)
Parameters = new Dictionary<string, Parameter>();
}

/// <summary>
/// Add a parameter with it's key and value in the <see cref="Parameters"/> dictionnary
/// </summary>
/// <param name="parameterName">Parameter's name for the query</param>
/// <param name="value">Parameter's value for the query</param>
public void AddParameter(string parameterName, object value)
{
AddParameter(parameterName, value, Direction.Input);
}

/// <summary>
/// Add a parameter with it's key, its value and the direction
/// </summary>
/// <param name="parameterName">Parameter key</param>
/// <param name="value">Parameter's value</param>
/// <param name="direction">SQL direction. It query is not stored procedure and direction is output,
/// an exception is thrown.</param>
/// <exception cref="ArgumentException"></exception>
public void AddParameter(string parameterName, object value, Direction direction)
{
if (string.IsNullOrWhiteSpace(parameterName))
Expand Down
200 changes: 87 additions & 113 deletions Connection/Connection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using MySqlConnector;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
Expand All @@ -7,10 +8,31 @@ namespace DevHopTools.Connection
{
public class Connection
{
/// <summary>
/// The connection string to the database
/// </summary>
private readonly string _connectionString;

/// <summary>
/// TODO : Comment correctly this property
/// </summary>
private readonly DbProviderFactory _providerFactory;

public Connection(string connectionString, DbProviderFactory providerFactory)
/// <summary>
/// Specify which type of database is used
/// </summary>
private readonly DbType _dbType;

/// <summary>
/// Create an instance of the <see cref="Connection"/> taking the <paramref name="connectionString"/>,
/// <paramref name="providerFactory"/> and <paramref name="dbType"/>
/// </summary>
/// <param name="connectionString">The complete connection string with all needed parameters</param>
/// <param name="providerFactory">The database provider factory</param>
/// <param name="dbType">The database type used</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="InvalidOperationException"></exception>
public Connection(string connectionString, DbProviderFactory providerFactory, DbType dbType)
{
if (providerFactory is null)
throw new ArgumentException("providerFactory is not valid !");
Expand All @@ -20,156 +42,108 @@ public Connection(string connectionString, DbProviderFactory providerFactory)

_connectionString = connectionString;
_providerFactory = providerFactory;
_dbType = dbType;

try
{
using (DbConnection dbConnection = CreateConnection())
switch (_dbType)
{
dbConnection.Open();
case DbType.MSSQL:
using (DbConnection dbConnection = MSSQL.CreateConnection(_connectionString, _providerFactory))
{
dbConnection.Open();
}
break;
case DbType.MySQL:
using (MySqlConnection mySqlConnection = MySql.CreateConnection(_connectionString, _providerFactory))
{
mySqlConnection.Open();
}
break;
default:
throw new InvalidOperationException($"The given database type is not in the list!");
}


}
catch (Exception)
{
throw new InvalidOperationException("the connection string is not valid or the server is down...");
}
}

/// <summary>
/// Execute a query and returns the number of row affected
/// </summary>
/// <param name="command"></param>
/// <returns>The number of row affected</returns>
/// <exception cref="InvalidOperationException"></exception>
public int ExecuteNonQuery(Command command)
{
using (DbConnection dbConnection = CreateConnection())
switch (_dbType)
{
using (DbCommand dbCommand = CreateCommand(command, dbConnection))
{
dbConnection.Open();
int rows = dbCommand.ExecuteNonQuery();

if (command.IsStoredProcedure)
FinalizeQuery(command, dbCommand);

return rows;
}
case DbType.MSSQL: return MSSQL.ExecuteNonQuery(_connectionString, _providerFactory, command);
case DbType.MySQL: return MySql.ExecuteNonQuery(_connectionString, _providerFactory, command);
default:
throw new InvalidOperationException($"Provided database type is not valid!");
}
}

/// <summary>
/// Execute a query and retrieve selected fields values from the database
/// </summary>
/// <typeparam name="TResult">The type of the object with want to retrieve</typeparam>
/// <param name="command">The SQL Command</param>
/// <param name="selector">Callback function to map the values from database to the desired type</param>
/// <returns>A <see cref="IEnumerable{T}"/> of type <typeparamref name="TResult"/></returns>
public IEnumerable<TResult> ExecuteReader<TResult>(Command command, Func<IDataRecord, TResult> selector)
{
using (DbConnection dbConnection = CreateConnection())
switch (_dbType)
{
using (DbCommand dbCommand = CreateCommand(command, dbConnection))
{
dbConnection.Open();
using (DbDataReader dataReader = dbCommand.ExecuteReader())
{
while (dataReader.Read())
{
yield return selector(dataReader);
}
}

if (command.IsStoredProcedure)
FinalizeQuery(command, dbCommand);
}
case DbType.MSSQL: return MSSQL.ExecuteReader(_connectionString, _providerFactory, command, selector);
case DbType.MySQL: return MySql.ExecuteReader(_connectionString, _providerFactory, command, selector);
default:
throw new InvalidOperationException($"Provided database type is not valid!");
}
}

/// <summary>
/// Execute query and retrieve only one field value
/// </summary>
/// <param name="command"></param>
/// <returns>The desired unique object from database</returns>
public object ExecuteScalar(Command command)
{
using (DbConnection dbConnection = CreateConnection())
switch (_dbType)
{
using (DbCommand dbCommand = CreateCommand(command, dbConnection))
{
dbConnection.Open();
object result = dbCommand.ExecuteScalar();

if (command.IsStoredProcedure)
FinalizeQuery(command, dbCommand);

return result is DBNull ? null : result;
}
case DbType.MSSQL: return MSSQL.ExecuteScalar(_connectionString, _providerFactory, command);
case DbType.MySQL: return MySql.ExecuteScalar(_connectionString, _providerFactory, command);
default:
throw new InvalidOperationException($"Provided database type is not valid!");
}
}

// TODO : Write a good complete comment
public DataTable GetDataTable(Command command)
{
using (DbConnection dbConnection = CreateConnection())
switch (_dbType)
{
using (DbCommand dbCommand = CreateCommand(command, dbConnection))
{
using (DbDataAdapter dbDataAdapter = _providerFactory.CreateDataAdapter())
{
DataTable dataTable = new DataTable();
dbDataAdapter.SelectCommand = dbCommand;
dbDataAdapter.Fill(dataTable);

if (command.IsStoredProcedure)
FinalizeQuery(command, dbCommand);

return dataTable;
}
}
case DbType.MSSQL: return MSSQL.GetDataTable(_connectionString, _providerFactory, command);
case DbType.MySQL: return MySql.GetDataTable(_connectionString, _providerFactory, command);
default:
throw new InvalidOperationException($"Provided database type is not valid!");
}
}

// TODO : Write a good complete comment
public DataSet GetDataSet(Command command)
{
using (DbConnection dbConnection = CreateConnection())
switch (_dbType)
{
using (DbCommand dbCommand = CreateCommand(command, dbConnection))
{
using (DbDataAdapter dbDataAdapter = _providerFactory.CreateDataAdapter())
{
DataSet dataSet = new DataSet();
dbDataAdapter.SelectCommand = dbCommand;
dbDataAdapter.Fill(dataSet);

if (command.IsStoredProcedure)
FinalizeQuery(command, dbCommand);

return dataSet;
}
}
}
}

private DbConnection CreateConnection()
{
DbConnection dbConnection = _providerFactory.CreateConnection();
dbConnection.ConnectionString = _connectionString;

return dbConnection;
}

private static DbCommand CreateCommand(Command command, DbConnection dbConnection)
{
DbCommand dbCommand = dbConnection.CreateCommand();
dbCommand.CommandText = command.Query;

if (command.IsStoredProcedure)
dbCommand.CommandType = CommandType.StoredProcedure;

foreach (KeyValuePair<string, Parameter> parameter in command.Parameters)
{
DbParameter dbParameter = dbCommand.CreateParameter();
dbParameter.ParameterName = parameter.Key;
dbParameter.Value = parameter.Value.ParameterValue;

if (parameter.Value.Direction == Direction.Output)
dbParameter.Direction = ParameterDirection.Output;

dbCommand.Parameters.Add(dbParameter);
}

return dbCommand;
}

private void FinalizeQuery(Command command, DbCommand dbCommand)
{
foreach (KeyValuePair<string, Parameter> parameter in command.Parameters)
{
if (parameter.Value.Direction == Direction.Output)
{
parameter.Value.ParameterValue = dbCommand.Parameters[parameter.Key].Value;
}
case DbType.MSSQL: return MSSQL.GetDataSet(_connectionString, _providerFactory, command);
case DbType.MySQL: return MySql.GetDataSet(_connectionString, _providerFactory, command);
default:
throw new InvalidOperationException($"Provided database type is not valid!");
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions Connection/DbType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace DevHopTools.Connection
{
public enum DbType
{
MSSQL,
MySQL
}
}
Loading

0 comments on commit 07321f6

Please sign in to comment.