using Microsoft.VisualBasic;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace MontoyaTech.MySqlPlus
{
///
/// The outline of a MySqlSession which contains a MySqlManagedConnection
/// and a few other help functions.
///
public class MySqlSession : IDisposable
{
///
/// Returns whether or not this MySqlSession has a valid connection.
///
public bool IsConnected
{
get
{
return this.Connection != null && this.Connection.IsConnected;
}
}
///
/// The underlying MySql Connection that this Session is using.
///
public MySqlManagedConnection Connection = null;
///
/// Creates a new default MySqlSession.
///
public MySqlSession() { }
///
/// Creates a new MySqlSession with a connection string.
///
///
public MySqlSession(string connectionString)
{
this.Connection = new MySqlManagedConnection(connectionString);
}
///
/// Creates a new MySqlSession with a given connection.
///
///
public MySqlSession(MySqlManagedConnection connection)
{
this.Connection = connection;
}
///
/// Inserts a new row in the db and returns it's id.
///
///
///
///
///
public ulong Insert(T row)
{
using (var command = new MySqlCommand())
{
command.Insert(row);
this.Connection.ExecuteNonQuery(command);
//Update the primary key value on the row if it auto increments.
if (row.GetMySqlPrimaryKey(out FieldInfo primaryField, out MySqlColumn primaryColumn))
{
if (primaryColumn.AutoIncrement)
{
if (Type.GetTypeCode(primaryField.FieldType) == TypeCode.UInt64)
primaryField.SetValue(row, (ulong)command.LastInsertedId);
else
primaryField.SetValue(row, command.LastInsertedId);
}
}
return (ulong)command.LastInsertedId;
}
}
///
/// Updates a row in the db.
///
///
///
public void Update(T row)
{
using (var command = new MySqlCommand())
{
command.Update(row);
this.Connection.ExecuteNonQuery(command);
}
}
///
/// Gets a row in the db by it's id.
///
///
///
///
public T Get(ulong id)
{
var instance = typeof(T).CreateInstance();
this.Get(instance, id);
return instance;
}
///
/// Gets a row in the db by it's id.
///
///
///
///
public T Get(string id)
{
var instance = typeof(T).CreateInstance();
this.Get(instance, id);
return instance;
}
///
/// Gets a row in the db by it's id and populates an existing instance of the row.
///
///
///
///
public void Get(T row, ulong id)
{
using (var command = new MySqlCommand())
{
command.Get(id);
using (var reader = this.Connection.ExecuteReader(command))
reader.Read(row);
}
}
///
/// Gets a row in the db by it's id and populates an existing instance of the row.
///
///
///
///
public void Get(T row, string id)
{
using (var command = new MySqlCommand())
{
command.Get(id);
using (var reader = this.Connection.ExecuteReader(command))
reader.Read(row);
}
}
///
/// Gets all the rows of a given type in the db.
///
///
///
public List GetAll()
{
using (var command = new MySqlCommand())
{
command.GetAll();
using (var reader = this.Connection.ExecuteReader(command))
return reader.ReadAll();
}
}
///
/// Returns whether or not a row of a given type exists by id in the db.
///
///
///
///
public bool Exists(ulong id)
{
using (var command = new MySqlCommand())
{
command.Exists(id);
using (var reader = this.Connection.ExecuteReader(command))
if (reader.Read())
return reader.GetBoolean(0);
}
return false;
}
///
/// Returns whether or not a row of a given type exists by id in the db.
///
///
///
///
public bool Exists(string id)
{
using (var command = new MySqlCommand())
{
command.Exists(id);
using (var reader = this.Connection.ExecuteReader(command))
if (reader.Read())
return reader.GetBoolean(0);
}
return false;
}
///
/// Deletes a row in the db.
///
///
///
public void Delete(T row)
{
using (var command = new MySqlCommand())
{
command.Delete(row);
this.Connection.ExecuteNonQuery(command);
}
}
///
/// Deletes a row in the db by it's id.
///
///
///
public void Delete(ulong id)
{
using (var command = new MySqlCommand())
{
command.Delete(id);
this.Connection.ExecuteNonQuery(command);
}
}
///
/// Deletes a row in the db by it's id.
///
///
///
public void Delete(string id)
{
using (var command = new MySqlCommand())
{
command.Delete(id);
this.Connection.ExecuteNonQuery(command);
}
}
///
/// Deletes all the rows of a given type in the db.
///
/// The type of row to delete.
/// The number of rows affected
public int DeleteAll()
{
using (var command = new MySqlCommand())
{
command.DeleteAll();
return this.Connection.ExecuteNonQuery(command);
}
}
///
/// Creates a new table in the db of a given row type.
///
///
public void CreateTable()
{
using (var command = new MySqlCommand())
{
command.CreateTable();
this.Connection.ExecuteNonQuery(command);
}
}
///
/// Returns whether or not a table exists in the db of a given row type.
///
///
///
public bool TableExists()
{
using (var command = new MySqlCommand())
{
command.TableExists();
using (var reader = this.Connection.ExecuteReader(command))
return reader.Read();
}
}
///
/// Emptys a table in the db for a given row type.
///
///
public void EmptyTable()
{
using (var command = new MySqlCommand())
{
command.EmptyTable();
this.Connection.ExecuteNonQuery(command);
}
}
///
/// Deletes a table in the db for a given row type.
///
///
public void DeleteTable()
{
using (var command = new MySqlCommand())
{
command.DeleteTable();
this.Connection.ExecuteNonQuery(command);
}
}
///
/// Returns the name of the table for a given row type.
///
///
///
public string GetTable()
{
return MySqlRow.GetName();
}
///
/// Executes a data reader for a command and retrys if the database goes away or glitches.
///
/// The MySqlCommand to execute.
/// The max number of times to retry, default is 5.
/// Whether or not to backoff longer each fail, default is true.
/// Whether or not to retry if the command fails, default is true.
/// The MySqlDataReader from running the command.
public MySqlDataReader ExecuteReader(MySqlCommand command, int maxRetrys = 5, bool exponentialBackoff = true, bool retry = true)
{
return this.Connection.ExecuteReader(command, maxRetrys, exponentialBackoff, retry);
}
///
/// Executes a non query command and retrys if the database goes away or glitches.
///
/// The MySqlCommand to execute.
/// The max number of times to retry, default is 5.
/// Whether or not to backoff longer each fail, default is true.
/// Whether or not to retry if the command fails, default is true.
/// The number of rows affected.
///
public int ExecuteNonQuery(MySqlCommand command, int maxRetrys = 5, bool exponentialBackoff = true, bool retry = true)
{
return this.Connection.ExecuteNonQuery(command, maxRetrys, exponentialBackoff, retry);
}
///
/// Implicitly converts a MySqlSession to a MySqlConnection.
///
///
public static implicit operator MySqlConnection(MySqlSession session)
{
return session.Connection.MySqlConnection;
}
///
/// Disposes this MySqlSession.
///
public virtual void Dispose()
{
if (this.Connection != null)
this.Connection.Disconnect();
}
///
/// Cleans up this MySqlSession before GC collection.
///
~MySqlSession()
{
if (this.Connection != null)
this.Connection.Disconnect();
}
}
}