Skip to content

Commit

Permalink
Refactored getting list of available virtual attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkMpn committed Jun 16, 2024
1 parent 3a71157 commit 566c9f1
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 27 deletions.
12 changes: 2 additions & 10 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/ExecuteMessageNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,16 +206,8 @@ private void SetOutputSchema(DataSource dataSource, Message message, TSqlFragmen
AddSchemaColumn(attrMetadata.LogicalName, attrMetadata.GetAttributeSqlType(dataSource, false));

// Add standard virtual attributes
if (attrMetadata is EnumAttributeMetadata || attrMetadata is BooleanAttributeMetadata)
AddSchemaColumn(attrMetadata.LogicalName + "name", DataTypeHelpers.NVarChar(FetchXmlScan.LabelMaxLength, dataSource.DefaultCollation, CollationLabel.CoercibleDefault));

if (attrMetadata is LookupAttributeMetadata lookup)
{
AddSchemaColumn(attrMetadata.LogicalName + "name", DataTypeHelpers.NVarChar(lookup.Targets == null || lookup.Targets.Length == 0 ? 100 : lookup.Targets.Select(e => ((StringAttributeMetadata)dataSource.Metadata[e].Attributes.SingleOrDefault(a => a.LogicalName == dataSource.Metadata[e].PrimaryNameAttribute))?.MaxLength ?? 100).Max(), dataSource.DefaultCollation, CollationLabel.CoercibleDefault));

if (lookup.Targets?.Length != 1 && lookup.AttributeType != AttributeTypeCode.PartyList)
AddSchemaColumn(attrMetadata.LogicalName + "type", DataTypeHelpers.NVarChar(MetadataExtensions.EntityLogicalNameMaxLength, dataSource.DefaultCollation, CollationLabel.CoercibleDefault));
}
foreach (var virtualAttr in attrMetadata.GetVirtualAttributes(dataSource, false))
AddSchemaColumn(attrMetadata.LogicalName + virtualAttr.Suffix, virtualAttr.DataType);
}

if (audit)
Expand Down
18 changes: 2 additions & 16 deletions MarkMpn.Sql4Cds.Engine/ExecutionPlan/FetchXmlScan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ public InvalidPagingException(string message) : base(message)
}
}

public const int LabelMaxLength = 200;
private static readonly XmlSerializer _serializer = new XmlSerializer(typeof(FetchXml.FetchType));

private Dictionary<string, List<ParameterizedCondition>> _parameterizedConditions;
Expand Down Expand Up @@ -1290,21 +1289,8 @@ private void AddSchemaAttribute(DataSource dataSource, ColumnList schema, Dictio
return;

// Add standard virtual attributes
if (attrMetadata is MultiSelectPicklistAttributeMetadata)
AddSchemaAttribute(schema, aliases, AddSuffix(fullName, "name"), (attrMetadata.LogicalName + "name").EscapeIdentifier(), DataTypeHelpers.NVarChar(Int32.MaxValue, dataSource.DefaultCollation, CollationLabel.Implicit), notNull);
else if (attrMetadata is EnumAttributeMetadata || attrMetadata is BooleanAttributeMetadata)
AddSchemaAttribute(schema, aliases, AddSuffix(fullName, "name"), (attrMetadata.LogicalName + "name").EscapeIdentifier(), DataTypeHelpers.NVarChar(LabelMaxLength, dataSource.DefaultCollation, CollationLabel.Implicit), notNull);

if (attrMetadata is LookupAttributeMetadata lookup)
{
AddSchemaAttribute(schema, aliases, AddSuffix(fullName, "name"), (attrMetadata.LogicalName + "name").EscapeIdentifier(), DataTypeHelpers.NVarChar(lookup.Targets == null || lookup.Targets.Length == 0 ? 100 : lookup.Targets.Select(e => (dataSource.Metadata[e].Attributes.SingleOrDefault(a => a.LogicalName == dataSource.Metadata[e].PrimaryNameAttribute) as StringAttributeMetadata)?.MaxLength ?? 100).Max(), dataSource.DefaultCollation, CollationLabel.Implicit), notNull);

if (lookup.Targets?.Length != 1 && lookup.AttributeType != AttributeTypeCode.PartyList)
AddSchemaAttribute(schema, aliases, AddSuffix(fullName, "type"), (attrMetadata.LogicalName + "type").EscapeIdentifier(), DataTypeHelpers.NVarChar(MetadataExtensions.EntityLogicalNameMaxLength, dataSource.DefaultCollation, CollationLabel.Implicit), notNull); ;

if (lookup.Targets != null && lookup.Targets.Any(logicalName => dataSource.Metadata[logicalName].DataProviderId == DataProviders.ElasticDataProvider))
AddSchemaAttribute(schema, aliases, AddSuffix(fullName, "pid"), (attrMetadata.LogicalName + "pid").EscapeIdentifier(), DataTypeHelpers.NVarChar(100, dataSource.DefaultCollation, CollationLabel.Implicit), false);
}
foreach (var virtualAttr in attrMetadata.GetVirtualAttributes(dataSource, false))
AddSchemaAttribute(schema, aliases, AddSuffix(fullName, virtualAttr.Suffix), (attrMetadata.LogicalName + virtualAttr.Suffix).EscapeIdentifier(), virtualAttr.DataType, virtualAttr.NotNull ?? notNull);
}

