Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions Orm/Xtensive.Orm/Orm/Building/Builders/AttributeProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,26 @@ public void Process(HierarchyDef hierarchyDef, FieldDef fieldDef, KeyAttribute a
"attribute.Position");

var keyField = new KeyField(fieldDef.Name, attribute.Direction);
var hierarchyDefKeyFields = hierarchyDef.KeyFields;

if (hierarchyDef.KeyFields.Count > attribute.Position) {
var current = hierarchyDef.KeyFields[attribute.Position];
if (current != null) {
if (hierarchyDefKeyFields.Count > attribute.Position) {
var current = hierarchyDefKeyFields[attribute.Position];
if (current != default) {
throw new DomainBuilderException(string.Format(Strings.ExKeyFieldsXAndXHaveTheSamePositionX, current.Name,
fieldDef.Name, attribute.Position));
}

hierarchyDef.KeyFields[attribute.Position] = keyField;
hierarchyDefKeyFields[attribute.Position] = keyField;
}
else {
// Adding null stubs for not yet processed key fields
while (hierarchyDef.KeyFields.Count < attribute.Position) {
hierarchyDef.KeyFields.Add(null);
// Adding default stubs for not yet processed key fields
hierarchyDefKeyFields.EnsureCapacity(attribute.Position + 1);
while (hierarchyDefKeyFields.Count < attribute.Position) {
hierarchyDefKeyFields.Add(default);
}

// Finally adding target key field at the specified position
hierarchyDef.KeyFields.Add(keyField);
hierarchyDefKeyFields.Add(keyField);
}
}

Expand Down
5 changes: 2 additions & 3 deletions Orm/Xtensive.Orm/Orm/Building/Definitions/HierarchyDef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public sealed class HierarchyDef : Node
/// <summary>
/// Gets the fields that are included in the key for this hierarchy.
/// </summary>
public List<KeyField> KeyFields { get; private set; }
public List<KeyField> KeyFields { get; } = new(WellKnown.MaxKeyFieldNumber);

/// <summary>
/// Gets the <see cref="InheritanceSchema"/> for this hierarchy.
Expand Down Expand Up @@ -58,9 +58,8 @@ public sealed class HierarchyDef : Node
internal HierarchyDef(TypeDef root)
{
Root = root;
KeyFields = new List<KeyField>(WellKnown.MaxKeyFieldNumber);
IsClustered = true;
KeyGeneratorKind = KeyGeneratorKind.Default;
}
}
}
}
2 changes: 1 addition & 1 deletion Orm/Xtensive.Orm/Orm/Building/FixupActionProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public void Process(AddPrimaryIndexAction action)

var hierarchyDef = context.ModelDef.FindHierarchy(hierarchyRoot);

foreach (KeyField pair in hierarchyDef.KeyFields)
foreach (var pair in hierarchyDef.KeyFields)
generatedIndex.KeyFields.Add(pair.Name, pair.Direction);

// Check if user added secondary index equal to auto-generated primary index
Expand Down
2 changes: 1 addition & 1 deletion Orm/Xtensive.Orm/Orm/Building/ModelInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public static void Inspect(BuildingContext context, HierarchyDef hierarchyDef)
}

