Simplified some logic and added initial Insert, Update, Get, Delete session functions.
This commit is contained in:
parent
41cd87b2f4
commit
c7602f6b0a
@ -4,21 +4,23 @@ namespace MontoyaTech.MySqlPlus.Example
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public class Car : MySqlRow
|
||||
[MySqlRow("cars")]
|
||||
public class Car
|
||||
{
|
||||
[MySqlRowId]
|
||||
[MySqlColumn]
|
||||
[MySqlColumn(Id = true, Name = "id")]
|
||||
public ulong Id = 0;
|
||||
|
||||
[MySqlColumn("make")]
|
||||
[MySqlColumnAlias("Make")]
|
||||
public string Make = null;
|
||||
|
||||
[MySqlColumn("mode")]
|
||||
[MySqlColumn("model")]
|
||||
public string Model = null;
|
||||
|
||||
[MySqlColumn("dateCreated", typeof(DateTime2UnixConverter))]
|
||||
public DateTime DateCreated = DateTime.UtcNow;
|
||||
[MySqlColumn("year")]
|
||||
public uint Year = 0;
|
||||
|
||||
//[MySqlColumn("dateCreated", typeof(DateTime2UnixConverter))]
|
||||
//public DateTime DateCreated = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public class DateTime2UnixConverter
|
||||
@ -28,7 +30,24 @@ namespace MontoyaTech.MySqlPlus.Example
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Hello, World!");
|
||||
var session = new MySqlSession("server=db.zone2d.com;user=root;database=zone2d;port=3306;password=-+W6!?Kv-6wDL2Vj5f=kC^Q&;SslMode=Required");
|
||||
|
||||
//var car = new Car() { Make = "Chevy", Model = "Camaro" };
|
||||
|
||||
//session.Insert(car);
|
||||
|
||||
//car.Model = null;
|
||||
|
||||
//session.Update(car);
|
||||
|
||||
var car2 = session.Get<Car>(9);
|
||||
|
||||
session.Insert(car2);
|
||||
|
||||
//session.Delete(car);
|
||||
|
||||
Console.WriteLine("Done.");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Org.BouncyCastle.Asn1.X509.Qualified;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -8,15 +11,95 @@ namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
public class MySqlColumn : Attribute
|
||||
{
|
||||
public bool Id = false;
|
||||
|
||||
public string Name = null;
|
||||
|
||||
public Type Converter = null;
|
||||
|
||||
public MySqlColumn(string name = null, Type converter = null)
|
||||
public MySqlColumn() { }
|
||||
|
||||
public MySqlColumn(string name, Type converter = null)
|
||||
{
|
||||
this.Name = name;
|
||||
|
||||
this.Converter = converter;
|
||||
}
|
||||
|
||||
public void ReadValue<T>(T row, FieldInfo field, MySqlDataReader reader)
|
||||
{
|
||||
//See if we can find the column index.
|
||||
int columnIndex = -1;
|
||||
int fields = reader.FieldCount;
|
||||
for (int i = 0; i < fields; i++)
|
||||
{
|
||||
string name = reader.GetName(i);
|
||||
|
||||
if (name == this.Name || name == field.Name)
|
||||
{
|
||||
columnIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//If we didn't find the column, exit.
|
||||
if (columnIndex == -1)
|
||||
return;
|
||||
|
||||
//Get our field type code
|
||||
var typeCode = Type.GetTypeCode(field.FieldType);
|
||||
|
||||
//Read the value based on the type code.
|
||||
switch (typeCode)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(bool) : reader.GetValue(columnIndex).ConvertToType<bool>());
|
||||
break;
|
||||
case TypeCode.Byte:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(byte) : reader.GetValue(columnIndex).ConvertToType<byte>());
|
||||
break;
|
||||
case TypeCode.Char:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(char) : reader.GetValue(columnIndex).ConvertToType<char>());
|
||||
break;
|
||||
case TypeCode.Decimal:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(decimal) : reader.GetValue(columnIndex).ConvertToType<decimal>());
|
||||
break;
|
||||
case TypeCode.DateTime:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(DateTime) : reader.GetValue(columnIndex).ConvertToType<DateTime>());
|
||||
break;
|
||||
case TypeCode.Double:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(double) : reader.GetValue(columnIndex).ConvertToType<double>());
|
||||
break;
|
||||
case TypeCode.Int16:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(short) : reader.GetValue(columnIndex).ConvertToType<short>());
|
||||
break;
|
||||
case TypeCode.Int32:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(int) : reader.GetValue(columnIndex).ConvertToType<int>());
|
||||
break;
|
||||
case TypeCode.Int64:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(long) : reader.GetValue(columnIndex).ConvertToType<long>());
|
||||
break;
|
||||
case TypeCode.SByte:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(sbyte) : reader.GetValue(columnIndex).ConvertToType<sbyte>());
|
||||
break;
|
||||
case TypeCode.Single:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(float) : reader.GetValue(columnIndex).ConvertToType<float>());
|
||||
break;
|
||||
case TypeCode.String:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(string) : reader.GetValue(columnIndex).ConvertToType<string>());
|
||||
break;
|
||||
case TypeCode.UInt16:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(ushort) : reader.GetValue(columnIndex).ConvertToType<ushort>());
|
||||
break;
|
||||
case TypeCode.UInt32:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(uint) : reader.GetValue(columnIndex).ConvertToType<uint>());
|
||||
break;
|
||||
case TypeCode.UInt64:
|
||||
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(ulong) : reader.GetValue(columnIndex).ConvertToType<ulong>());
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("Unsupported TypeCode");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
public class MySqlColumnAlias : Attribute
|
||||
{
|
||||
public string Alias = null;
|
||||
|
||||
public MySqlColumnAlias(string alias)
|
||||
{
|
||||
this.Alias = alias;
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
/// <summary>
|
||||
/// The Internal MySqlConnection for this managed copy.
|
||||
/// </summary>
|
||||
public MySqlConnection Internal = null;
|
||||
public MySqlConnection MySqlConnection = null;
|
||||
|
||||
/// <summary>
|
||||
/// The connection string that is used to repoen the connection.
|
||||
@ -33,7 +33,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Internal == null || this.Internal.State != System.Data.ConnectionState.Open || !this.Internal.Ping())
|
||||
if (this.MySqlConnection == null || this.MySqlConnection.State != System.Data.ConnectionState.Open || !this.MySqlConnection.Ping())
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
@ -55,7 +55,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
if (string.IsNullOrWhiteSpace(conn.ConnectionString))
|
||||
throw new Exception("Connection string must be set on MySqlConnection.");
|
||||
|
||||
this.Internal = conn;
|
||||
this.MySqlConnection = conn;
|
||||
this.ConnectionString = conn.ConnectionString;
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
if (string.IsNullOrWhiteSpace(conn))
|
||||
throw new Exception("Invalid connection string passed, it must not be null or empty.");
|
||||
|
||||
this.Internal = new MySqlConnection(conn);
|
||||
this.MySqlConnection = new MySqlConnection(conn);
|
||||
this.ConnectionString = conn;
|
||||
}
|
||||
|
||||
@ -82,20 +82,20 @@ namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Internal == null)
|
||||
if (this.MySqlConnection == null)
|
||||
{
|
||||
Internal = new MySqlConnection(this.ConnectionString);
|
||||
this.MySqlConnection = new MySqlConnection(this.ConnectionString);
|
||||
}
|
||||
else
|
||||
{
|
||||
try { Internal.Close(); } catch { }
|
||||
try { this.MySqlConnection.Close(); } catch { }
|
||||
|
||||
try { Internal.Dispose(); } catch { }
|
||||
try { this.MySqlConnection.Dispose(); } catch { }
|
||||
|
||||
Internal = new MySqlConnection(this.ConnectionString);
|
||||
this.MySqlConnection = new MySqlConnection(this.ConnectionString);
|
||||
}
|
||||
|
||||
Internal.Open();
|
||||
this.MySqlConnection.Open();
|
||||
|
||||
//If we are now connected then stop trying.
|
||||
if (this.IsConnected)
|
||||
@ -120,22 +120,26 @@ namespace MontoyaTech.MySqlPlus
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a connection the remote server if we can.
|
||||
/// Attempts to connect to the remote MySql server.
|
||||
/// </summary>
|
||||
public void Open()
|
||||
public void Connect()
|
||||
{
|
||||
//Just invoke reconnect it handles everything for us.
|
||||
this.Reconnect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes this managed connection.
|
||||
/// Disconnects from the remote MySql server.
|
||||
/// </summary>
|
||||
public void Close()
|
||||
public void Disconnect()
|
||||
{
|
||||
if (Internal != null)
|
||||
if (this.MySqlConnection != null)
|
||||
{
|
||||
try { Internal.Close(); } catch { }
|
||||
try { this.MySqlConnection.Close(); } catch { }
|
||||
|
||||
try { this.MySqlConnection.Dispose(); } catch { }
|
||||
|
||||
this.MySqlConnection = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,7 +162,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
|
||||
try
|
||||
{
|
||||
command.Connection = this.Internal;
|
||||
command.Connection = this.MySqlConnection;
|
||||
return command.ExecuteReader();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -206,12 +210,14 @@ namespace MontoyaTech.MySqlPlus
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a mysql command without a reader.
|
||||
/// Executes a non query command.
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
/// <param name="maxRetrys"></param>
|
||||
/// <param name="exponentialBackoff"></param>
|
||||
/// <param name="retry"></param>
|
||||
/// <returns>The number of rows affected.</returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public int ExecuteNonQuery(MySqlCommand command, int maxRetrys = 5, bool exponentialBackoff = true, bool retry = true)
|
||||
{
|
||||
int backoffSleep = 2000;
|
||||
@ -223,7 +229,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
|
||||
try
|
||||
{
|
||||
command.Connection = this.Internal;
|
||||
command.Connection = this.MySqlConnection;
|
||||
|
||||
return command.ExecuteNonQuery();
|
||||
}
|
||||
@ -284,41 +290,42 @@ namespace MontoyaTech.MySqlPlus
|
||||
return false;
|
||||
else if (number == 1265)
|
||||
return false; //Data truncation (Don't try again)
|
||||
else if (number == 1264)
|
||||
return false; //Value out of range (Don't try again)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes this managed connection and releases all resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (Internal != null)
|
||||
{
|
||||
try { Internal.Close(); } catch { }
|
||||
|
||||
try { Internal.Dispose(); } catch { }
|
||||
|
||||
Internal = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when this managed connections needs to be deallocated.
|
||||
///
|
||||
/// </summary>
|
||||
~MySqlManagedConnection()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the exposal of the internal MySqlConnection from the managed version.
|
||||
/// </summary>
|
||||
/// <param name="connection"></param>
|
||||
public static implicit operator MySqlConnection(MySqlManagedConnection connection)
|
||||
{
|
||||
return connection.Internal;
|
||||
return connection.MySqlConnection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes this managed connection and releases all resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (this.MySqlConnection != null)
|
||||
{
|
||||
try { this.MySqlConnection.Close(); } catch { }
|
||||
|
||||
try { this.MySqlConnection.Dispose(); } catch { }
|
||||
|
||||
this.MySqlConnection = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up this MySqlManagedConnection when GC is collecting.
|
||||
/// </summary>
|
||||
~MySqlManagedConnection()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,15 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
public class MySqlRow
|
||||
public class MySqlRow : Attribute
|
||||
{
|
||||
public string Name;
|
||||
|
||||
public MySqlRow() { }
|
||||
|
||||
public MySqlRow(string name)
|
||||
{
|
||||
this.Name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
public class MySqlRowId : Attribute
|
||||
{
|
||||
public MySqlRowId() { }
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
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;
|
||||
|
||||
@ -20,17 +22,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Connection == null || !this.Connection.IsConnected)
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return this.Connection != null && this.Connection.IsConnected;
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,89 +32,344 @@ namespace MontoyaTech.MySqlPlus
|
||||
public MySqlManagedConnection Connection = null;
|
||||
|
||||
/// <summary>
|
||||
/// The raw connection string used to open a MySqlConnection.
|
||||
/// Creates a new default MySqlSession.
|
||||
/// </summary>
|
||||
protected string ConnectionStr = null;
|
||||
public MySqlSession() { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new MySqlSession with a connection string.
|
||||
/// </summary>
|
||||
/// <param name="connectionStr"></param>
|
||||
public MySqlSession(string connectionStr)
|
||||
/// <param name="connectionString"></param>
|
||||
public MySqlSession(string connectionString)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(this.ConnectionStr))
|
||||
throw new Exception("Must provide a valid non null or empty MySql connection string.");
|
||||
|
||||
this.ConnectionStr = connectionStr;
|
||||
this.Connection = new MySqlManagedConnection(connectionString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to connect to the MySql Server using the connection information.
|
||||
/// Creates a new MySqlSession with a given connection.
|
||||
/// </summary>
|
||||
/// <param name="connection"></param>
|
||||
public MySqlSession(MySqlManagedConnection connection)
|
||||
{
|
||||
this.Connection = connection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a new row in the db and returns it's id.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="row"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public void Connect()
|
||||
public ulong Insert<T>(T row)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
//Dont connect again if we are already connected.
|
||||
if (this.Connection == null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(this.ConnectionStr))
|
||||
{
|
||||
try
|
||||
{
|
||||
//Setup the mysql connection.
|
||||
this.Connection = new MySqlManagedConnection(this.ConnectionStr);
|
||||
var command = new MySqlCommand();
|
||||
|
||||
//Attempt to open the connection, this will make sure its valid and works for us.
|
||||
this.Connection.Open();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Failed to connect to MySql database.", ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
//Get the type of T
|
||||
var type = typeof(T);
|
||||
|
||||
//Get the row information.
|
||||
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
|
||||
|
||||
//Get all the fields.
|
||||
var fields = type.GetFields();
|
||||
|
||||
if (fields == null || fields.Length == 0)
|
||||
throw new Exception("Found no public fields on given row.");
|
||||
|
||||
//Start building the query.
|
||||
var builder = new StringBuilder();
|
||||
|
||||
//Write the insert section.
|
||||
builder.Append($"INSERT INTO `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` ");
|
||||
|
||||
//Write the set values section.
|
||||
builder.Append("SET ");
|
||||
|
||||
FieldInfo idField = null;
|
||||
bool seperate = false;
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
var column = fields[i].GetCustomAttribute<MySqlColumn>();
|
||||
|
||||
if (column == null)
|
||||
continue;
|
||||
|
||||
//Skip id columns because they are auto incremented.
|
||||
if (column.Id)
|
||||
{
|
||||
idField = fields[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (seperate)
|
||||
builder.Append(", ");
|
||||
|
||||
builder.Append($"`{(string.IsNullOrWhiteSpace(column.Name) ? fields[i].Name : column.Name)}` = @{i}");
|
||||
|
||||
command.Parameters.AddWithValue($"@{i}", fields[i].GetValue(row));
|
||||
|
||||
seperate = true;
|
||||
}
|
||||
|
||||
//Execute the insert command.
|
||||
command.CommandText = builder.ToString();
|
||||
|
||||
this.Connection.ExecuteNonQuery(command);
|
||||
|
||||
//Set the id on the row if we can.
|
||||
if (idField != null)
|
||||
{
|
||||
if (Type.GetTypeCode(idField.FieldType) == TypeCode.UInt64)
|
||||
idField.SetValue(row, (ulong)command.LastInsertedId);
|
||||
else
|
||||
idField.SetValue(row, command.LastInsertedId);
|
||||
}
|
||||
|
||||
return (ulong)command.LastInsertedId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates a row in the db.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="row"></param>
|
||||
public void Update<T>(T row)
|
||||
{
|
||||
var command = new MySqlCommand();
|
||||
|
||||
//Get the type of T
|
||||
var type = typeof(T);
|
||||
|
||||
//Get the row information.
|
||||
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
|
||||
|
||||
//Get all the fields.
|
||||
var fields = type.GetFields();
|
||||
|
||||
if (fields == null || fields.Length == 0)
|
||||
throw new Exception("Found no public fields on given row.");
|
||||
|
||||
//Start building the query.
|
||||
var builder = new StringBuilder();
|
||||
|
||||
//Write the update section
|
||||
builder.Append($"UPDATE `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` ");
|
||||
|
||||
//Write the set values section
|
||||
builder.Append("SET ");
|
||||
|
||||
FieldInfo idField = null;
|
||||
MySqlColumn idColumn = null;
|
||||
bool seperate = false;
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
var column = fields[i].GetCustomAttribute<MySqlColumn>();
|
||||
|
||||
if (column == null)
|
||||
continue;
|
||||
|
||||
//Skip id columns because they are auto incremented.
|
||||
if (column.Id)
|
||||
{
|
||||
idField = fields[i];
|
||||
idColumn = column;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (seperate)
|
||||
builder.Append(", ");
|
||||
|
||||
builder.Append($"`{(string.IsNullOrWhiteSpace(column.Name) ? fields[i].Name : column.Name)}` = @{i}");
|
||||
|
||||
command.Parameters.AddWithValue($"@{i}", fields[i].GetValue(row));
|
||||
|
||||
seperate = true;
|
||||
}
|
||||
|
||||
//Make sure we have an id column.
|
||||
if (idField == null)
|
||||
throw new Exception("Given row does not contain an id column");
|
||||
|
||||
//Write the where clause
|
||||
builder.Append($" WHERE `{(string.IsNullOrWhiteSpace(idColumn.Name) ? idField.Name : idColumn.Name)}`=@id LIMIT 1");
|
||||
|
||||
command.Parameters.AddWithValue("@id", idField.GetValue(row));
|
||||
|
||||
//Execute the command.
|
||||
command.CommandText = builder.ToString();
|
||||
|
||||
this.Connection.ExecuteNonQuery(command);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a row in the db by it's id.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public T Get<T>(ulong id)
|
||||
{
|
||||
var instance = typeof(T).ForceCreateInstanceFromType<T>();
|
||||
|
||||
this.Get<T>(instance, id);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a row in the db by it's id and populates an existing instance of the row.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="row"></param>
|
||||
/// <param name="id"></param>
|
||||
public void Get<T>(T row, ulong id)
|
||||
{
|
||||
var command = new MySqlCommand();
|
||||
|
||||
//Get the type of T
|
||||
var type = typeof(T);
|
||||
|
||||
//Get the row information.
|
||||
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
|
||||
|
||||
//Get all the fields.
|
||||
var fields = type.GetFields();
|
||||
|
||||
if (fields == null || fields.Length == 0)
|
||||
throw new Exception("Found no public fields on given row.");
|
||||
|
||||
//Find the id field
|
||||
FieldInfo idField = null;
|
||||
MySqlColumn idColumn = null;
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
var column = fields[i].GetCustomAttribute<MySqlColumn>();
|
||||
|
||||
if (column != null && column.Id)
|
||||
{
|
||||
idField = fields[i];
|
||||
idColumn = column;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Make sure we have an id field.
|
||||
if (idField == null)
|
||||
throw new Exception("Failed to find id column for row.");
|
||||
|
||||
command.CommandText = $"SELECT * FROM `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` WHERE `{(string.IsNullOrWhiteSpace(idColumn.Name) ? idField.Name : idColumn.Name)}`=@id LIMIT 1";
|
||||
command.Parameters.AddWithValue("@id", id);
|
||||
|
||||
using (var reader = this.Connection.ExecuteReader(command))
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
throw new Exception("Missing connection details to connect to MySql database.");
|
||||
var column = fields[i].GetCustomAttribute<MySqlColumn>();
|
||||
|
||||
if (column == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (column.Id)
|
||||
{
|
||||
if (Type.GetTypeCode(fields[i].FieldType) == TypeCode.UInt64)
|
||||
fields[i].SetValue(row, (ulong)id);
|
||||
else
|
||||
fields[i].SetValue(row, (long)id);
|
||||
}
|
||||
else
|
||||
{
|
||||
column.ReadValue(row, fields[i], reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disconnects from the MySql Server this Session is connected to.
|
||||
/// Deletes a row in the db.
|
||||
/// </summary>
|
||||
public void Disconnect()
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="row"></param>
|
||||
public void Delete<T>(T row)
|
||||
{
|
||||
lock (this)
|
||||
var command = new MySqlCommand();
|
||||
|
||||
//Get the type of T
|
||||
var type = typeof(T);
|
||||
|
||||
//Get the row information.
|
||||
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
|
||||
|
||||
//Get all the fields.
|
||||
var fields = type.GetFields();
|
||||
|
||||
if (fields == null || fields.Length == 0)
|
||||
throw new Exception("Found no public fields on given row.");
|
||||
|
||||
//Start building the query.
|
||||
var builder = new StringBuilder();
|
||||
|
||||
//Write the delete from section
|
||||
builder.Append($"DELETE FROM `{(rowAttribute == null || string.IsNullOrWhiteSpace(rowAttribute.Name) ? type.Name : rowAttribute.Name)}` ");
|
||||
|
||||
//Find the id column.
|
||||
FieldInfo idField = null;
|
||||
MySqlColumn idColumn = null;
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.Connection != null)
|
||||
{
|
||||
try { this.Connection.Close(); } catch { }
|
||||
var column = fields[i].GetCustomAttribute<MySqlColumn>();
|
||||
|
||||
try { this.Connection.Dispose(); } catch { }
|
||||
|
||||
this.Connection = null;
|
||||
}
|
||||
}
|
||||
catch
|
||||
if (column != null && column.Id)
|
||||
{
|
||||
this.Connection = null;
|
||||
idField = fields[i];
|
||||
idColumn = column;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Make sure we found the id
|
||||
if (idField == null)
|
||||
throw new Exception("Failed to find id column for row.");
|
||||
|
||||
//Write the where clause
|
||||
builder.Append($"WHERE `{(string.IsNullOrWhiteSpace(idColumn.Name) ? idField.Name : idColumn.Name)}`=@id LIMIT 1");
|
||||
|
||||
command.Parameters.AddWithValue("@id", idField.GetValue(row));
|
||||
|
||||
command.CommandText = builder.ToString();
|
||||
|
||||
this.Connection.ExecuteNonQuery(command);
|
||||
}
|
||||
|
||||
~MySqlSession()
|
||||
/// <summary>
|
||||
/// Implicitly converts a MySqlSession to a MySqlConnection.
|
||||
/// </summary>
|
||||
/// <param name="session"></param>
|
||||
public static implicit operator MySqlConnection(MySqlSession session)
|
||||
{
|
||||
this.Disconnect();
|
||||
return session.Connection.MySqlConnection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes this MySqlSession.
|
||||
/// </summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
this.Disconnect();
|
||||
if (this.Connection != null)
|
||||
this.Connection.Disconnect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up this MySqlSession before GC collection.
|
||||
/// </summary>
|
||||
~MySqlSession()
|
||||
{
|
||||
if (this.Connection != null)
|
||||
this.Connection.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
/// <summary>
|
||||
/// Creates a new default CachedAPISession.
|
||||
/// </summary>
|
||||
public CachedMySqlSession(string connectionStr) : base(connectionStr)
|
||||
public CachedMySqlSession(string connectionString) : base(connectionString)
|
||||
{
|
||||
this.Id = Guid.NewGuid().ToString();
|
||||
}
|
||||
@ -68,7 +68,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
/// <summary>
|
||||
/// The connection string to use when creating MySqlSessions.
|
||||
/// </summary>
|
||||
private static string ConnectionStr = null;
|
||||
private static string ConnectionString = null;
|
||||
|
||||
/// <summary>
|
||||
/// The list of Cached Sessions currently being maintained by the Cache.
|
||||
@ -107,7 +107,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
/// <param name="connectionStr"></param>
|
||||
public static void Start(string connectionStr)
|
||||
{
|
||||
ConnectionStr = connectionStr;
|
||||
ConnectionString = connectionStr;
|
||||
|
||||
lock (Sessions)
|
||||
{
|
||||
@ -115,6 +115,9 @@ namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
Running = true;
|
||||
|
||||
if (Sessions == null)
|
||||
Sessions = new List<CachedMySqlSession>();
|
||||
|
||||
UnCacheThread = new Thread(UnCache);
|
||||
UnCacheThread.IsBackground = true;
|
||||
UnCacheThread.Start();
|
||||
@ -136,9 +139,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < Sessions.Count; i++)
|
||||
{
|
||||
Sessions[i].Disconnect();
|
||||
}
|
||||
Sessions[i].Dispose();
|
||||
}
|
||||
catch { }
|
||||
|
||||
@ -156,23 +157,26 @@ namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
lock (Sessions)
|
||||
{
|
||||
for (int i = 0; i < Sessions.Count; i++)
|
||||
if (Sessions != null)
|
||||
{
|
||||
var session = Sessions[i];
|
||||
|
||||
//Remove the sessions not in use and the ones who are zombies.
|
||||
|
||||
if (session.InUse == false)
|
||||
for (int i = 0; i < Sessions.Count; i++)
|
||||
{
|
||||
Sessions.RemoveAt(i);
|
||||
session.Disconnect();
|
||||
i--;
|
||||
}
|
||||
else if (session.InUse && (DateTime.UtcNow - session.LastUse).Minutes >= ZombieCacheLifeTime)
|
||||
{
|
||||
Sessions.RemoveAt(i);
|
||||
session.Disconnect();
|
||||
i--;
|
||||
var session = Sessions[i];
|
||||
|
||||
//Remove the sessions not in use and the ones who are zombies.
|
||||
|
||||
if (session.InUse == false)
|
||||
{
|
||||
Sessions.RemoveAt(i);
|
||||
session.Dispose();
|
||||
i--;
|
||||
}
|
||||
else if (session.InUse && (DateTime.UtcNow - session.LastUse).Minutes >= ZombieCacheLifeTime)
|
||||
{
|
||||
Sessions.RemoveAt(i);
|
||||
session.Dispose();
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,9 +208,12 @@ namespace MontoyaTech.MySqlPlus
|
||||
//Create a new Session if we didnt find one.
|
||||
if (result == null)
|
||||
{
|
||||
result = new CachedMySqlSession(ConnectionStr);
|
||||
result.Connect();
|
||||
Sessions.Add(result);
|
||||
result = new CachedMySqlSession(ConnectionString);
|
||||
|
||||
if (Sessions == null)
|
||||
Sessions = new List<CachedMySqlSession>() { result };
|
||||
else
|
||||
Sessions.Add(result);
|
||||
}
|
||||
|
||||
result.InUse = true;
|
||||
@ -236,23 +243,26 @@ namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
lock (Sessions)
|
||||
{
|
||||
for (int i = 0; i < Sessions.Count; i++)
|
||||
if (Sessions != null)
|
||||
{
|
||||
var session = Sessions[i];
|
||||
for (int i = 0; i < Sessions.Count; i++)
|
||||
{
|
||||
var session = Sessions[i];
|
||||
|
||||
//If this session is older than it's lifetime and it's not in use, kill it.
|
||||
if (session.InUse == false && (DateTime.UtcNow - session.LastUse).Minutes >= CacheLifeTime)
|
||||
{
|
||||
Sessions.RemoveAt(i);
|
||||
session.Disconnect();
|
||||
i--;
|
||||
}
|
||||
//If this session is in use but it appears to be a zombie session, kill it.
|
||||
else if (session.InUse && (DateTime.UtcNow - session.LastUse).Minutes >= ZombieCacheLifeTime)
|
||||
{
|
||||
Sessions.RemoveAt(i);
|
||||
session.Disconnect();
|
||||
i--;
|
||||
//If this session is older than it's lifetime and it's not in use, kill it.
|
||||
if (session.InUse == false && (DateTime.UtcNow - session.LastUse).Minutes >= CacheLifeTime)
|
||||
{
|
||||
Sessions.RemoveAt(i);
|
||||
session.Dispose();
|
||||
i--;
|
||||
}
|
||||
//If this session is in use but it appears to be a zombie session, kill it.
|
||||
else if (session.InUse && (DateTime.UtcNow - session.LastUse).Minutes >= ZombieCacheLifeTime)
|
||||
{
|
||||
Sessions.RemoveAt(i);
|
||||
session.Dispose();
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
625
MySqlPlus/TypeExentions.cs
Normal file
625
MySqlPlus/TypeExentions.cs
Normal file
@ -0,0 +1,625 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
/// <summary>
|
||||
/// A set of extensions to help work with Types.
|
||||
/// </summary>
|
||||
internal static class TypeExentions
|
||||
{
|
||||
public static T ForceCreateInstanceFromType<T>(this Type type)
|
||||
{
|
||||
if (type == null)
|
||||
return default;
|
||||
|
||||
//See if we can create an instance of the type the easy way.
|
||||
try { return (T)Activator.CreateInstance(type); }
|
||||
catch { }
|
||||
|
||||
//See if we can force create the type..
|
||||
try { return (T)System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type); }
|
||||
catch { }
|
||||
|
||||
//If that failed, then this might be an array, so try again.
|
||||
try { return (T)Activator.CreateInstance(type, 0); }
|
||||
catch { }
|
||||
|
||||
//If we get here it means we couldn't create an instance so return null.
|
||||
return default;
|
||||
}
|
||||
|
||||
public static T ConvertToType<T>(this object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return default(T);
|
||||
|
||||
var target = Type.GetTypeCode(typeof(T));
|
||||
|
||||
var current = Type.GetTypeCode(obj.GetType());
|
||||
|
||||
if (target == current)
|
||||
{
|
||||
return (T)obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (target)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)((byte)obj != 0 ? true : false);
|
||||
case TypeCode.Char:
|
||||
return (T)(object)((char)obj != 'f' && (char)obj != 'F' && (char)obj != '0' ? true : false);
|
||||
case TypeCode.Decimal:
|
||||
return (T)(object)((decimal)obj > 0 ? true : false);
|
||||
case TypeCode.Double:
|
||||
return (T)(object)((double)obj > 0 ? true : false);
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)((short)obj > 0 ? true : false);
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)((int)obj > 0 ? true : false);
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)((long)obj > 0 ? true : false);
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)((sbyte)obj > 0 ? true : false);
|
||||
case TypeCode.Single:
|
||||
return (T)(object)((float)obj > 0 ? true : false);
|
||||
case TypeCode.String:
|
||||
{
|
||||
var str = ((string)obj).ToLower().Trim();
|
||||
|
||||
if (str == "t" || str == "1" || str == "true" || str == "yes" || str == "y")
|
||||
return (T)(object)true;
|
||||
else
|
||||
return (T)(object)false;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)((ushort)obj > 0 ? true : false);
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)((uint)obj > 0 ? true : false);
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)((ulong)obj > 0 ? true : false);
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)false;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.Byte:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? 1 : 0);
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(byte)(char)obj;
|
||||
case TypeCode.Decimal:
|
||||
return (T)(object)(byte)(decimal)obj;
|
||||
case TypeCode.Double:
|
||||
return (T)(object)(byte)(double)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(byte)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(byte)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(byte)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(byte)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(byte)(float)obj;
|
||||
case TypeCode.String:
|
||||
{
|
||||
if (byte.TryParse((string)obj, out byte result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return (T)(object)0;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(byte)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(byte)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(byte)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)0;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.Char:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? '1' : '0');
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)(char)(byte)obj;
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(char)(char)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(char)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(char)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(char)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(char)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(char)(float)obj;
|
||||
case TypeCode.Double:
|
||||
return (T)(object)(char)(double)obj;
|
||||
case TypeCode.String:
|
||||
return (T)(object)((string)obj)[0];
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(char)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(char)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(char)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return default(T);
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.DateTime:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.String:
|
||||
if (DateTime.TryParse((string)obj, out DateTime result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return default(T);
|
||||
default:
|
||||
return default(T);
|
||||
}
|
||||
case TypeCode.DBNull:
|
||||
return default(T);
|
||||
case TypeCode.Decimal:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? 1 : 0);
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)(decimal)(byte)obj;
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(decimal)(char)obj;
|
||||
case TypeCode.Double:
|
||||
return (T)(object)(decimal)(double)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(decimal)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(decimal)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(decimal)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(decimal)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(decimal)(float)obj;
|
||||
case TypeCode.String:
|
||||
{
|
||||
if (decimal.TryParse((string)obj, out decimal result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return (T)(object)0;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(decimal)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(decimal)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(decimal)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)0;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.Double:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? 1 : 0);
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)(double)(byte)obj;
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(double)(char)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(double)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(double)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(double)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(double)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(double)(float)obj;
|
||||
case TypeCode.String:
|
||||
{
|
||||
if (double.TryParse((string)obj, out double result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return (T)(object)0;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(double)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(double)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(double)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)0;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.Empty:
|
||||
return default(T);
|
||||
case TypeCode.Int16:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? 1 : 0);
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)(short)(byte)obj;
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(short)(char)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(short)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(short)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(short)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(short)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(short)(float)obj;
|
||||
case TypeCode.Double:
|
||||
return (T)(object)(short)(double)obj;
|
||||
case TypeCode.String:
|
||||
{
|
||||
if (short.TryParse((string)obj, out short result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return (T)(object)0;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(short)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(short)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(short)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)0;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.Int32:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? 1 : 0);
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)(int)(byte)obj;
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(int)(char)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(int)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(int)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(int)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(int)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(int)(float)obj;
|
||||
case TypeCode.Double:
|
||||
return (T)(object)(int)(double)obj;
|
||||
case TypeCode.String:
|
||||
{
|
||||
if (int.TryParse((string)obj, out int result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return (T)(object)0;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(int)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(int)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(int)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)0;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.Int64:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? 1 : 0);
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)(long)(byte)obj;
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(long)(char)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(long)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(long)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(long)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(long)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(long)(float)obj;
|
||||
case TypeCode.Double:
|
||||
return (T)(object)(long)(double)obj;
|
||||
case TypeCode.String:
|
||||
{
|
||||
if (long.TryParse((string)obj, out long result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return (T)(object)0;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(long)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(long)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(long)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)0;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.Object:
|
||||
return (T)obj;
|
||||
case TypeCode.SByte:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? 1 : 0);
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)(sbyte)(byte)obj;
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(sbyte)(char)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(sbyte)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(sbyte)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(sbyte)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(sbyte)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(sbyte)(float)obj;
|
||||
case TypeCode.Double:
|
||||
return (T)(object)(sbyte)(double)obj;
|
||||
case TypeCode.String:
|
||||
{
|
||||
if (sbyte.TryParse((string)obj, out sbyte result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return (T)(object)0;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(sbyte)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(sbyte)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(sbyte)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)0;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.Single:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? 1 : 0);
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)(float)(byte)obj;
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(float)(char)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(float)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(float)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(float)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(float)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(float)(float)obj;
|
||||
case TypeCode.Double:
|
||||
return (T)(object)(float)(double)obj;
|
||||
case TypeCode.String:
|
||||
{
|
||||
if (float.TryParse((string)obj, out float result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return (T)(object)0;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(float)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(float)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(float)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)0;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.String:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DBNull:
|
||||
return default(T);
|
||||
default:
|
||||
return (T)(object)obj.ToString();
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? 1 : 0);
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)(ushort)(byte)obj;
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(ushort)(char)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(ushort)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(ushort)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(ushort)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(ushort)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(ushort)(float)obj;
|
||||
case TypeCode.Double:
|
||||
return (T)(object)(ushort)(double)obj;
|
||||
case TypeCode.String:
|
||||
{
|
||||
if (ushort.TryParse((string)obj, out ushort result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return (T)(object)0;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(ushort)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(ushort)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(ushort)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)0;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.UInt32:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? 1 : 0);
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)(uint)(byte)obj;
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(uint)(char)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(uint)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(uint)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(uint)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(uint)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(uint)(float)obj;
|
||||
case TypeCode.Double:
|
||||
return (T)(object)(uint)(double)obj;
|
||||
case TypeCode.String:
|
||||
{
|
||||
if (uint.TryParse((string)obj, out uint result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return (T)(object)0;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(uint)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(uint)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(uint)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)0;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
case TypeCode.UInt64:
|
||||
switch (current)
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
return (T)(object)((bool)obj == true ? 1 : 0);
|
||||
case TypeCode.Byte:
|
||||
return (T)(object)(ulong)(byte)obj;
|
||||
case TypeCode.Char:
|
||||
return (T)(object)(ulong)(char)obj;
|
||||
case TypeCode.Int16:
|
||||
return (T)(object)(ulong)(short)obj;
|
||||
case TypeCode.Int32:
|
||||
return (T)(object)(ulong)(int)obj;
|
||||
case TypeCode.Int64:
|
||||
return (T)(object)(ulong)(long)obj;
|
||||
case TypeCode.SByte:
|
||||
return (T)(object)(ulong)(sbyte)obj;
|
||||
case TypeCode.Single:
|
||||
return (T)(object)(ulong)(float)obj;
|
||||
case TypeCode.Double:
|
||||
return (T)(object)(ulong)(double)obj;
|
||||
case TypeCode.String:
|
||||
{
|
||||
if (ulong.TryParse((string)obj, out ulong result))
|
||||
return (T)(object)result;
|
||||
else
|
||||
return (T)(object)0;
|
||||
}
|
||||
case TypeCode.UInt16:
|
||||
return (T)(object)(ulong)(ushort)obj;
|
||||
case TypeCode.UInt32:
|
||||
return (T)(object)(ulong)(uint)obj;
|
||||
case TypeCode.UInt64:
|
||||
return (T)(object)(ulong)(ulong)obj;
|
||||
case TypeCode.Object:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DateTime:
|
||||
return (T)(object)0;
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported current typecode: {current}");
|
||||
}
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported target typecode: {target}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user