From d3d0a9acf832ae4a556aae7cf90820666a261538 Mon Sep 17 00:00:00 2001 From: Kristian Hellang Date: Mon, 18 Feb 2019 12:50:45 +0100 Subject: [PATCH] Add SortOrder enum and use in metadata --- .../Internal/NpgsqlAnnotationCodeGenerator.cs | 2 +- .../NpgsqlIndexBuilderExtensions.cs | 5 ++-- .../Metadata/INpgsqlIndexAnnotations.cs | 2 +- .../Internal/NpgsqlAnnotationNames.cs | 2 +- .../Metadata/NpgsqlIndexAnnotations.cs | 12 ++++---- src/EFCore.PG/Metadata/SortOrder.cs | 23 +++++++++++++++ .../NpgsqlMigrationsAnnotationProvider.cs | 4 +-- .../NpgsqlMigrationsSqlGenerator.cs | 28 +++++++++++++------ .../NpgsqlMigrationSqlGeneratorTest.cs | 2 +- 9 files changed, 58 insertions(+), 22 deletions(-) create mode 100644 src/EFCore.PG/Metadata/SortOrder.cs diff --git a/src/EFCore.PG/Design/Internal/NpgsqlAnnotationCodeGenerator.cs b/src/EFCore.PG/Design/Internal/NpgsqlAnnotationCodeGenerator.cs index 1b360ee834..d63301531d 100644 --- a/src/EFCore.PG/Design/Internal/NpgsqlAnnotationCodeGenerator.cs +++ b/src/EFCore.PG/Design/Internal/NpgsqlAnnotationCodeGenerator.cs @@ -165,7 +165,7 @@ public override MethodCallCodeFragment GenerateFluentApi(IIndex index, IAnnotati return new MethodCallCodeFragment(nameof(NpgsqlIndexBuilderExtensions.ForNpgsqlHasOperators), annotation.Value); if (annotation.Name == NpgsqlAnnotationNames.IndexCollation) return new MethodCallCodeFragment(nameof(NpgsqlIndexBuilderExtensions.ForNpgsqlHasCollation), annotation.Value); - if (annotation.Name == NpgsqlAnnotationNames.IndexDescendingOrder) + if (annotation.Name == NpgsqlAnnotationNames.IndexSortOrder) return new MethodCallCodeFragment(nameof(NpgsqlIndexBuilderExtensions.ForNpgsqlHasDescendingOrder), annotation.Value); if (annotation.Name == NpgsqlAnnotationNames.IndexNullsFirst) return new MethodCallCodeFragment(nameof(NpgsqlIndexBuilderExtensions.ForNpgsqlHasNullsFirst), annotation.Value); diff --git a/src/EFCore.PG/Extensions/NpgsqlIndexBuilderExtensions.cs b/src/EFCore.PG/Extensions/NpgsqlIndexBuilderExtensions.cs index 9627b057d9..1a2eaa477b 100644 --- a/src/EFCore.PG/Extensions/NpgsqlIndexBuilderExtensions.cs +++ b/src/EFCore.PG/Extensions/NpgsqlIndexBuilderExtensions.cs @@ -4,6 +4,7 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using Npgsql.EntityFrameworkCore.PostgreSQL.Utilities; // ReSharper disable once CheckNamespace @@ -88,11 +89,11 @@ public static IndexBuilder ForNpgsqlHasCollation( /// A builder to further configure the index. public static IndexBuilder ForNpgsqlHasDescendingOrder( [NotNull] this IndexBuilder indexBuilder, - [CanBeNull, ItemNotNull] params bool?[] values) + [CanBeNull] params SortOrder[] values) { Check.NotNull(indexBuilder, nameof(indexBuilder)); - indexBuilder.Metadata.Npgsql().DescendingOrder = values; + indexBuilder.Metadata.Npgsql().SortOrder = values; return indexBuilder; } diff --git a/src/EFCore.PG/Metadata/INpgsqlIndexAnnotations.cs b/src/EFCore.PG/Metadata/INpgsqlIndexAnnotations.cs index 7d681593ac..7650415969 100644 --- a/src/EFCore.PG/Metadata/INpgsqlIndexAnnotations.cs +++ b/src/EFCore.PG/Metadata/INpgsqlIndexAnnotations.cs @@ -35,7 +35,7 @@ public interface INpgsqlIndexAnnotations : IRelationalIndexAnnotations /// /// https://www.postgresql.org/docs/current/static/indexes-ordering.html /// - IReadOnlyList DescendingOrder { get; } + IReadOnlyList SortOrder { get; } /// /// The column NULL sort orders to be used, or null if they have not been specified. diff --git a/src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationNames.cs b/src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationNames.cs index 6e16a006c7..ee2639860d 100644 --- a/src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationNames.cs +++ b/src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationNames.cs @@ -12,7 +12,7 @@ public static class NpgsqlAnnotationNames public const string IndexMethod = Prefix + "IndexMethod"; public const string IndexOperators = Prefix + "IndexOperators"; public const string IndexCollation = Prefix + "IndexCollation"; - public const string IndexDescendingOrder = Prefix + "IndexDescendingOrder"; + public const string IndexSortOrder = Prefix + "IndexSortOrder"; public const string IndexNullsFirst = Prefix + "IndexNullsFirst"; public const string IndexInclude = Prefix + "IndexInclude"; public const string PostgresExtensionPrefix = Prefix + "PostgresExtension:"; diff --git a/src/EFCore.PG/Metadata/NpgsqlIndexAnnotations.cs b/src/EFCore.PG/Metadata/NpgsqlIndexAnnotations.cs index 0a2e99898c..f91f03a77a 100644 --- a/src/EFCore.PG/Metadata/NpgsqlIndexAnnotations.cs +++ b/src/EFCore.PG/Metadata/NpgsqlIndexAnnotations.cs @@ -63,13 +63,13 @@ public string[] Collation /// /// https://www.postgresql.org/docs/current/static/indexes-ordering.html /// - public bool?[] DescendingOrder + public SortOrder[] SortOrder { - get => (bool?[])Annotations.Metadata[NpgsqlAnnotationNames.IndexDescendingOrder]; - set => SetDescendingOrder(value); + get => (SortOrder[])Annotations.Metadata[NpgsqlAnnotationNames.IndexSortOrder]; + set => SetSortOrder(value); } - IReadOnlyList INpgsqlIndexAnnotations.DescendingOrder => DescendingOrder; + IReadOnlyList INpgsqlIndexAnnotations.SortOrder => SortOrder; /// /// The column NULL sort orders to be used, or null if they have not been specified. @@ -108,8 +108,8 @@ protected virtual bool SetOperators(string[] value) protected virtual bool SetCollation(string[] value) => Annotations.SetAnnotation(NpgsqlAnnotationNames.IndexCollation, value); - protected virtual bool SetDescendingOrder(bool?[] value) - => Annotations.SetAnnotation(NpgsqlAnnotationNames.IndexDescendingOrder, value); + protected virtual bool SetSortOrder(SortOrder[] value) + => Annotations.SetAnnotation(NpgsqlAnnotationNames.IndexSortOrder, value); protected virtual bool SetNullsFirst(bool?[] value) => Annotations.SetAnnotation(NpgsqlAnnotationNames.IndexNullsFirst, value); diff --git a/src/EFCore.PG/Metadata/SortOrder.cs b/src/EFCore.PG/Metadata/SortOrder.cs new file mode 100644 index 0000000000..c44aa61bc9 --- /dev/null +++ b/src/EFCore.PG/Metadata/SortOrder.cs @@ -0,0 +1,23 @@ +namespace Npgsql.EntityFrameworkCore.PostgreSQL.Metadata +{ + /// + /// Options for modifying sort ordering of index values. + /// + public enum SortOrder + { + /// + /// Represents an unspecified sort order. The database default will be used. + /// + Unspecified = 0, + + /// + /// Specifies ascending sort order, which is the default. + /// + Ascending = 1, + + /// + /// Specifies descending sort order. + /// + Descending = 2, + } +} diff --git a/src/EFCore.PG/Migrations/Internal/NpgsqlMigrationsAnnotationProvider.cs b/src/EFCore.PG/Migrations/Internal/NpgsqlMigrationsAnnotationProvider.cs index 96bc98d997..64e4444766 100644 --- a/src/EFCore.PG/Migrations/Internal/NpgsqlMigrationsAnnotationProvider.cs +++ b/src/EFCore.PG/Migrations/Internal/NpgsqlMigrationsAnnotationProvider.cs @@ -47,8 +47,8 @@ public override IEnumerable For(IIndex index) yield return new Annotation(NpgsqlAnnotationNames.IndexOperators, index.Npgsql().Operators); if (index.Npgsql().Collation != null) yield return new Annotation(NpgsqlAnnotationNames.IndexCollation, index.Npgsql().Collation); - if (index.Npgsql().DescendingOrder != null) - yield return new Annotation(NpgsqlAnnotationNames.IndexDescendingOrder, index.Npgsql().DescendingOrder); + if (index.Npgsql().SortOrder != null) + yield return new Annotation(NpgsqlAnnotationNames.IndexSortOrder, index.Npgsql().SortOrder); if (index.Npgsql().NullsFirst != null) yield return new Annotation(NpgsqlAnnotationNames.IndexNullsFirst, index.Npgsql().NullsFirst); if (index.Npgsql().IncludeProperties != null) diff --git a/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs b/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs index 6c62bb38ae..2bed129a25 100644 --- a/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs +++ b/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs @@ -1229,9 +1229,21 @@ string IndexColumnList(IndexColumn[] columns) builder.Append(" COLLATE ").Append(column.Collation); } - if (column.DescendingOrder.HasValue) + if (column.SortOrder != SortOrder.Unspecified) { - builder.Append(" ").Append(column.DescendingOrder.Value ? "DESC" : "ASC"); + builder.Append(" "); + + switch (column.SortOrder) + { + case SortOrder.Ascending: + builder.Append("ASC"); + break; + case SortOrder.Descending: + builder.Append("DESC"); + break; + default: + throw new ArgumentOutOfRangeException(); + } } if (column.NullsFirst.HasValue) @@ -1265,7 +1277,7 @@ static IndexColumn[] GetIndexColumns(CreateIndexOperation operation) { var operators = operation[NpgsqlAnnotationNames.IndexOperators] as string[]; var collations = operation[NpgsqlAnnotationNames.IndexCollation] as string[]; - var descendingOrders = operation[NpgsqlAnnotationNames.IndexDescendingOrder] as bool?[]; + var sortOrders = operation[NpgsqlAnnotationNames.IndexSortOrder] as SortOrder[]; var nullsFirsts = operation[NpgsqlAnnotationNames.IndexNullsFirst] as bool?[]; var columns = new IndexColumn[operation.Columns.Length]; @@ -1275,10 +1287,10 @@ static IndexColumn[] GetIndexColumns(CreateIndexOperation operation) var name = operation.Columns[i]; var @operator = i < operators?.Length ? operators[i] : null; var collation = i < collations?.Length ? collations[i] : null; - var descendingOrder = i < descendingOrders?.Length ? descendingOrders[i] : null; + var sortOrder = i < sortOrders?.Length ? sortOrders[i] : SortOrder.Unspecified; var nullsFirst = i < nullsFirsts?.Length ? nullsFirsts[i] : null; - columns[i] = new IndexColumn(name, @operator, collation, descendingOrder, nullsFirst); + columns[i] = new IndexColumn(name, @operator, collation, sortOrder, nullsFirst); } return columns; @@ -1286,12 +1298,12 @@ static IndexColumn[] GetIndexColumns(CreateIndexOperation operation) struct IndexColumn { - public IndexColumn(string name, string @operator, string collation, bool? descendingOrder, bool? nullsFirst) + public IndexColumn(string name, string @operator, string collation, SortOrder sortOrder, bool? nullsFirst) { Name = name; Operator = @operator; Collation = collation; - DescendingOrder = descendingOrder; + SortOrder = sortOrder; NullsFirst = nullsFirst; } @@ -1301,7 +1313,7 @@ public IndexColumn(string name, string @operator, string collation, bool? descen public string Collation { get; } - public bool? DescendingOrder { get; } + public SortOrder SortOrder { get; } public bool? NullsFirst { get; } } diff --git a/test/EFCore.PG.FunctionalTests/NpgsqlMigrationSqlGeneratorTest.cs b/test/EFCore.PG.FunctionalTests/NpgsqlMigrationSqlGeneratorTest.cs index d00f841766..c79678ad22 100644 --- a/test/EFCore.PG.FunctionalTests/NpgsqlMigrationSqlGeneratorTest.cs +++ b/test/EFCore.PG.FunctionalTests/NpgsqlMigrationSqlGeneratorTest.cs @@ -717,7 +717,7 @@ public void CreateIndexOperation_sort_order() Table = "People", Schema = "dbo", Columns = new[] { "FirstName", "MiddleName", "LastName" }, - [NpgsqlAnnotationNames.IndexDescendingOrder] = new bool?[] { true, null, false } + [NpgsqlAnnotationNames.IndexSortOrder] = new bool?[] { true, null, false } }); Assert.Equal(