Skip to content

Commit

Permalink
v2.3.10 (#44)
Browse files Browse the repository at this point in the history
* v2.3.10

* Created new cleaned .NET name.
  • Loading branch information
chullybun committed Aug 29, 2023
1 parent 7ff5790 commit ab9c8a2
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 22 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Represents the **NuGet** versions.

## v2.3.10
- *Fixed:* `DbTableSchema`, `DbColumnSchema` and `DataParserArgs` now correctly support the full range of by-convention properties (e.g. `RowVersion`, `TenantId` and `IsDeleted`). Both the `SqlServerSchemaConfig` and `MySqlSchemaConfig` updated to default names as appropriate. Additional properties added to `Db*Schema` to support additional code-generation scenarios, etc.

## v2.3.9
- *Fixed:* The YAML-based `MigrationCommand.Data` logic previously set the `CreatedBy`, `CreatedDate`, `UpdatedBy` and `UpdatedDate` (or specified equivalent) regardless of whether the data was being inserted or merged (insert/update). This has been corrected such that the appropriate values are only set for the specific type of operation being performed; i.e. `Created*`-only or `Updated*`-only.
- *Fixed:* Enabled additional command-line arguments to be passed for `MigrationCommand.CodeGen` to enable inherited usage flexibility. Removed `MigrationArgsBase.ScriptName` and `MigrationArgsBase.ScriptArguments` and included within existing `MigrationArgsBase.Parameters` as singular dictionary of key/value pairs (simplification).
Expand Down
2 changes: 1 addition & 1 deletion Common.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>2.3.9</Version>
<Version>2.3.10</Version>
<LangVersion>preview</LangVersion>
<Authors>Avanade</Authors>
<Company>Avanade</Company>
Expand Down
18 changes: 18 additions & 0 deletions src/DbEx.MySql/MySqlSchemaConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ public class MySqlSchemaConfig : DatabaseSchemaConfig
/// <remarks>Value is '<c>updated_by</c>'.</remarks>
public override string UpdatedByColumnName => "updated_by";

/// <inheritdoc/>
/// <remarks>Value is '<c>tenant_id</c>'.</remarks>
public override string TenantIdColumnName => "tenant_id";

/// <inheritdoc/>
/// <remarks>Value is '<c>row_version</c>'.</remarks>
public override string RowVersionColumnName => "row_version";

/// <inheritdoc/>
/// <remarks>Value is '<c>is_deleted</c>'.</remarks>
public override string IsDeletedColumnName => "is_deleted";

/// <inheritdoc/>
/// <remarks>Value is '<c>code</c>'.</remarks>
public override string RefDataCodeColumnName => "code";
Expand All @@ -68,10 +80,16 @@ public override void PrepareDataParserArgs(DataParserArgs dataParserArgs)
dataParserArgs.RefDataColumnDefaults.TryAdd("sort_order", i => i);
}

dataParserArgs.IdColumnNameSuffix ??= IdColumnNameSuffix;
dataParserArgs.CreatedByColumnName ??= CreatedByColumnName;
dataParserArgs.CreatedDateColumnName ??= CreatedDateColumnName;
dataParserArgs.UpdatedByColumnName ??= UpdatedByColumnName;
dataParserArgs.UpdatedDateColumnName ??= UpdatedDateColumnName;
dataParserArgs.TenantIdColumnName ??= TenantIdColumnName;
dataParserArgs.RowVersionColumnName ??= RowVersionColumnName;
dataParserArgs.IsDeletedColumnName ??= IsDeletedColumnName;
dataParserArgs.RefDataCodeColumnName ??= RefDataCodeColumnName;
dataParserArgs.RefDataTextColumnName ??= RefDataTextColumnName;
}

/// <inheritdoc/>
Expand Down
18 changes: 18 additions & 0 deletions src/DbEx.SqlServer/SqlServerSchemaConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ public class SqlServerSchemaConfig : DatabaseSchemaConfig
/// <remarks>Value is '<c>UpdatedBy</c>'.</remarks>
public override string UpdatedByColumnName => "UpdatedBy";

/// <inheritdoc/>
/// <remarks>Value is '<c>TenantId</c>'.</remarks>
public override string TenantIdColumnName => "TenantId";

/// <inheritdoc/>
/// <remarks>Value is '<c>RowVersion</c>'.</remarks>
public override string RowVersionColumnName => "RowVersion";

