Skip to content

Commit

Permalink
initial try at reusing existing entities while generating code by gen…
Browse files Browse the repository at this point in the history
…erating ForeignKey(typeof(SomeRow)) instead of ForeignKey("SomeTable", "SomeId")
  • Loading branch information
volkanceylan committed Oct 18, 2023
1 parent cc295d7 commit ce87569
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 10 deletions.
17 changes: 15 additions & 2 deletions src/Serenity.Net.CodeGenerator/Commands/GenerateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public ExitCodes Run(string csproj, string[] args)
ConnectionKey = connectionKey,
Config = config,
Schema = tableEntry.Schema,
Table = tableEntry.Tablename,
Table = tableEntry.Table,
Module = module,
Identifier = identifier,
PermissionKey = permissionKey
Expand All @@ -136,12 +136,25 @@ public ExitCodes Run(string csproj, string[] args)
config.GenerateCustom = whatToGenerate.Contains("Custom", StringComparer.Ordinal);
}

IApplicationMetadata application = null;
try
{
var assemblyFiles = ServerTypingsCommand.DetermineAssemblyFiles(fileSystem, csproj, config, (error) => { });
if (assemblyFiles != null && assemblyFiles.Length > 0)
{
application = new ApplicationMetadata(fileSystem, assemblyFiles);
}
}
catch { }

foreach (var inputs in inputsList)
{
UpdateConfigTableFor(inputs, confConnection);

inputs.Application = application;

var generator = CreateCodeGenerator(inputs, new EntityModelGenerator(),
csproj, fileSystem, sqlConnections, interactive: argsIdentifier is null);
csproj, fileSystem, sqlConnections, interactive: true);

