Implemented the MySqlColumn converter and added more example code. Improved documentation. Added new DeleteAll function.
This commit is contained in:
parent
2d85bf4d62
commit
8cdcf02ab5
@ -20,18 +20,51 @@ namespace MontoyaTech.MySqlPlus.Example
|
||||
[MySqlColumn("year")]
|
||||
public uint Year = 0;
|
||||
|
||||
//[MySqlColumn("dateCreated", typeof(DateTime2UnixConverter))]
|
||||
//public DateTime DateCreated = DateTime.UtcNow;
|
||||
[MySqlColumn("dateCreated", typeof(DateTime2UnixConverter))]
|
||||
public DateTime DateCreated = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public class DateTime2UnixConverter
|
||||
public class DateTime2UnixConverter : MySqlColumnConverter
|
||||
{
|
||||
public object ConvertFrom(object input)
|
||||
{
|
||||
if (input is ulong unix)
|
||||
{
|
||||
if (unix == 0)
|
||||
return DateTime.MinValue;
|
||||
|
||||
return new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(unix).ToUniversalTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("Unsupported input object to convert from unix.");
|
||||
}
|
||||
}
|
||||
|
||||
public object ConvertTo(object input)
|
||||
{
|
||||
if (input is DateTime dateTime)
|
||||
{
|
||||
if (dateTime == DateTime.MinValue)
|
||||
return 0;
|
||||
|
||||
if (dateTime == DateTime.MaxValue)
|
||||
return ulong.MaxValue;
|
||||
|
||||
return (ulong)(dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc))).TotalSeconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("Unsupported input object to convert to unix.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var session = new MySqlSession("server=db.zone2d.com;user=root;database=zone2d;port=3306;password=-+W6!?Kv-6wDL2Vj5f=kC^Q&;SslMode=Required");
|
||||
var session = new MySqlSession("");
|
||||
|
||||
session.DeleteAll<Car>();
|
||||
|
||||
session.Insert(new Car() { Make = "Chevy", Model = "Camaro", Year = 2011 });
|
||||
|
||||
@ -40,7 +73,7 @@ namespace MontoyaTech.MySqlPlus.Example
|
||||
var cars = session.GetAll<Car>();
|
||||
|
||||
foreach (var car in cars)
|
||||
Console.WriteLine($"Make: {car.Make}, Model: {car.Model}, Year: {car.Year}");
|
||||
Console.WriteLine($"Make: {car.Make}, Model: {car.Model}, Year: {car.Year}, DateCreated: {car.DateCreated}");
|
||||
|
||||
cars[0].Make = "test";
|
||||
|
||||
|
@ -16,21 +16,52 @@ namespace MontoyaTech.MySqlPlus
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
|
||||
public class MySqlColumn : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether or not this column is the row id.
|
||||
/// </summary>
|
||||
public bool Id = false;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the column, if null, the field name will be used instead.
|
||||
/// </summary>
|
||||
public string Name = null;
|
||||
|
||||
/// <summary>
|
||||
/// An optional MySqlColumnConverter that can convert this column to another
|
||||
/// data type when needed.
|
||||
/// </summary>
|
||||
public Type Converter = null;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new default MySqlColumn.
|
||||
/// </summary>
|
||||
public MySqlColumn() { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new MySqlColumn with a name and column converter if needed.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="converter"></param>
|
||||
/// <exception cref="NotSupportedException"></exception>
|
||||
public MySqlColumn(string name, Type converter = null)
|
||||
{
|
||||
this.Name = name;
|
||||
|
||||
//Make sure the converter is valid if one was passed.
|
||||
if (converter != null && !converter.IsAssignableTo(typeof(MySqlColumnConverter)))
|
||||
throw new NotSupportedException($"Converter must inherit {nameof(MySqlColumnConverter)}");
|
||||
|
||||
this.Converter = converter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads this column from a given data reader and stores the value into the provided field on a row.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="row"></param>
|
||||
/// <param name="field"></param>
|
||||
/// <param name="reader"></param>
|
||||
/// <exception cref="NotSupportedException"></exception>
|
||||
public void ReadValue<T>(T row, FieldInfo field, MySqlDataReader reader)
|
||||
{
|
||||
//See if we can find the column index.
|
||||
@ -51,59 +82,67 @@ namespace MontoyaTech.MySqlPlus
|
||||
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)
|
||||
//See if we have a converter, use it to read the value.
|
||||
if (this.Converter != null)
|
||||
{
|
||||
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");
|
||||
field.SetValue(row, this.Converter.CreateInstance<MySqlColumnConverter>().ConvertFrom(reader.GetValue(columnIndex)));
|
||||
}
|
||||
else
|
||||
{
|
||||
//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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
29
MySqlPlus/MySqlColumnConverter.cs
Normal file
29
MySqlPlus/MySqlColumnConverter.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MontoyaTech.MySqlPlus
|
||||
{
|
||||
/// <summary>
|
||||
/// The outline of a MySqlColumnConverter that can convert a
|
||||
/// columns value from one type to another and back.
|
||||
/// </summary>
|
||||
public interface MySqlColumnConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts the input value to the desired type the database expects.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
object ConvertTo(object input);
|
||||
|
||||
/// <summary>
|
||||
/// Converts the input value from a database type to the desired type.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
object ConvertFrom(object input);
|
||||
}
|
||||
}
|
@ -60,7 +60,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
|
||||
builder.Append($"`{(string.IsNullOrWhiteSpace(column.Name) ? fields[i].Name : column.Name)}` = @{i}");
|
||||
|
||||
command.Parameters.AddWithValue($"@{i}", fields[i].GetValue(row));
|
||||
command.Parameters.AddWithValue($"@{i}", (column.Converter == null ? fields[i].GetValue(row) : column.Converter.CreateInstance<MySqlColumnConverter>().ConvertTo(fields[i].GetValue(row))));
|
||||
|
||||
seperate = true;
|
||||
}
|
||||
@ -122,7 +122,7 @@ namespace MontoyaTech.MySqlPlus
|
||||
|
||||
builder.Append($"`{(string.IsNullOrWhiteSpace(column.Name) ? fields[i].Name : column.Name)}` = @{i}");
|
||||
|
||||
command.Parameters.AddWithValue($"@{i}", fields[i].GetValue(row));
|
||||
command.Parameters.AddWithValue($"@{i}", (column.Converter == null ? fields[i].GetValue(row) : column.Converter.CreateInstance<MySqlColumnConverter>().ConvertTo(fields[i].GetValue(row))));
|
||||
|
||||
seperate = true;
|
||||
}
|
||||
@ -257,5 +257,28 @@ namespace MontoyaTech.MySqlPlus
|
||||
//Set the command text.
|
||||
command.CommandText = builder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setups this MySqlCommand to delete all rows of a given type from the db.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="command"></param>
|
||||
public static void DeleteAll<T>(this MySqlCommand command)
|
||||
{
|
||||
//Get the type of T
|
||||
var type = typeof(T);
|
||||
|
||||
//Get the row information.
|
||||
var rowAttribute = type.GetCustomAttribute<MySqlRow>();
|
||||
|
||||
//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)}`");
|
||||
|
||||
//Set the command text.
|
||||
command.CommandText = builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
|
@ -174,6 +174,21 @@ namespace MontoyaTech.MySqlPlus
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes all the rows of a given type in the db.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of row to delete.</typeparam>
|
||||
/// <returns>The number of rows affected</returns>
|
||||
public int DeleteAll<T>()
|
||||
{
|
||||
using (var command = new MySqlCommand())
|
||||
{
|
||||
command.DeleteAll<T>();
|
||||
|
||||
return this.Connection.ExecuteNonQuery(command);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicitly converts a MySqlSession to a MySqlConnection.
|
||||
/// </summary>
|
||||
|
Loading…
x
Reference in New Issue
Block a user