Simplified MySqlColumn by removing Default and Nullable. Added support for built in Nullable types. Bumped package version to 1.1.0

This commit is contained in:
MattMo 2023-02-22 08:06:42 -08:00
parent 7595acb740
commit 15e51b7a42
6 changed files with 102 additions and 49 deletions

View File

@ -10,19 +10,22 @@ namespace MontoyaTech.MySqlPlus.Example
[MySqlRowIndex("year", "year")]
public class Car
{
[MySqlColumn(Id = true, Name = "id", PrimaryKey = true, AutoIncrement = true, Nullable = false)]
[MySqlColumn(Id = true, Name = "id", PrimaryKey = true, AutoIncrement = true)]
public ulong Id = 0;
[MySqlColumn("make")]
public string Make = null;
[MySqlColumn("model", Nullable = false, Type = "VARCHAR(255)")]
[MySqlColumn("model", Type = "VARCHAR(255)")]
public string Model = "Unknown";
[MySqlColumn("year", Nullable = false)]
[MySqlColumn("year")]
public uint Year = 0;
[MySqlColumn("dateCreated", typeof(DateTimeToUnixConverter), DefaultValue = 0, Nullable = false)]
[MySqlColumn("compact")]
public bool? Compact = null;
[MySqlColumn("dateCreated", typeof(DateTimeToUnixConverter), DefaultValue = 0)]
public DateTime DateCreated = DateTime.UtcNow;
}
@ -30,18 +33,21 @@ namespace MontoyaTech.MySqlPlus.Example
{
var session = new MySqlSession("");
if (session.TableExists<Car>())
session.DeleteTable<Car>();
session.CreateTable<Car>();
session.DeleteAll<Car>();
session.Insert(new Car() { Make = "Chevy", Model = "Camaro", Year = 2011 });
session.Insert(new Car() { Make = "Chevy", Model = "Camaro", Year = 2011, Compact = true });
session.Insert(new Car() { Make = "GMC", Model = "Sierra", Year = 2000 });
var cars = session.GetAll<Car>();
foreach (var car in cars)
Console.WriteLine($"Make: {car.Make}, Model: {car.Model}, Year: {car.Year}, DateCreated: {car.DateCreated}");
Console.WriteLine($"Make: {car.Make}, Model: {car.Model}, Year: {car.Year}, Compact: {car.Compact}, DateCreated: {car.DateCreated}");
cars[0].Make = "test";

View File

@ -41,16 +41,6 @@ namespace MontoyaTech.MySqlPlus
/// </summary>
public bool AutoIncrement = false;
/// <summary>
/// Whether or not this column can be null, default is true.
/// </summary>
public bool Nullable = true;
/// <summary>
/// Whether or not this column has a default value, default is true.
/// </summary>
public bool Default = true;
/// <summary>
/// An overrided default value for this column if set, default is null.
/// </summary>

View File

@ -20,13 +20,13 @@ namespace MontoyaTech.MySqlPlus
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="row"></param>
/// <param name="idField"></param>
/// <param name="field"></param>
/// <param name="idColumn"></param>
public static bool GetMySqlId<T>(this T row, out FieldInfo idField, out MySqlColumn idColumn)
public static bool GetMySqlId<T>(this T row, out FieldInfo field, out MySqlColumn idColumn)
{
var type = typeof(T);
return GetMySqlId(type, out idField, out idColumn);
return GetMySqlId(type, out field, out idColumn);
}
/// <summary>
@ -34,12 +34,12 @@ namespace MontoyaTech.MySqlPlus
/// whether or not we found it.
/// </summary>
/// <param name="type"></param>
/// <param name="idField"></param>
/// <param name="field"></param>
/// <param name="idColumn"></param>
/// <returns></returns>
public static bool GetMySqlId(this Type type, out FieldInfo idField, out MySqlColumn idColumn)
public static bool GetMySqlId(this Type type, out FieldInfo field, out MySqlColumn idColumn)
{
idField = null;
field = null;
idColumn = null;
@ -54,7 +54,7 @@ namespace MontoyaTech.MySqlPlus
if (column != null && column.Id)
{
idField = fields[i];
field = fields[i];
idColumn = column;
return true;
@ -78,9 +78,13 @@ namespace MontoyaTech.MySqlPlus
if (column.Converter != null)
return column.Converter.CreateInstance<MySqlColumnConverter>().ConvertToType;
var code = Type.GetTypeCode(field.FieldType);
var typeCode = Type.GetTypeCode(field.FieldType);
switch (code)
//If the field type is a nullable, get the actual field type.
if (field.FieldType.IsNullable())
typeCode = Type.GetTypeCode(Nullable.GetUnderlyingType(field.FieldType));
switch (typeCode)
{
case TypeCode.Boolean:
return "BOOLEAN";
@ -125,7 +129,7 @@ namespace MontoyaTech.MySqlPlus
return "TINYINT";
default:
throw new NotSupportedException($"Unsupported column type code: {code}");
throw new NotSupportedException($"Unsupported column type code: {typeCode}");
}
}
@ -168,58 +172,97 @@ namespace MontoyaTech.MySqlPlus
//Get our field type code
var typeCode = Type.GetTypeCode(field.FieldType);
//If this field is a nullable, get the underlying type.
bool nullable = false;
if (field.FieldType.IsNullable())
{
typeCode = Type.GetTypeCode(Nullable.GetUnderlyingType(field.FieldType));
nullable = true;
}
//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>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(bool)) : reader.GetValue(columnIndex).ConvertToType<bool>());
break;
case TypeCode.Byte:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(byte) : reader.GetValue(columnIndex).ConvertToType<byte>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(byte)) : reader.GetValue(columnIndex).ConvertToType<byte>());
break;
case TypeCode.Char:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(char) : reader.GetValue(columnIndex).ConvertToType<char>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(char)) : reader.GetValue(columnIndex).ConvertToType<char>());
break;
case TypeCode.Decimal:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(decimal) : reader.GetValue(columnIndex).ConvertToType<decimal>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(decimal)) : reader.GetValue(columnIndex).ConvertToType<decimal>());
break;
case TypeCode.DateTime:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(DateTime) : reader.GetValue(columnIndex).ConvertToType<DateTime>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(DateTime)) : reader.GetValue(columnIndex).ConvertToType<DateTime>());
break;
case TypeCode.Double:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(double) : reader.GetValue(columnIndex).ConvertToType<double>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(double)) : reader.GetValue(columnIndex).ConvertToType<double>());
break;
case TypeCode.Int16:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(short) : reader.GetValue(columnIndex).ConvertToType<short>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(short)) : reader.GetValue(columnIndex).ConvertToType<short>());
break;
case TypeCode.Int32:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(int) : reader.GetValue(columnIndex).ConvertToType<int>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(int)) : reader.GetValue(columnIndex).ConvertToType<int>());
break;
case TypeCode.Int64:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(long) : reader.GetValue(columnIndex).ConvertToType<long>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(long)) : reader.GetValue(columnIndex).ConvertToType<long>());
break;
case TypeCode.SByte:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(sbyte) : reader.GetValue(columnIndex).ConvertToType<sbyte>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(sbyte)) : reader.GetValue(columnIndex).ConvertToType<sbyte>());
break;
case TypeCode.Single:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(float) : reader.GetValue(columnIndex).ConvertToType<float>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : 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>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(ushort)) : reader.GetValue(columnIndex).ConvertToType<ushort>());
break;
case TypeCode.UInt32:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(uint) : reader.GetValue(columnIndex).ConvertToType<uint>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null: default(uint)) : reader.GetValue(columnIndex).ConvertToType<uint>());
break;
case TypeCode.UInt64:
field.SetValue(row, reader.IsDBNull(columnIndex) ? default(ulong) : reader.GetValue(columnIndex).ConvertToType<ulong>());
field.SetValue(row, reader.IsDBNull(columnIndex) ? (nullable ? null : default(ulong)) : reader.GetValue(columnIndex).ConvertToType<ulong>());
break;
default:
throw new NotSupportedException("Unsupported TypeCode");
}
}
}
/// <summary>
/// Returns whether or not a MySqlColumn can be nullable or not based on the field definition and a row.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="column"></param>
/// <param name="field"></param>
/// <param name="row"></param>
/// <returns></returns>
public static bool IsNullable<T>(this MySqlColumn column, FieldInfo field, T row)
{
var fieldType = field.FieldType;
var defaultValue = field.GetValue(row);
if (column.DefaultValue != null)
defaultValue = column.DefaultValue;
if (column.Converter != null)
fieldType = column.Converter.CreateInstance<MySqlColumnConverter>().ConvertTo(defaultValue).GetType();
if (fieldType.IsNullable())
return true;
if (fieldType.IsValueType)
return false;
return true;
}
}
}

