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