// Should TypeId field be added to key fields?
if (hierarchyDef.IncludeTypeId && hierarchyDef.KeyFields.Find(f => f.Name == WellKnown.TypeIdFieldName) == null) {
if (hierarchyDef.IncludeTypeId && hierarchyDef.KeyFields.All(f => f.Name != WellKnown.TypeIdFieldName)) {
context.ModelInspectionResult.Register(new AddTypeIdToKeyFieldsAction(hierarchyDef));
}

Expand Down
44 changes: 18 additions & 26 deletions Orm/Xtensive.Orm/Orm/Building/Validator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
// Created by: Dmitri Maximov
// Created: 2007.09.12

using System;
using System.Collections.Generic;
using System.Collections.Frozen;
using System.Text.RegularExpressions;
using Xtensive.Orm.Building.Definitions;
using Xtensive.Orm.Internals;
Expand All @@ -14,12 +13,13 @@

namespace Xtensive.Orm.Building
{
internal class Validator
internal class Validator(IEnumerable<Type> validFieldTypes)
{
private readonly HashSet<Type> validFieldTypes;
private readonly Regex columnNamingRule;
private readonly Regex typeNamingRule;
private readonly Regex fieldNamingRule;
private static readonly Regex ColumnNamingRule = new(@"^[\w][\w\-\.]*$", RegexOptions.Compiled | RegexOptions.CultureInvariant);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to use compile time generated regex feature

private static readonly Regex TypeNamingRule = new(@"^[\w][\w\-\.\(\),]*$", RegexOptions.Compiled | RegexOptions.CultureInvariant);
private static readonly Regex FieldNamingRule = new(@"^[\w][\w\-\.]*$", RegexOptions.Compiled | RegexOptions.CultureInvariant);

private readonly FrozenSet<Type> validFieldTypes = validFieldTypes.Append(WellKnownOrmTypes.Key).ToFrozenSet();

/// <summary>
/// Determines whether the specified name is valid.
Expand All @@ -41,13 +41,13 @@ public void ValidateName(string name, ValidationRule rule)
case ValidationRule.Type:
case ValidationRule.Schema:
case ValidationRule.Database:
namingRule = typeNamingRule;
namingRule = TypeNamingRule;
break;
case ValidationRule.Field:
namingRule = fieldNamingRule;
namingRule = FieldNamingRule;
break;
case ValidationRule.Column:
namingRule = columnNamingRule;
namingRule = ColumnNamingRule;
break;
default:
throw new ArgumentOutOfRangeException();
Expand Down Expand Up @@ -95,7 +95,7 @@ public void ValidateHierarchy(HierarchyDef hierarchyDef)
}

// if one of key fields is TypeId field and number of fields == 2 then it is OK
if (keyFields.Count == 2 && keyFields.Find(f => f.Name == WellKnown.TypeIdFieldName) != null) {
if (keyFields.Count == 2 && keyFields.Any(f => f.Name == WellKnown.TypeIdFieldName)) {
throw new DomainBuilderException(Strings.ExDefaultGeneratorCanServeHierarchyWithExactlyOneKeyField);
}
}
Expand Down Expand Up @@ -257,17 +257,6 @@ internal void EnsureIsNullable(Type valueType)
}
}

// Type initializer

public Validator(IEnumerable<Type> validFieldTypes)
{
columnNamingRule = new Regex(@"^[\w][\w\-\.]*$", RegexOptions.Compiled | RegexOptions.CultureInvariant);
typeNamingRule = new Regex(@"^[\w][\w\-\.\(\),]*$", RegexOptions.Compiled | RegexOptions.CultureInvariant);
fieldNamingRule = new Regex(@"^[\w][\w\-\.]*$", RegexOptions.Compiled | RegexOptions.CultureInvariant);

this.validFieldTypes = new HashSet<Type>(validFieldTypes) {WellKnownOrmTypes.Key};
}

public void ValidateHierarchyEquality(TypeDef @interface, HierarchyDef first, HierarchyDef second)
{
// TypeId mode must match
Expand All @@ -277,17 +266,20 @@ public void ValidateHierarchyEquality(TypeDef @interface, HierarchyDef first, Hi
@interface.Name, first.Root.Name, second.Root.Name));
}

var firstKeyFields = first.KeyFields;
var secondKeyFields = second.KeyFields;