View File

@ -321,11 +321,14 @@ namespace MontoyaTech.MySqlPlus
//Write the column data type
builder.Append($"{column.GetMySqlColumnType(fields[i])} ");
//Determine if this column is nullable
bool nullable = column.IsNullable(field, row);
//Write the column null information
builder.Append($"{(column.Nullable ? "NULL" : "NOT NULL")} ");
builder.Append($"{(nullable ? "NULL" : "NOT NULL")} ");
//Write the column default value if needed. (We can't do this if the column is auto increment)
if (column.Default && !column.AutoIncrement)
if (!column.AutoIncrement)
{
var defaultValue = column.DefaultValue;
@ -333,13 +336,14 @@ namespace MontoyaTech.MySqlPlus
if (defaultValue == null)
defaultValue = field.GetValue(row);
//Quirk, don't do this if the converter is null, and the default is null, and we are nullable.
if (!(column.Converter == null && defaultValue == null && column.Nullable))
{
//If we have a converter, run the converter to get the true default value.
if (column.Converter != null)
defaultValue = column.Converter.CreateInstance<MySqlColumnConverter>().ConvertTo(defaultValue);
builder.Append($"{(column.Default ? $"DEFAULT @{i}" : "")} ");
//If we have a default value, set it on the column.
if (defaultValue != null)
{
builder.Append($"DEFAULT @{i} ");
command.Parameters.AddWithValue($"@{i}", defaultValue);
}

View File

@ -7,7 +7,7 @@
<AssemblyName>MontoyaTech.MySqlPlus</AssemblyName>
<RootNamespace>MontoyaTech.MySqlPlus</RootNamespace>
<Title>MontoyaTech.MySqlPlus</Title>
<Version>1.0.9</Version>
<Version>1.1.0</Version>
<Company>MontoyaTech</Company>
<Description>A simple C# library to help work with MySql.</Description>
<Copyright>MontoyaTech 2023</Copyright>

View File

@ -635,5 +635,15 @@ namespace MontoyaTech.MySqlPlus
}
}
}
/// <summary>
/// Returns whether or not a given type is a System Nullabe type.
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static bool IsNullable(this Type type)
{
return type.IsGenericType && type.GetGenericTypeDefinition().IsEquivalentTo(typeof(Nullable<>));
}
}
}