/// <inheritdoc/>
/// <remarks>Value is '<c>IsDeleted</c>'.</remarks>
public override string IsDeletedColumnName => "IsDeleted";

/// <inheritdoc/>
/// <remarks>Value is '<c>Code</c>'.</remarks>
public override string RefDataCodeColumnName => "Code";
Expand All @@ -68,10 +80,16 @@ public override void PrepareDataParserArgs(DataParserArgs dataParserArgs)
dataParserArgs.RefDataColumnDefaults.TryAdd("SortOrder", i => i);
}

dataParserArgs.IdColumnNameSuffix ??= IdColumnNameSuffix;
dataParserArgs.CreatedByColumnName ??= CreatedByColumnName;
dataParserArgs.CreatedDateColumnName ??= CreatedDateColumnName;
dataParserArgs.UpdatedByColumnName ??= UpdatedByColumnName;
dataParserArgs.UpdatedDateColumnName ??= UpdatedDateColumnName;
dataParserArgs.TenantIdColumnName ??= TenantIdColumnName;
dataParserArgs.RowVersionColumnName ??= RowVersionColumnName;
dataParserArgs.IsDeletedColumnName ??= IsDeletedColumnName;
dataParserArgs.RefDataCodeColumnName ??= RefDataCodeColumnName;
dataParserArgs.RefDataTextColumnName ??= RefDataTextColumnName;
}

/// <inheritdoc/>
Expand Down
43 changes: 38 additions & 5 deletions src/DbEx/DatabaseExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using OnRamp.Utility;

namespace DbEx
{
Expand All @@ -31,9 +34,11 @@ public static async Task<List<DbTableSchema>> SelectSchemaAsync(this IDatabase d
var tables = new List<DbTableSchema>();
DbTableSchema? table = null;

var idColumnNameSuffix = dataParserArgs?.IdColumnNameSuffix ?? databaseSchemaConfig.IdColumnNameSuffix;
var refDataCodeColumn = dataParserArgs?.RefDataCodeColumnName ?? databaseSchemaConfig.RefDataCodeColumnName;
var refDataTextColumn = dataParserArgs?.RefDataTextColumnName ?? databaseSchemaConfig.RefDataTextColumnName;
dataParserArgs ??= new DataParserArgs();
databaseSchemaConfig.PrepareDataParserArgs(dataParserArgs);
var idColumnNameSuffix = dataParserArgs?.IdColumnNameSuffix!;
var refDataCodeColumn = dataParserArgs?.RefDataCodeColumnName!;
var refDataTextColumn = dataParserArgs?.RefDataTextColumnName!;
var refDataPredicate = new Func<DbTableSchema, bool>(t => t.Columns.Any(c => c.Name == refDataCodeColumn && !c.IsPrimaryKey && c.DotNetType == "string") && t.Columns.Any(c => c.Name == refDataTextColumn && !c.IsPrimaryKey && c.DotNetType == "string"));

// Get all the tables and their columns.
Expand All @@ -56,8 +61,11 @@ public static async Task<List<DbTableSchema>> SelectSchemaAsync(this IDatabase d
tables.Add(table = dt);
var dc = databaseSchemaConfig.CreateColumnFromInformationSchema(table, dr);
dc.IsCreatedAudit = dc.Name == (dataParserArgs?.CreatedByColumnName ?? databaseSchemaConfig.CreatedByColumnName) || dc.Name == (dataParserArgs?.CreatedDateColumnName ?? databaseSchemaConfig.CreatedDateColumnName);
dc.IsUpdatedAudit = dc.Name == (dataParserArgs?.UpdatedByColumnName ?? databaseSchemaConfig.UpdatedByColumnName) || dc.Name == (dataParserArgs?.UpdatedDateColumnName ?? databaseSchemaConfig.UpdatedDateColumnName);
dc.IsCreatedAudit = dc.Name == dataParserArgs?.CreatedByColumnName || dc.Name == dataParserArgs?.CreatedDateColumnName;
dc.IsUpdatedAudit = dc.Name == dataParserArgs?.UpdatedByColumnName || dc.Name == dataParserArgs?.UpdatedDateColumnName;
dc.IsTenantId = dc.Name == dataParserArgs?.TenantIdColumnName;
dc.IsRowVersion = dc.Name == dataParserArgs?.RowVersionColumnName;
dc.IsIsDeleted = dc.Name == dataParserArgs?.IsDeletedColumnName;
table.Columns.Add(dc);
return 0;
Expand Down Expand Up @@ -153,6 +161,31 @@ public static async Task<List<DbTableSchema>> SelectSchemaAsync(this IDatabase d
}
}

// Attempt to infer if a reference data column where not explicitly specified.
var sb = new StringBuilder();

foreach (var t in tables)
{
foreach (var c in t.Columns.Where(x => !x.IsPrimaryKey))
{
if (c.IsForeignRefData)
{
c.IsRefData = true;
continue;
}

sb.Clear();
c.Name.Split(new char[] { '_', '-' }, StringSplitOptions.RemoveEmptyEntries).ForEach(part => sb.Append(StringConverter.ToPascalCase(part)));
var words = Regex.Split(sb.ToString(), DbTableSchema.WordSplitPattern).Where(x => !string.IsNullOrEmpty(x));
if (words.Count() > 1 && new string[] { "Id", "Code" }.Contains(words.Last(), StringComparer.InvariantCultureIgnoreCase))
{
var name = string.Join(string.Empty, words.Take(words.Count() - 1));
if (tables.Any(x => x.Name == name && x.Schema == t.Schema && x.IsRefData))
c.IsRefData = true;
}
}
}

return tables;
}
}
Expand Down
19 changes: 15 additions & 4 deletions src/DbEx/DatabaseSchemaConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,33 @@ protected DatabaseSchemaConfig(string databaseName, bool supportsSchema = true)
/// <summary>
/// Gets the name of the <see cref="IChangeLogAudit.CreatedDate"/> column (where it exists).
/// </summary>
/// <remarks>Defaults to '<c>CreatedDate</c>'.</remarks>
public abstract string CreatedDateColumnName { get; }