private void AddSchemaAttribute(ColumnList schema, Dictionary<string, IReadOnlyList<string>> aliases, string fullName, string simpleName, DataTypeReference type, bool notNull)
Expand Down
43 changes: 42 additions & 1 deletion MarkMpn.Sql4Cds.Engine/MetadataExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@

namespace MarkMpn.Sql4Cds.Engine
{
static class MetadataExtensions
public static class MetadataExtensions
{
public static int EntityLogicalNameMaxLength { get; } = 64;

private const int LabelMaxLength = 200;

public static string[] VirtualLookupAttributeSuffixes { get; } = new[] { "name", "type", "pid" };

public static AttributeMetadata FindBaseAttributeFromVirtualAttribute(this EntityMetadata entity, string virtualAttributeLogicalName, out string suffix)
Expand All @@ -29,6 +31,45 @@ public static AttributeMetadata FindBaseAttributeFromVirtualAttribute(this Entit
.SingleOrDefault(a => a.LogicalName.Equals(virtualAttributeLogicalName.Substring(0, virtualAttributeLogicalName.Length - matchingSuffix.Length), StringComparison.OrdinalIgnoreCase));
}

public static IEnumerable<VirtualAttribute> GetVirtualAttributes(this AttributeMetadata attrMetadata, DataSource dataSource, bool writeable)
{
if (!writeable)
{
if (attrMetadata is MultiSelectPicklistAttributeMetadata)
yield return new VirtualAttribute("name", DataTypeHelpers.NVarChar(Int32.MaxValue, dataSource.DefaultCollation, CollationLabel.Implicit), null);
else if (attrMetadata is EnumAttributeMetadata || attrMetadata is BooleanAttributeMetadata)
yield return new VirtualAttribute("name", DataTypeHelpers.NVarChar(LabelMaxLength, dataSource.DefaultCollation, CollationLabel.Implicit), null);
}

if (attrMetadata is LookupAttributeMetadata lookup)
{
if (!writeable)
yield return new VirtualAttribute("name", DataTypeHelpers.NVarChar(lookup.Targets == null || lookup.Targets.Length == 0 ? 100 : lookup.Targets.Select(e => (dataSource.Metadata[e].Attributes.SingleOrDefault(a => a.LogicalName == dataSource.Metadata[e].PrimaryNameAttribute) as StringAttributeMetadata)?.MaxLength ?? 100).Max(), dataSource.DefaultCollation, CollationLabel.Implicit), null);

if (lookup.Targets?.Length != 1 && lookup.AttributeType != AttributeTypeCode.PartyList)
yield return new VirtualAttribute("type", DataTypeHelpers.NVarChar(EntityLogicalNameMaxLength, dataSource.DefaultCollation, CollationLabel.Implicit), null);

if (lookup.Targets != null && lookup.Targets.Any(logicalName => dataSource.Metadata[logicalName].DataProviderId == DataProviders.ElasticDataProvider))
yield return new VirtualAttribute("pid", DataTypeHelpers.NVarChar(100, dataSource.DefaultCollation, CollationLabel.Implicit), false);
}
}

public class VirtualAttribute
{
public VirtualAttribute(string suffix, DataTypeReference dataType, bool? notNull)
{
Suffix = suffix;
DataType = dataType;
NotNull = notNull;
}

public string Suffix { get; }

public DataTypeReference DataType { get; }

public bool? NotNull { get; }
}

public static Type GetAttributeType(this AttributeMetadata attrMetadata)
{
if (attrMetadata is MultiSelectPicklistAttributeMetadata)
Expand Down

0 comments on commit 566c9f1

Please sign in to comment.