Skip to content
Permalink
Browse files

Merge pull request #530 from asherber/consolidate-mapper-methods

Refactor to get rid of duplicate TableInfo/ColumnInfo code
  • Loading branch information...
pleb committed May 14, 2019
2 parents ec276ad + ce03489 commit d0a08baa05be8e340dd35df8f7a8caef955e0d1b
Showing with 88 additions and 105 deletions.
  1. +29 −31 PetaPoco/Core/ColumnInfo.cs
  2. +26 −50 PetaPoco/Core/ConventionMapper.cs
  3. +33 −24 PetaPoco/Core/TableInfo.cs
@@ -1,4 +1,6 @@
using System.Reflection;
using System;
using System.Linq;
using System.Reflection;

namespace PetaPoco
{
@@ -49,49 +51,45 @@ public class ColumnInfo
/// </summary>
public string UpdateTemplate { get; set; }

/// <summary>
/// Creates and populates a ColumnInfo from the attributes of a POCO property.
/// </summary>
/// <param name="propertyInfo">The property whose column info is required</param>
/// <returns>A ColumnInfo instance</returns>
public static ColumnInfo FromProperty(PropertyInfo propertyInfo)
internal static void PopulateFromProperty(PropertyInfo pi, ref ColumnInfo ci, out ColumnAttribute columnAttr)
{
// Check if declaring poco has [Explicit] attribute
var explicitColumns = propertyInfo.DeclaringType.GetCustomAttributes(typeof(ExplicitColumnsAttribute), true).Length > 0;
var isExplicit = pi.DeclaringType.GetCustomAttributes(typeof(ExplicitColumnsAttribute), true).Any();

// Check for [Column]/[Ignore] Attributes
var colAttrs = propertyInfo.GetCustomAttributes(typeof(ColumnAttribute), true);
if (explicitColumns)
columnAttr = pi.GetCustomAttributes(typeof(ColumnAttribute), true).FirstOrDefault() as ColumnAttribute;
var isIgnore = pi.GetCustomAttributes(typeof(IgnoreAttribute), true).Any();

if (isIgnore || (isExplicit && columnAttr == null))
{
if (colAttrs.Length == 0)
return null;
ci = null;
}
else
{
if (propertyInfo.GetCustomAttributes(typeof(IgnoreAttribute), true).Length != 0)
return null;
}
ci = ci ?? new ColumnInfo();

var ci = new ColumnInfo();
ci.ColumnName = columnAttr?.Name ?? pi.Name;
ci.ForceToUtc = columnAttr?.ForceToUtc == true;
ci.InsertTemplate = columnAttr?.InsertTemplate;
ci.UpdateTemplate = columnAttr?.UpdateTemplate;

// Read attribute
if (colAttrs.Length > 0)
{
var colattr = (ColumnAttribute) colAttrs[0];
ci.InsertTemplate = colattr.InsertTemplate;
ci.UpdateTemplate = colattr.UpdateTemplate;
ci.ColumnName = colattr.Name ?? propertyInfo.Name;
ci.ForceToUtc = colattr.ForceToUtc;
if ((colattr as ResultColumnAttribute) != null)
if (columnAttr is ResultColumnAttribute resAttr)
{
ci.ResultColumn = true;
ci.AutoSelectedResultColumn = resAttr.IncludeInAutoSelect == IncludeInAutoSelect.Yes;
}
}
else
{
ci.ColumnName = propertyInfo.Name;
ci.ForceToUtc = false;
ci.ResultColumn = false;
}
}

/// <summary>
/// Creates and populates a ColumnInfo from the attributes of a POCO property.
/// </summary>
/// <param name="propertyInfo">The property whose column info is required</param>
/// <returns>A ColumnInfo instance</returns>
public static ColumnInfo FromProperty(PropertyInfo propertyInfo)
{
var ci = new ColumnInfo();
PopulateFromProperty(propertyInfo, ref ci, out _);
return ci;
}
}
@@ -69,40 +69,31 @@ public ConventionMapper()
InflectTableName = (inflect, tn) => tn;
MapPrimaryKey = (ti, t) =>
{
var primaryKey = t.GetCustomAttributes(typeof(PrimaryKeyAttribute), true).FirstOrDefault() as PrimaryKeyAttribute;
TableInfo.PopulatePrimaryKeyFromPoco(t, ref ti, out var pkAttr, out var idProp);

if (primaryKey != null)
if (pkAttr == null && idProp == null)
return false;
else
{
ti.PrimaryKey = primaryKey.Value;
ti.SequenceName = primaryKey.SequenceName;
ti.AutoIncrement = primaryKey.AutoIncrement;
// If there's no pkAttr, then there's extra processing
if (pkAttr == null)
{
ti.PrimaryKey = InflectColumnName(Inflector.Instance, idProp.Name);
ti.AutoIncrement = IsPrimaryKeyAutoIncrement(idProp.PropertyType);
ti.SequenceName = GetSequenceName(t, idProp);
}

return true;
}

var prop = t.GetProperties().FirstOrDefault(p =>
{
if (p.Name.Equals("Id", StringComparison.OrdinalIgnoreCase))
return true;
if (p.Name.Equals(t.Name + "Id", StringComparison.OrdinalIgnoreCase))
return true;
if (p.Name.Equals(t.Name + "_Id", StringComparison.OrdinalIgnoreCase))
return true;
return false;
});

if (prop == null)
return false;

ti.PrimaryKey = InflectColumnName(Inflector.Instance, prop.Name);
ti.AutoIncrement = IsPrimaryKeyAutoIncrement(prop.PropertyType);
ti.SequenceName = GetSequenceName(t, prop);
return true;
};
MapTable = (ti, t) =>
{
var tableName = t.GetCustomAttributes(typeof(TableNameAttribute), true).FirstOrDefault() as TableNameAttribute;
ti.TableName = tableName != null ? tableName.Value : InflectTableName(Inflector.Instance, t.Name);
TableInfo.PopulateTableNameFromPoco(t, ref ti, out var tblAttr);
if (tblAttr == null)
ti.TableName = InflectTableName(Inflector.Instance, t.Name);

MapPrimaryKey(ti, t);

return true;
};
IsPrimaryKeyAutoIncrement = t =>
@@ -121,34 +112,19 @@ public ConventionMapper()
};
MapColumn = (ci, t, pi) =>
{
// Check if declaring poco has [Explicit] attribute
var isExplicit = t.GetCustomAttributes(typeof(ExplicitColumnsAttribute), true).Any();

// Check for [Column]/[Ignore] Attributes
var column = pi.GetCustomAttributes(typeof(ColumnAttribute), true).FirstOrDefault() as ColumnAttribute;

if (isExplicit && column == null)
return false;

if (pi.GetCustomAttributes(typeof(IgnoreAttribute), true).Any())
ColumnInfo.PopulateFromProperty(pi, ref ci, out var columnAttr);

if (ci == null)
return false;

// Read attribute
if (column != null)
{
ci.ColumnName = column.Name ?? InflectColumnName(Inflector.Instance, pi.Name);
ci.ForceToUtc = column.ForceToUtc;
ci.ResultColumn = (column as ResultColumnAttribute) != null;
ci.AutoSelectedResultColumn = (column as ResultColumnAttribute)?.IncludeInAutoSelect == IncludeInAutoSelect.Yes;
ci.InsertTemplate = column.InsertTemplate;
ci.UpdateTemplate = column.UpdateTemplate;
}
else
{
ci.ColumnName = InflectColumnName(Inflector.Instance, pi.Name);
}
// If there's no colAttr.Name, then we got the name
// from pi, so inflect it
if (columnAttr?.Name == null)
ci.ColumnName = InflectColumnName(Inflector.Instance, pi.Name);

return true;
return true;
}
};
FromDbConverter = (pi, t) =>
{
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Reflection;

namespace PetaPoco
{
@@ -35,39 +36,47 @@ public class TableInfo
/// <returns>A TableInfo instance</returns>
public static TableInfo FromPoco(Type t)
{
TableInfo ti = new TableInfo();
var ti = new TableInfo();
PopulateTableNameFromPoco(t, ref ti, out _);
PopulatePrimaryKeyFromPoco(t, ref ti, out _, out _);
return ti;
}

// Get the table name
var a = t.GetCustomAttributes(typeof(TableNameAttribute), true);
ti.TableName = a.Length == 0 ? t.Name : (a[0] as TableNameAttribute).Value;

// Get the primary key
a = t.GetCustomAttributes(typeof(PrimaryKeyAttribute), true);
ti.PrimaryKey = a.Length == 0 ? null : (a[0] as PrimaryKeyAttribute).Value;
ti.SequenceName = a.Length == 0 ? null : (a[0] as PrimaryKeyAttribute).SequenceName;
ti.AutoIncrement = a.Length == 0 ? false : (a[0] as PrimaryKeyAttribute).AutoIncrement;
internal static void PopulateTableNameFromPoco(Type t, ref TableInfo ti, out TableNameAttribute tblAttr)
{
ti = ti ?? new TableInfo();
tblAttr = t.GetCustomAttributes(typeof(TableNameAttribute), true).FirstOrDefault() as TableNameAttribute;
ti.TableName = tblAttr?.Value ?? t.Name;
}

if (string.IsNullOrEmpty(ti.PrimaryKey))
internal static void PopulatePrimaryKeyFromPoco(Type t, ref TableInfo ti, out PrimaryKeyAttribute pkAttr, out PropertyInfo idProp)
{
ti = ti ?? new TableInfo();
pkAttr = t.GetCustomAttributes(typeof(PrimaryKeyAttribute), true).FirstOrDefault() as PrimaryKeyAttribute;
idProp = null;

ti.PrimaryKey = pkAttr?.Value;
ti.SequenceName = pkAttr?.SequenceName;
ti.AutoIncrement = pkAttr?.AutoIncrement ?? false;

if (String.IsNullOrWhiteSpace(ti.PrimaryKey))
{
var prop = t.GetProperties().FirstOrDefault(p =>
bool isIdProp(PropertyInfo p)
{
if (p.Name.Equals("id", StringComparison.OrdinalIgnoreCase))
return true;
if (p.Name.Equals(t.Name + "id", StringComparison.OrdinalIgnoreCase))
return true;
if (p.Name.Equals(t.Name + "_id", StringComparison.OrdinalIgnoreCase))
return true;
return false;
});
bool hasName(string name) => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase);
return hasName("id")
|| hasName(t.Name + "id")
|| hasName(t.Name + "_id");
}

if (prop != null)
idProp = t.GetProperties().FirstOrDefault(isIdProp) as PropertyInfo;
if (idProp != null)
{
ti.PrimaryKey = prop.Name;
ti.AutoIncrement = prop.PropertyType.IsValueType;
ti.PrimaryKey = idProp.Name;
ti.AutoIncrement = idProp.PropertyType.IsValueType;
}
}

return ti;
}
}
}

0 comments on commit d0a08ba

Please sign in to comment.
You can’t perform that action at this time.