/// <summary>
/// Gets the name of the <see cref="IChangeLogAudit.CreatedBy"/> column (where it exists).
/// </summary>
/// <remarks>Defaults to '<c>CreatedBy</c>'.</remarks>
public abstract string CreatedByColumnName { get; }

/// <summary>
/// Gets the name of the <see cref="IChangeLogAudit.UpdatedDate"/> column (where it exists).
/// </summary>
/// <remarks>Defaults to '<c>UpdatedDate</c>'.</remarks>
public abstract string UpdatedDateColumnName { get; }

/// <summary>
/// Gets the name of the <see cref="IChangeLogAudit.UpdatedBy"/> column (where it exists).
/// </summary>
/// <remarks>Defaults to '<c>UpdatedBy</c>'.</remarks>
public abstract string UpdatedByColumnName { get; }

/// <summary>
/// Gets the name of the <see cref="ITenantId.TenantId"/> column (where it exists).
/// </summary>
public abstract string TenantIdColumnName { get; }

/// <summary>
/// Gets the name of the row-version (<see cref="IETag.ETag"/> equivalent) column (where it exists).
/// </summary>
public abstract string RowVersionColumnName { get; }

/// <summary>
/// Gets the default <see cref="IReferenceData.Code"/> column.
/// </summary>
Expand All @@ -75,6 +81,11 @@ protected DatabaseSchemaConfig(string databaseName, bool supportsSchema = true)
/// </summary>
public abstract string RefDataTextColumnName { get; }

/// <summary>
/// Gets the default <see cref="ILogicallyDeleted.IsDeleted"/> column.
/// </summary>
public abstract string IsDeletedColumnName { get; }