// Number of key fields must match
if (first.KeyFields.Count != second.KeyFields.Count) {
if (firstKeyFields.Count != secondKeyFields.Count) {
throw new DomainBuilderException(string.Format(
Strings.ExImplementorsOfXInterfaceBelongToHierarchiesWithDifferentKeyStructureYZ,
@interface.Name, first.Root.Name, second.Root.Name));
}

// Type of each key field must match
for (var i = 0; i < first.KeyFields.Count; i++) {
var masterField = first.Root.Fields[first.KeyFields[i].Name];
var candidateField = second.Root.Fields[second.KeyFields[i].Name];
for (var i = 0; i < firstKeyFields.Count; i++) {
var masterField = first.Root.Fields[firstKeyFields[i].Name];
var candidateField = second.Root.Fields[secondKeyFields[i].Name];
if (masterField.ValueType != candidateField.ValueType) {
throw new DomainBuilderException(string.Format(
Strings.ExImplementorsOfXInterfaceBelongToHierarchiesWithDifferentKeyStructureYZ,
Expand Down
51 changes: 6 additions & 45 deletions Orm/Xtensive.Orm/Orm/Model/KeyField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,12 @@
// Created by: Dmitri Maximov
// Created: 2007.12.28

using System;
using Xtensive.Core;

namespace Xtensive.Orm.Model;

namespace Xtensive.Orm.Model
{
/// <summary>
/// Describes a field that is a part of a primary key.
/// </summary>
[Serializable]
public sealed class KeyField : Node
{
/// <summary>
/// Gets or sets the direction.
/// </summary>
public Direction Direction { get; private set; }

/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(Name, Direction);

/// <inheritdoc/>
public override bool Equals(object obj) =>
ReferenceEquals(this, obj)
|| obj is KeyField kf && Name == kf.Name && Direction == kf.Direction;


// Constructors

/// <summary>
/// Initializes a new instance of this class.
/// </summary>
/// <param name="name">The name.</param>
public KeyField(string name)
: this(name, Direction.Positive)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="KeyField"/> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="direction">The direction.</param>
public KeyField(string name, Direction direction) : base(name)
{
Direction = direction;
}
}
}
/// <summary>
/// Describes a field that is a part of a primary key.
/// </summary>
[Serializable]
public record struct KeyField(string Name, Direction Direction = Direction.Positive);
10 changes: 1 addition & 9 deletions Orm/Xtensive.Orm/Orm/Model/ModelVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ protected virtual TResult Visit(Node node) =>
DomainModel domainModel => VisitDomainModel(domainModel),
KeyInfo keyProviderInfo => VisitKeyInfo(keyProviderInfo),
SequenceInfo sequenceInfo => VisitSequenceInfo(sequenceInfo),
KeyField keyField => VisitKeyField(keyField),
AssociationInfo association => VisitAssociationInfo(association),
FieldInfo field => VisitFieldInfo(field),
TypeInfo type => VisitTypeInfo(type),
Expand All @@ -38,13 +37,6 @@ protected virtual TResult Visit(Node node) =>
_ => throw new ArgumentException(Strings.ExNodeTypeIsUnknown, "node")
};

/// <summary>
/// Visits key field.
/// </summary>
/// <param name="keyField">The key field.</param>
/// <returns>Visit result.</returns>
protected abstract TResult VisitKeyField(KeyField keyField);

/// <summary>
/// Visits a column.
/// </summary>
Expand Down Expand Up @@ -114,4 +106,4 @@ protected virtual TResult Visit(Node node) =>
/// <param name="fullTextIndex">Full index of the text.</param>
protected abstract TResult VisitFullTextIndexInfo(FullTextIndexInfo fullTextIndex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -337,13 +337,6 @@ private IEnumerable<TableInfo> CreateTables(IndexInfo index)

#region Not supported

/// <inheritdoc/>
/// <exception cref="NotSupportedException">Method is not supported.</exception>
protected override IPathNode VisitKeyField(KeyField keyField)
{
throw new NotSupportedException(String.Format(Strings.ExVisitKeyFieldIsNotSupportedByX, typeof (DomainModelConverter)));
}

/// <inheritdoc/>
/// <exception cref="NotSupportedException">Method is not supported.</exception>
protected override IPathNode VisitFieldInfo(FieldInfo field)
Expand Down
Loading