generator.Run();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,13 @@ void makeUniquePropertyName(EntityField f)
if (!string.IsNullOrEmpty(tableField.PKTable))
{
var pkTable = string.IsNullOrEmpty(tableField.PKSchema) ? tableField.PKTable : ("[" + tableField.PKSchema + "].[" + tableField.PKTable + "]");
attrs.Add(new("Serenity.Data.Mapping.ForeignKey", pkTable, tableField.PKColumn));
var pkRow = inputs.Application?.GetRowByTablename(pkTable);
if (pkRow != null)
{
attrs.Add(new("Serenity.Data.Mapping.ForeignKey", new TypeOfRef(pkRow.FullName)));
}
else
attrs.Add(new("Serenity.Data.Mapping.ForeignKey", pkTable, tableField.PKColumn));

object alias = model.DeclareJoinConstants ?
new RawCode(tableField.ForeignJoinAlias) : tableField.ForeignJoinAlias;
Expand Down
2 changes: 1 addition & 1 deletion src/Serenity.Net.CodeGenerator/Models/AttributeTypeRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public string ToString(CodeWriter cw)
if (i > 0)
s += ", ";

if (value is TypeNameRef tr)
if (value is TypeOfRef tr)
s += tr.ToString(cw);
else if (value is string str)
s += StringHelper.ToDoubleQuoted(str);
Expand Down
3 changes: 2 additions & 1 deletion src/Serenity.Net.CodeGenerator/Models/EntityModelInputs.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
namespace Serenity.CodeGenerator;
namespace Serenity.CodeGenerator;

public class EntityModelInputs : IEntityModelInputs
{
public IApplicationMetadata Application { get; set; }
public GeneratorConfig Config { get; set; }
public string ConnectionKey { get; set; }
public IEntityDataSchema DataSchema { get; set; }
Expand Down
3 changes: 2 additions & 1 deletion src/Serenity.Net.CodeGenerator/Models/IEntityModelInputs.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
namespace Serenity.CodeGenerator;
namespace Serenity.CodeGenerator;

public interface IEntityModelInputs
{
public IApplicationMetadata Application { get; }
string ConnectionKey { get; }
string Identifier { get; }
GeneratorConfig Config { get; }
Expand Down
118 changes: 118 additions & 0 deletions src/Serenity.Net.CodeGenerator/Models/Metadata/ApplicationMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using Serenity.CodeGeneration;

namespace Serenity.CodeGenerator;

public class ApplicationMetadata : IApplicationMetadata
{
private class Scanner : ServerTypingsGenerator
{
public List<TypeDefinition> RowTypes { get; } = new();

public Scanner(IGeneratorFileSystem fileSystem, params string[] assemblyLocations)
: base(fileSystem, assemblyLocations)
{
}

protected override void GenerateCodeFor(TypeDefinition type)
{
if (TypingsUtils.IsSubclassOf(type, "Serenity.Data", "Row") ||
TypingsUtils.IsSubclassOf(type, "Serenity.Data", "Row`1"))
{
RowTypes.Add(type);
}
}

protected override void HandleMemberType(TypeReference memberType, string codeNamespace, bool module)
{
}
}

private readonly Scanner scanner;

public ApplicationMetadata(IGeneratorFileSystem fileSystem, params string[] assemblyLocations)
{
scanner = new Scanner(fileSystem, assemblyLocations);
scanner.Run();
}

string DefaultSchema { get; set; }

private string ParseSchemaAndName(string objectName, out string schema)
{
if (objectName is null)
throw new ArgumentNullException(nameof(objectName));

schema = DefaultSchema;
var parts = objectName.Split('.');
if (parts.Length <= 0 || parts.Length > 2)
return null;

if (parts.Length == 1)
return SqlSyntax.Unquote(parts[0]);

schema = SqlSyntax.Unquote(parts[0]);
return SqlSyntax.Unquote(parts[1]);
}

private string NormalizeTablename(string objectName)
{
var table = ParseSchemaAndName(objectName, out var schema);
return table + "." + schema;
}

private bool IsEqualIgnoreCase(string objectName1, string objectName2)
{
return !string.IsNullOrEmpty(objectName1) &&
!string.IsNullOrEmpty(objectName2) &&
string.Equals(NormalizeTablename(objectName1),
NormalizeTablename(objectName2), StringComparison.OrdinalIgnoreCase);
}

public IRowMetadata GetRowByTablename(string tablename)
{
foreach (var type in scanner.RowTypes)
{
var attr = type.GetAttributes().FirstOrDefault(x =>
x.AttributeType().Name == "TableNameAttribute" &&
x.AttributeType().NamespaceOf() == "Serenity.Data.Mapping");

if (attr != null)
{
if (IsEqualIgnoreCase(tablename, attr?.ConstructorArguments?.FirstOrDefault().Value as string))
return new RowMetadata(type);

continue;
}

var name = type.Name;
if (name.EndsWith("Row", StringComparison.Ordinal))
name = name[..^3];

if (IsEqualIgnoreCase(tablename, name))
return new RowMetadata(type);
}

return null;
}

private class RowMetadata : IRowMetadata
{
private readonly TypeDefinition type;

public RowMetadata(TypeDefinition type)
{
this.type = type ?? throw new ArgumentNullException(nameof(type));
}

public string Namespace => type.NamespaceOf();

public string ClassName => type.Name;

public string FullName => type.FullNameOf();

public IRowPropertyMetadata GetTableField(string columnName)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Serenity.CodeGenerator;

public interface IApplicationMetadata
{
IRowMetadata GetRowByTablename(string tablename);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Serenity.CodeGenerator;

public interface IClassMetadata
{
string Namespace { get; }
string ClassName { get; }
string FullName => string.IsNullOrEmpty(Namespace) ? ClassName : Namespace + "." + ClassName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Serenity.CodeGenerator;

public interface IPropertyMetadata
{
string PropertyName { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Serenity.CodeGenerator;

public interface IRowMetadata : IClassMetadata
{
IRowPropertyMetadata GetTableField(string columnName);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Serenity.CodeGenerator;

public interface IRowPropertyMetadata : IPropertyMetadata
{
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
namespace Serenity.CodeGenerator;

public class TypeNameRef
public class TypeOfRef
{
public string TypeName { get; }

public TypeNameRef(string typeName)
public TypeOfRef(string typeName)
{
TypeName = typeName ?? throw new ArgumentNullException(nameof(typeName));
}
Expand Down
9 changes: 7 additions & 2 deletions src/Serenity.Net.Core/Reflection/CodeWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,13 @@ public string ShortTypeName(string ns, string typeName)

if (Using(ns))
return typeName;
else
return ns + "." + typeName;
else if (CurrentNamespace != null)
{
var idx = CurrentNamespace.IndexOf('.', StringComparison.Ordinal);
if (idx >= 0 && ns.StartsWith(CurrentNamespace[..(idx + 1)], StringComparison.Ordinal))
ns = ns[(idx + 1)..];
}
return ns + "." + typeName;
}

/// <summary>
Expand Down

0 comments on commit ce87569

Please sign in to comment.