/// <summary>
/// Gets the default reference data predicate to determine <see cref="DbTableSchema.IsRefData"/>.
/// </summary>
Expand Down
51 changes: 41 additions & 10 deletions src/DbEx/DbSchema/DbColumnSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class DbColumnSchema
{
private string? _dotNetType;
private string? _dotNetName;
private string? _dotNetCleanedName;
private string? _sqlType;

/// <summary>
Expand Down Expand Up @@ -53,6 +54,11 @@ public DbColumnSchema(DbTableSchema dbTable, string name, string type)
/// </summary>
public ulong? Length { get; set; }

/// <summary>
/// Indicates whether the column has a length greater than zero.
/// </summary>
public bool HasLength => Length != null && Length > 0;

/// <summary>
/// Gets or sets the precision.
/// </summary>
Expand Down Expand Up @@ -119,7 +125,12 @@ public DbColumnSchema(DbTableSchema dbTable, string name, string type)
public string? ForeignColumn { get; set; }

/// <summary>
/// Indicates whether the foreign key is references a reference data table/entity.
/// Indicates whether the column <see cref="IsForeignRefData"/> or the name (after removing '<c>Id</c>' or '<c>Code</c>') matches a reference data table/entity in the same schema (where applicable).
/// </summary>
public bool IsRefData { get; set; }

/// <summary>
/// Indicates whether the foreign key is referencing a reference data table/entity.
/// </summary>
public bool IsForeignRefData { get; set; }

Expand All @@ -138,6 +149,26 @@ public DbColumnSchema(DbTableSchema dbTable, string name, string type)
/// </summary>
public bool IsUpdatedAudit { get; set; }

/// <summary>
/// Indicates whether the column is a row-version column; i.e. name is <c>RowVersion</c>.
/// </summary>
public bool IsRowVersion { get; set; }

/// <summary>
/// Indicates whether the column is a tenant identifier column; i.e. name is <c>TenantId</c>.
/// </summary>
public bool IsTenantId { get; set; }

/// <summary>
/// Indicates whether the column is an is-deleted column; i.e. name is <c>IsDeleted</c>.
/// </summary>
public bool IsIsDeleted { get; set; }

/// <summary>
/// Indicates whether the column <i>may</i> contain JSON content by convention (<see cref="DotNetType"/> is a `<c>string</c>` and the <see cref="Name"/> ends with `<c>Json</c>`) .
/// </summary>
public bool IsJsonContent => DotNetType == "string" && Name.EndsWith("Json", StringComparison.OrdinalIgnoreCase);

/// <summary>
/// Gets the corresponding .NET <see cref="System.Type"/> name.
/// </summary>
Expand All @@ -149,19 +180,14 @@ public DbColumnSchema(DbTableSchema dbTable, string name, string type)
public string DotNetName => _dotNetName ??= DbTableSchema.CreateDotNetName(Name);

/// <summary>
/// Gets the fully defined SQL type.
/// Gets the corresponding .NET name cleaned; by removing any known suffixes where <see cref="IsRefData"/> or <see cref="IsJsonContent"/>
/// </summary>
public string SqlType => _sqlType ??= DbTable?.Config.ToFormattedSqlType(this) ?? throw new InvalidOperationException($"The {nameof(DbTable)} must be set before the {nameof(SqlType)} property can be accessed.");
public string DotNetCleanedName => _dotNetCleanedName ??= DbTableSchema.CreateDotNetName(Name, IsRefData || IsJsonContent);

/// <summary>
/// Prepares the schema by updating the calculated properties: <see cref="DotNetType"/>, <see cref="DotNetName"/> and <see cref="SqlType"/>.
/// Gets the fully defined SQL type.
/// </summary>
public void Prepare()
{
_dotNetType = DbTable.Config.ToDotNetTypeName(this);
_dotNetName = DbTableSchema.CreateDotNetName(Name);
_sqlType = DbTable.Config.ToFormattedSqlType(this);
}
public string SqlType => _sqlType ??= DbTable?.Config.ToFormattedSqlType(this) ?? throw new InvalidOperationException($"The {nameof(DbTable)} must be set before the {nameof(SqlType)} property can be accessed.");

/// <summary>
/// Clones the <see cref="DbColumnSchema"/> creating a new instance.
Expand Down Expand Up @@ -195,11 +221,16 @@ public void CopyFrom(DbColumnSchema column)
ForeignSchema = column.ForeignSchema;
ForeignColumn = column.ForeignColumn;
IsForeignRefData = column.IsForeignRefData;
IsRefData = column.IsRefData;
ForeignRefDataCodeColumn = column.ForeignRefDataCodeColumn;
IsCreatedAudit = column.IsCreatedAudit;
IsUpdatedAudit = column.IsUpdatedAudit;
IsRowVersion = column.IsRowVersion;
IsTenantId = column.IsTenantId;
IsIsDeleted = column.IsIsDeleted;
_dotNetType = column._dotNetType;
_dotNetName = column._dotNetName;
_dotNetCleanedName = column._dotNetCleanedName;
_sqlType = column._sqlType;
}
}
Expand Down
Loading

0 comments on commit ab9c8a2

Please sign in to comment.