diff --git a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Customization.cs b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Customization.cs index d36406c52fc..5df10b9d9d0 100644 --- a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Customization.cs +++ b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Customization.cs @@ -7,70 +7,68 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -using Elastic.Clients.Elasticsearch; using Elastic.Transport; using Newtonsoft.Json; -namespace Elastic.Clients.Elasticsearch.JsonNetSerializer +namespace Elastic.Clients.Elasticsearch.JsonNetSerializer; + +public abstract partial class ConnectionSettingsAwareSerializer : Serializer { - public abstract partial class ConnectionSettingsAwareSerializer : Serializer - { - // Default buffer size of StreamWriter, which is private :( - internal const int DefaultBufferSize = 1024; + // Default buffer size of StreamWriter, which is private :( + internal const int DefaultBufferSize = 1024; - private static readonly Task CompletedTask = Task.CompletedTask; + private static readonly Task CompletedTask = Task.CompletedTask; - internal static readonly Encoding ExpectedEncoding = new UTF8Encoding(false); - private readonly JsonSerializer _collapsedSerializer; + internal static readonly Encoding ExpectedEncoding = new UTF8Encoding(false); + private readonly JsonSerializer _collapsedSerializer; - private readonly JsonSerializer _serializer; - protected virtual int BufferSize => DefaultBufferSize; + private readonly JsonSerializer _serializer; + protected virtual int BufferSize => DefaultBufferSize; - public override T Deserialize(Stream stream) - { - using var streamReader = new StreamReader(stream); - using var jsonTextReader = new JsonTextReader(streamReader); - return _serializer.Deserialize(jsonTextReader); - } + public override T Deserialize(Stream stream) + { + using var streamReader = new StreamReader(stream); + using var jsonTextReader = new JsonTextReader(streamReader); + return _serializer.Deserialize(jsonTextReader); + } - public override object Deserialize(Type type, Stream stream) - { - using var streamReader = new StreamReader(stream); - using var jsonTextReader = new JsonTextReader(streamReader); - return _serializer.Deserialize(jsonTextReader, type); - } + public override object Deserialize(Type type, Stream stream) + { + using var streamReader = new StreamReader(stream); + using var jsonTextReader = new JsonTextReader(streamReader); + return _serializer.Deserialize(jsonTextReader, type); + } - public override async ValueTask DeserializeAsync(Stream stream, CancellationToken cancellationToken = default) - { - using var streamReader = new StreamReader(stream); - using var jsonTextReader = new JsonTextReader(streamReader); - var token = await jsonTextReader.ReadTokenWithDateParseHandlingNoneAsync(cancellationToken).ConfigureAwait(false); - return token.ToObject(_serializer); - } + public override async ValueTask DeserializeAsync(Stream stream, CancellationToken cancellationToken = default) + { + using var streamReader = new StreamReader(stream); + using var jsonTextReader = new JsonTextReader(streamReader); + var token = await jsonTextReader.ReadTokenWithDateParseHandlingNoneAsync(cancellationToken).ConfigureAwait(false); + return token.ToObject(_serializer); + } - public override async ValueTask DeserializeAsync(Type type, Stream stream, CancellationToken cancellationToken = default(CancellationToken)) - { - using var streamReader = new StreamReader(stream); - using var jsonTextReader = new JsonTextReader(streamReader); - var token = await jsonTextReader.ReadTokenWithDateParseHandlingNoneAsync(cancellationToken).ConfigureAwait(false); - return token.ToObject(type, _serializer); - } + public override async ValueTask DeserializeAsync(Type type, Stream stream, CancellationToken cancellationToken = default(CancellationToken)) + { + using var streamReader = new StreamReader(stream); + using var jsonTextReader = new JsonTextReader(streamReader); + var token = await jsonTextReader.ReadTokenWithDateParseHandlingNoneAsync(cancellationToken).ConfigureAwait(false); + return token.ToObject(type, _serializer); + } - public override void Serialize(T data, Stream stream, SerializationFormatting formatting = SerializationFormatting.None) - { - using var writer = new StreamWriter(stream, ExpectedEncoding, BufferSize, true); - using var jsonWriter = new JsonTextWriter(writer); - var serializer = formatting == SerializationFormatting.Indented ? _serializer : _collapsedSerializer; - serializer.Serialize(jsonWriter, data); - } + public override void Serialize(T data, Stream stream, SerializationFormatting formatting = SerializationFormatting.None) + { + using var writer = new StreamWriter(stream, ExpectedEncoding, BufferSize, true); + using var jsonWriter = new JsonTextWriter(writer); + var serializer = formatting == SerializationFormatting.Indented ? _serializer : _collapsedSerializer; + serializer.Serialize(jsonWriter, data); + } - public override Task SerializeAsync(T data, Stream stream, SerializationFormatting formatting = SerializationFormatting.None, - CancellationToken cancellationToken = default) - { - //This makes no sense now but we need the async method on the interface in 6.x so we can start swapping this out - //for an implementation that does make sense without having to wait for 7.x - Serialize(data, stream, formatting); - return CompletedTask; - } + public override Task SerializeAsync(T data, Stream stream, SerializationFormatting formatting = SerializationFormatting.None, + CancellationToken cancellationToken = default) + { + //This makes no sense now but we need the async method on the interface in 6.x so we can start swapping this out + //for an implementation that does make sense without having to wait for 7.x + Serialize(data, stream, formatting); + return CompletedTask; } } diff --git a/src/Elastic.Clients.Elasticsearch/Api/AsyncSearch/AsyncSearchSubmitRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/AsyncSearch/AsyncSearchSubmitRequest.cs index b8d5cbfec9c..9871821daf5 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/AsyncSearch/AsyncSearchSubmitRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/AsyncSearch/AsyncSearchSubmitRequest.cs @@ -5,29 +5,28 @@ using System; using Elastic.Clients.Elasticsearch.QueryDsl; -namespace Elastic.Clients.Elasticsearch.AsyncSearch +namespace Elastic.Clients.Elasticsearch.AsyncSearch; + +public partial class AsyncSearchSubmitRequest { - public partial class AsyncSearchSubmitRequest - { - // Any request may contain aggregations so we force typed_keys in order to successfully deserialise them. - internal override void BeforeRequest() => TypedKeys = true; - } + // Any request may contain aggregations so we force typed_keys in order to successfully deserialise them. + internal override void BeforeRequest() => TypedKeys = true; +} - public sealed partial class AsyncSearchSubmitRequestDescriptor - { - public AsyncSearchSubmitRequestDescriptor MatchAll(Action? selector = null) => selector is null ? Query(q => q.MatchAll()) : Query(q => q.MatchAll(selector)); +public sealed partial class AsyncSearchSubmitRequestDescriptor +{ + public AsyncSearchSubmitRequestDescriptor MatchAll(Action? selector = null) => selector is null ? Query(q => q.MatchAll()) : Query(q => q.MatchAll(selector)); - internal override void BeforeRequest() => TypedKeys(true); - } + internal override void BeforeRequest() => TypedKeys(true); +} - public sealed partial class AsyncSearchSubmitRequestDescriptor +public sealed partial class AsyncSearchSubmitRequestDescriptor +{ + public AsyncSearchSubmitRequestDescriptor MatchAll() { - public AsyncSearchSubmitRequestDescriptor MatchAll() - { - Query(new MatchAllQuery()); - return Self; - } - - internal override void BeforeRequest() => TypedKeys(true); + Query(new MatchAllQuery()); + return Self; } + + internal override void BeforeRequest() => TypedKeys(true); } diff --git a/src/Elastic.Clients.Elasticsearch/Api/AsyncSearch/GetAsyncSearchRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/AsyncSearch/GetAsyncSearchRequest.cs index 4979aace729..0df7e6e5abe 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/AsyncSearch/GetAsyncSearchRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/AsyncSearch/GetAsyncSearchRequest.cs @@ -2,23 +2,22 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch.AsyncSearch +namespace Elastic.Clients.Elasticsearch.AsyncSearch; + +public partial class GetAsyncSearchRequest { - public partial class GetAsyncSearchRequest - { - // Any request may contain aggregations so we force typed_keys in order to successfully deserialise them. - internal override void BeforeRequest() => TypedKeys = true; - } + // Any request may contain aggregations so we force typed_keys in order to successfully deserialise them. + internal override void BeforeRequest() => TypedKeys = true; +} - public sealed partial class GetAsyncSearchRequestDescriptor - { - // Any request may contain aggregations so we force typed_keys in order to successfully deserialise them. - internal override void BeforeRequest() => TypedKeys(true); - } +public sealed partial class GetAsyncSearchRequestDescriptor +{ + // Any request may contain aggregations so we force typed_keys in order to successfully deserialise them. + internal override void BeforeRequest() => TypedKeys(true); +} - public sealed partial class GetAsyncSearchRequestDescriptor - { - // Any request may contain aggregations so we force typed_keys in order to successfully deserialise them. - internal override void BeforeRequest() => TypedKeys(true); - } +public sealed partial class GetAsyncSearchRequestDescriptor +{ + // Any request may contain aggregations so we force typed_keys in order to successfully deserialise them. + internal override void BeforeRequest() => TypedKeys(true); } diff --git a/src/Elastic.Clients.Elasticsearch/Api/BulkRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/BulkRequest.cs index 02bc0bd8c51..d5bc8bfa624 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/BulkRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/BulkRequest.cs @@ -12,248 +12,247 @@ using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Clients.Elasticsearch.Requests; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public partial class BulkRequest : IStreamSerializable { - public partial class BulkRequest : IStreamSerializable - { - internal IRequest Self => this; + internal IRequest Self => this; - public BulkOperationsCollection Operations { get; set; } + public BulkOperationsCollection Operations { get; set; } - protected override string ContentType => "application/x-ndjson"; + protected override string ContentType => "application/x-ndjson"; - protected override string Accept => "application/json"; + protected override string Accept => "application/json"; - public void Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None) - { - if (Operations is null) - return; + public void Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None) + { + if (Operations is null) + return; - var index = Self.RouteValues.Get("index"); + var index = Self.RouteValues.Get("index"); - foreach (var op in Operations) - { - if (op is not IStreamSerializable serializable) - throw new InvalidOperationException(""); + foreach (var op in Operations) + { + if (op is not IStreamSerializable serializable) + throw new InvalidOperationException(""); - op.PrepareIndex(index); + op.PrepareIndex(index); - serializable.Serialize(stream, settings, formatting); - stream.WriteByte((byte)'\n'); - } + serializable.Serialize(stream, settings, formatting); + stream.WriteByte((byte)'\n'); } + } - public async Task SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None) - { - if (Operations is null) - return; + public async Task SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None) + { + if (Operations is null) + return; - var index = Self.RouteValues.Get("index"); + var index = Self.RouteValues.Get("index"); - foreach (var op in Operations) - { - if (op is not IStreamSerializable serializable) - throw new InvalidOperationException(""); + foreach (var op in Operations) + { + if (op is not IStreamSerializable serializable) + throw new InvalidOperationException(""); - op.PrepareIndex(index); + op.PrepareIndex(index); - await serializable.SerializeAsync(stream, settings, formatting).ConfigureAwait(false); - stream.WriteByte((byte)'\n'); - } + await serializable.SerializeAsync(stream, settings, formatting).ConfigureAwait(false); + stream.WriteByte((byte)'\n'); } } +} - public sealed partial class BulkRequestDescriptor : IStreamSerializable - { - protected override string ContentType => "application/x-ndjson"; +public sealed partial class BulkRequestDescriptor : IStreamSerializable +{ + protected override string ContentType => "application/x-ndjson"; - protected override string Accept => "application/json"; + protected override string Accept => "application/json"; - private readonly BulkOperationsCollection _operations = new(); + private readonly BulkOperationsCollection _operations = new(); - public BulkRequestDescriptor Index(string index) - { - RouteValues.Optional("index", IndexName.Parse(index)); - return Self; - } + public BulkRequestDescriptor Index(string index) + { + RouteValues.Optional("index", IndexName.Parse(index)); + return Self; + } - public BulkRequestDescriptor Create(TSource document, Action> configure = null) - { - var descriptor = new BulkCreateOperationDescriptor(document); - configure?.Invoke(descriptor); - _operations.Add(descriptor); - return this; - } + public BulkRequestDescriptor Create(TSource document, Action> configure = null) + { + var descriptor = new BulkCreateOperationDescriptor(document); + configure?.Invoke(descriptor); + _operations.Add(descriptor); + return this; + } - public BulkRequestDescriptor Create(TSource document, IndexName index, Action> configure = null) - { - var descriptor = new BulkCreateOperationDescriptor(document, index); - configure?.Invoke(descriptor); - _operations.Add(descriptor); - return this; - } + public BulkRequestDescriptor Create(TSource document, IndexName index, Action> configure = null) + { + var descriptor = new BulkCreateOperationDescriptor(document, index); + configure?.Invoke(descriptor); + _operations.Add(descriptor); + return this; + } - public BulkRequestDescriptor Index(TSource document, Action> configure = null) - { - var descriptor = new BulkIndexOperationDescriptor(document); - configure?.Invoke(descriptor); - _operations.Add(descriptor); - return this; - } + public BulkRequestDescriptor Index(TSource document, Action> configure = null) + { + var descriptor = new BulkIndexOperationDescriptor(document); + configure?.Invoke(descriptor); + _operations.Add(descriptor); + return this; + } - public BulkRequestDescriptor Index(TSource document, IndexName index, Action> configure = null) - { - var descriptor = new BulkIndexOperationDescriptor(document, index); - configure?.Invoke(descriptor); - _operations.Add(descriptor); - return this; - } + public BulkRequestDescriptor Index(TSource document, IndexName index, Action> configure = null) + { + var descriptor = new BulkIndexOperationDescriptor(document, index); + configure?.Invoke(descriptor); + _operations.Add(descriptor); + return this; + } - public BulkRequestDescriptor Update(BulkUpdateOperation update) - { - _operations.Add(update); - return this; - } + public BulkRequestDescriptor Update(BulkUpdateOperation update) + { + _operations.Add(update); + return this; + } - public BulkRequestDescriptor Update(Action> configure) - { - var descriptor = new BulkUpdateOperationDescriptor(); - configure?.Invoke(descriptor); - _operations.Add(descriptor); - return this; - } + public BulkRequestDescriptor Update(Action> configure) + { + var descriptor = new BulkUpdateOperationDescriptor(); + configure?.Invoke(descriptor); + _operations.Add(descriptor); + return this; + } - public BulkRequestDescriptor Update(Action> configure) => - Update(configure); + public BulkRequestDescriptor Update(Action> configure) => + Update(configure); - public BulkRequestDescriptor Delete(Id id, Action configure = null) - { - var descriptor = new BulkDeleteOperationDescriptor(id); - configure?.Invoke(descriptor); - _operations.Add(descriptor); - return this; - } + public BulkRequestDescriptor Delete(Id id, Action configure = null) + { + var descriptor = new BulkDeleteOperationDescriptor(id); + configure?.Invoke(descriptor); + _operations.Add(descriptor); + return this; + } - public BulkRequestDescriptor Delete(string id, Action configure = null) - { - var descriptor = new BulkDeleteOperationDescriptor(id); - configure?.Invoke(descriptor); - _operations.Add(descriptor); - return this; - } + public BulkRequestDescriptor Delete(string id, Action configure = null) + { + var descriptor = new BulkDeleteOperationDescriptor(id); + configure?.Invoke(descriptor); + _operations.Add(descriptor); + return this; + } - public BulkRequestDescriptor Delete(Action configure) - { - var descriptor = new BulkDeleteOperationDescriptor(); - configure?.Invoke(descriptor); - _operations.Add(descriptor); - return this; - } + public BulkRequestDescriptor Delete(Action configure) + { + var descriptor = new BulkDeleteOperationDescriptor(); + configure?.Invoke(descriptor); + _operations.Add(descriptor); + return this; + } - public BulkRequestDescriptor Delete(TSource documentToDelete, Action configure = null) - { - var descriptor = new BulkDeleteOperationDescriptor(new Id(documentToDelete)); - configure?.Invoke(descriptor); - _operations.Add(descriptor); - return this; - } + public BulkRequestDescriptor Delete(TSource documentToDelete, Action configure = null) + { + var descriptor = new BulkDeleteOperationDescriptor(new Id(documentToDelete)); + configure?.Invoke(descriptor); + _operations.Add(descriptor); + return this; + } - public BulkRequestDescriptor Delete(Action configure) => Delete(configure); + public BulkRequestDescriptor Delete(Action configure) => Delete(configure); - public BulkRequestDescriptor CreateMany(IEnumerable documents, Action, TSource> bulkCreateSelector) => - AddOperations(documents, bulkCreateSelector, o => new BulkCreateOperationDescriptor(o)); + public BulkRequestDescriptor CreateMany(IEnumerable documents, Action, TSource> bulkCreateSelector) => + AddOperations(documents, bulkCreateSelector, o => new BulkCreateOperationDescriptor(o)); - public BulkRequestDescriptor CreateMany(IEnumerable documents) => - AddOperations(documents, null, o => new BulkCreateOperationDescriptor(o)); + public BulkRequestDescriptor CreateMany(IEnumerable documents) => + AddOperations(documents, null, o => new BulkCreateOperationDescriptor(o)); - public BulkRequestDescriptor IndexMany(IEnumerable documents, Action, TSource> bulkIndexSelector) => - AddOperations(documents, bulkIndexSelector, o => new BulkIndexOperationDescriptor(o)); + public BulkRequestDescriptor IndexMany(IEnumerable documents, Action, TSource> bulkIndexSelector) => + AddOperations(documents, bulkIndexSelector, o => new BulkIndexOperationDescriptor(o)); - public BulkRequestDescriptor IndexMany(IEnumerable documents) => - AddOperations(documents, null, o => new BulkIndexOperationDescriptor(o)); + public BulkRequestDescriptor IndexMany(IEnumerable documents) => + AddOperations(documents, null, o => new BulkIndexOperationDescriptor(o)); - public BulkRequestDescriptor UpdateMany(IEnumerable objects, Action, TSource> bulkIndexSelector) => - AddOperations(objects, bulkIndexSelector, o => new BulkUpdateOperationDescriptor().IdFrom(o)); + public BulkRequestDescriptor UpdateMany(IEnumerable objects, Action, TSource> bulkIndexSelector) => + AddOperations(objects, bulkIndexSelector, o => new BulkUpdateOperationDescriptor().IdFrom(o)); - public BulkRequestDescriptor UpdateMany(IEnumerable objects) => - AddOperations(objects, null, o => new BulkUpdateOperationDescriptor().IdFrom(o)); + public BulkRequestDescriptor UpdateMany(IEnumerable objects) => + AddOperations(objects, null, o => new BulkUpdateOperationDescriptor().IdFrom(o)); - public BulkRequestDescriptor DeleteMany(IEnumerable objects, Action bulkDeleteSelector) => - AddOperations(objects, bulkDeleteSelector, obj => new BulkDeleteOperationDescriptor(new Id(obj))); + public BulkRequestDescriptor DeleteMany(IEnumerable objects, Action bulkDeleteSelector) => + AddOperations(objects, bulkDeleteSelector, obj => new BulkDeleteOperationDescriptor(new Id(obj))); - public BulkRequestDescriptor DeleteMany(IEnumerable ids, Action bulkDeleteSelector) => - AddOperations(ids, bulkDeleteSelector, id => new BulkDeleteOperationDescriptor(id)); + public BulkRequestDescriptor DeleteMany(IEnumerable ids, Action bulkDeleteSelector) => + AddOperations(ids, bulkDeleteSelector, id => new BulkDeleteOperationDescriptor(id)); - public BulkRequestDescriptor DeleteMany(IEnumerable objects) => - AddOperations(objects, null, obj => new BulkDeleteOperationDescriptor(obj)); + public BulkRequestDescriptor DeleteMany(IEnumerable objects) => + AddOperations(objects, null, obj => new BulkDeleteOperationDescriptor(obj)); - public BulkRequestDescriptor DeleteMany(IndexName index, IEnumerable ids) => - AddOperations(ids, null, id => new BulkDeleteOperationDescriptor(id).Index(index)); + public BulkRequestDescriptor DeleteMany(IndexName index, IEnumerable ids) => + AddOperations(ids, null, id => new BulkDeleteOperationDescriptor(id).Index(index)); - public void Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None) - { - if (_operations is null) - return; + public void Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None) + { + if (_operations is null) + return; - var index = Self.RouteValues.Get("index"); + var index = Self.RouteValues.Get("index"); - foreach (var op in _operations) - { - if (op is not IStreamSerializable serializable) - throw new InvalidOperationException(""); + foreach (var op in _operations) + { + if (op is not IStreamSerializable serializable) + throw new InvalidOperationException(""); - op.PrepareIndex(index); + op.PrepareIndex(index); - serializable.Serialize(stream, settings, formatting); - stream.WriteByte((byte)'\n'); - } + serializable.Serialize(stream, settings, formatting); + stream.WriteByte((byte)'\n'); } + } - public async Task SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None) - { - if (_operations is null) - return; + public async Task SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None) + { + if (_operations is null) + return; - var index = Self.RouteValues.Get("index"); + var index = Self.RouteValues.Get("index"); - foreach (var op in _operations) - { - if (op is not IStreamSerializable serializable) - throw new InvalidOperationException(""); + foreach (var op in _operations) + { + if (op is not IStreamSerializable serializable) + throw new InvalidOperationException(""); - op.PrepareIndex(index); + op.PrepareIndex(index); - await serializable.SerializeAsync(stream, settings, formatting).ConfigureAwait(false); - stream.WriteByte((byte)'\n'); - } + await serializable.SerializeAsync(stream, settings, formatting).ConfigureAwait(false); + stream.WriteByte((byte)'\n'); } + } - private BulkRequestDescriptor AddOperations( - IEnumerable objects, - Action configureDescriptor, - Func createDescriptor - ) where TDescriptor : IBulkOperation - { - if (@objects == null) - return this; - - var objectsList = @objects.ToList(); - var operations = new List(objectsList.Count()); + private BulkRequestDescriptor AddOperations( + IEnumerable objects, + Action configureDescriptor, + Func createDescriptor + ) where TDescriptor : IBulkOperation + { + if (@objects == null) + return this; - foreach (var o in objectsList) - { - var descriptor = createDescriptor(o); + var objectsList = @objects.ToList(); + var operations = new List(objectsList.Count()); - if (configureDescriptor is not null) - { - configureDescriptor(descriptor, o); - } + foreach (var o in objectsList) + { + var descriptor = createDescriptor(o); - operations.Add(descriptor); + if (configureDescriptor is not null) + { + configureDescriptor(descriptor, o); } - _operations.AddRange(operations); - return Self; + operations.Add(descriptor); } + + _operations.AddRange(operations); + return Self; } } diff --git a/src/Elastic.Clients.Elasticsearch/Api/BulkResponse.cs b/src/Elastic.Clients.Elasticsearch/Api/BulkResponse.cs index d81b6f3a104..f38c477ee5c 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/BulkResponse.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/BulkResponse.cs @@ -8,28 +8,27 @@ using System.Linq; using Elastic.Clients.Elasticsearch.Core.Bulk; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public partial class BulkResponse { - public partial class BulkResponse - { - [JsonConverter(typeof(BulkResponseItemConverter)), JsonPropertyName("items")] - public IReadOnlyList Items { get; init; } + [JsonConverter(typeof(BulkResponseItemConverter)), JsonPropertyName("items")] + public IReadOnlyList Items { get; init; } - [JsonIgnore] - public IEnumerable ItemsWithErrors => !Items.HasAny() - ? Enumerable.Empty() - : Items.Where(i => !i.IsValid); + [JsonIgnore] + public IEnumerable ItemsWithErrors => !Items.HasAny() + ? Enumerable.Empty() + : Items.Where(i => !i.IsValid); - public override bool IsValid => base.IsValid && !Errors && !ItemsWithErrors.HasAny(); + public override bool IsValid => base.IsValid && !Errors && !ItemsWithErrors.HasAny(); - protected override void DebugIsValid(StringBuilder sb) - { - if (Items == null) - return; + protected override void DebugIsValid(StringBuilder sb) + { + if (Items == null) + return; - sb.AppendLine($"# Invalid Bulk items:"); - foreach (var i in Items.Select((item, i) => new { item, i }).Where(i => !i.item.IsValid)) - sb.AppendLine($" operation[{i.i}]: {i.item}"); - } + sb.AppendLine($"# Invalid Bulk items:"); + foreach (var i in Items.Select((item, i) => new { item, i }).Where(i => !i.item.IsValid)) + sb.AppendLine($" operation[{i.i}]: {i.item}"); } } diff --git a/src/Elastic.Clients.Elasticsearch/Api/CountRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/CountRequest.cs index 82b78f99fac..4087c60138b 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/CountRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/CountRequest.cs @@ -5,37 +5,36 @@ using System; using Elastic.Clients.Elasticsearch.QueryDsl; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public sealed partial class CountRequest : CountRequest { - public sealed partial class CountRequest : CountRequest - { - //protected CountRequest TypedSelf => this; + //protected CountRequest TypedSelf => this; - ////{index}/_count - public CountRequest() : base(typeof(TDocument)) - { - } + ////{index}/_count + public CountRequest() : base(typeof(TDocument)) + { + } - ////{index}/_count - ///Optional, accepts null - public CountRequest(Indices index) : base(index) - { - } + ////{index}/_count + ///Optional, accepts null + public CountRequest(Indices index) : base(index) + { } +} - public partial class CountRequestDescriptor +public partial class CountRequestDescriptor +{ + public CountRequestDescriptor Index(Indices indices) { - public CountRequestDescriptor Index(Indices indices) - { - RouteValues.Optional("index", indices); - return Self; - } + RouteValues.Optional("index", indices); + return Self; + } - public CountRequestDescriptor Query(Func configure) - { - var container = configure?.Invoke(new QueryContainerDescriptor()); - QueryValue = container; - return Self; - } + public CountRequestDescriptor Query(Func configure) + { + var container = configure?.Invoke(new QueryContainerDescriptor()); + QueryValue = container; + return Self; } } diff --git a/src/Elastic.Clients.Elasticsearch/Api/CreateRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/CreateRequest.cs index 54ac0d80058..4e03c9f85f0 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/CreateRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/CreateRequest.cs @@ -6,19 +6,18 @@ using Elastic.Transport; using System.Text.Json; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public sealed partial class CreateRequest : ICustomJsonWriter { - public sealed partial class CreateRequest : ICustomJsonWriter - { - public CreateRequest(Id id) : this(typeof(TDocument), id) - { - } + public CreateRequest(Id id) : this(typeof(TDocument), id) + { + } - public CreateRequest(TDocument documentWithId, IndexName index = null, Id id = null) - : this(index ?? typeof(TDocument), id ?? Id.From(documentWithId)) => - Document = documentWithId; + public CreateRequest(TDocument documentWithId, IndexName index = null, Id id = null) + : this(index ?? typeof(TDocument), id ?? Id.From(documentWithId)) => + Document = documentWithId; - public void WriteJson(Utf8JsonWriter writer, Serializer sourceSerializer) => SourceSerialisation.Serialize(Document, writer, sourceSerializer); - } + public void WriteJson(Utf8JsonWriter writer, Serializer sourceSerializer) => SourceSerialisation.Serialize(Document, writer, sourceSerializer); } diff --git a/src/Elastic.Clients.Elasticsearch/Api/DeleteRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/DeleteRequest.cs index 43d0131d409..c2a6e9ceb67 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/DeleteRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/DeleteRequest.cs @@ -2,16 +2,15 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch -{ - public sealed partial class DeleteRequest : DeleteRequest - { - public DeleteRequest(IndexName index, Id id) : base(index, id) { } +namespace Elastic.Clients.Elasticsearch; - public DeleteRequest(Id id) : this(typeof(TDocument), id) - { - } +public sealed partial class DeleteRequest : DeleteRequest +{ + public DeleteRequest(IndexName index, Id id) : base(index, id) { } - public DeleteRequest(TDocument documentWithId, IndexName index = null, Id id = null) : this(index ?? typeof(TDocument), id ?? Id.From(documentWithId)) { } + public DeleteRequest(Id id) : this(typeof(TDocument), id) + { } + + public DeleteRequest(TDocument documentWithId, IndexName index = null, Id id = null) : this(index ?? typeof(TDocument), id ?? Id.From(documentWithId)) { } } diff --git a/src/Elastic.Clients.Elasticsearch/Api/Eql/GetEqlResponse.cs b/src/Elastic.Clients.Elasticsearch/Api/Eql/GetEqlResponse.cs index 47e18383248..f512047e948 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/Eql/GetEqlResponse.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/Eql/GetEqlResponse.cs @@ -5,23 +5,22 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch.Eql +namespace Elastic.Clients.Elasticsearch.Eql; + +public partial class GetEqlResponse { - public partial class GetEqlResponse - { - private IReadOnlyCollection> _events; - private IReadOnlyCollection> _sequences; + private IReadOnlyCollection> _events; + private IReadOnlyCollection> _sequences; - [JsonIgnore] - public IReadOnlyCollection> Events => - _events ??= Hits?.Events ?? EmptyReadOnly>.Collection; + [JsonIgnore] + public IReadOnlyCollection> Events => + _events ??= Hits?.Events ?? EmptyReadOnly>.Collection; - [JsonIgnore] - public IReadOnlyCollection> Sequences => - _sequences ??= Hits?.Sequences ?? EmptyReadOnly>.Collection; + [JsonIgnore] + public IReadOnlyCollection> Sequences => + _sequences ??= Hits?.Sequences ?? EmptyReadOnly>.Collection; - [JsonIgnore] - public long Total => Hits?.Total.Value ?? -1; - } + [JsonIgnore] + public long Total => Hits?.Total.Value ?? -1; } diff --git a/src/Elastic.Clients.Elasticsearch/Api/ExistsRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/ExistsRequest.cs index 327735e67f6..abb03eb618c 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/ExistsRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/ExistsRequest.cs @@ -7,12 +7,11 @@ using System.Linq; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public partial class ExistsRequest { - public partial class ExistsRequest + public ExistsRequest(Type type, Id id) : base(r => r.Required("index", Infer.Index(type)).Required("id", id)) { - public ExistsRequest(Type type, Id id) : base(r => r.Required("index", Infer.Index(type)).Required("id", id)) - { - } } } diff --git a/src/Elastic.Clients.Elasticsearch/Api/IndexRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/IndexRequest.cs index 09e6e4d527f..389f5e74780 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/IndexRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/IndexRequest.cs @@ -8,43 +8,42 @@ using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public partial class IndexRequest : ICustomJsonWriter { - public partial class IndexRequest : ICustomJsonWriter - { - public IndexRequest() : this(typeof(TDocument)) { } + public IndexRequest() : this(typeof(TDocument)) { } - //public IndexRequest(TDocument document) : this(typeof(TDocument)) => Document = document; + //public IndexRequest(TDocument document) : this(typeof(TDocument)) => Document = document; - public IndexRequest(TDocument document, Id id) : this(typeof(TDocument), id) => Document = document; + public IndexRequest(TDocument document, Id id) : this(typeof(TDocument), id) => Document = document; - protected override HttpMethod? DynamicHttpMethod => GetHttpMethod(this); + protected override HttpMethod? DynamicHttpMethod => GetHttpMethod(this); - public IndexRequest(TDocument document, IndexName index = null, Id id = null) : this(index ?? typeof(TDocument), id ?? Id.From(document)) => Document = document; + public IndexRequest(TDocument document, IndexName index = null, Id id = null) : this(index ?? typeof(TDocument), id ?? Id.From(document)) => Document = document; - internal IRequest Self => this; + internal IRequest Self => this; - [JsonIgnore] private Id? Id => Self.RouteValues.Get("id"); + [JsonIgnore] private Id? Id => Self.RouteValues.Get("id"); - void ICustomJsonWriter.WriteJson(Utf8JsonWriter writer, Serializer sourceSerializer) => SourceSerialisation.Serialize(Document, writer, sourceSerializer); + void ICustomJsonWriter.WriteJson(Utf8JsonWriter writer, Serializer sourceSerializer) => SourceSerialisation.Serialize(Document, writer, sourceSerializer); - internal static HttpMethod GetHttpMethod(IndexRequest request) => - request.Id?.StringOrLongValue != null || request.Self.RouteValues.ContainsId ? HttpMethod.PUT : HttpMethod.POST; - } + internal static HttpMethod GetHttpMethod(IndexRequest request) => + request.Id?.StringOrLongValue != null || request.Self.RouteValues.ContainsId ? HttpMethod.PUT : HttpMethod.POST; +} - public sealed partial class IndexRequestDescriptor : ICustomJsonWriter +public sealed partial class IndexRequestDescriptor : ICustomJsonWriter +{ + // TODO: Codegen + public IndexRequestDescriptor Document(TDocument document) { - // TODO: Codegen - public IndexRequestDescriptor Document(TDocument document) - { - DocumentValue = document; - return Self; - } + DocumentValue = document; + return Self; + } - internal Id _id; + internal Id _id; - public void WriteJson(Utf8JsonWriter writer, Serializer sourceSerializer) => SourceSerialisation.Serialize(DocumentValue, writer, sourceSerializer); + public void WriteJson(Utf8JsonWriter writer, Serializer sourceSerializer) => SourceSerialisation.Serialize(DocumentValue, writer, sourceSerializer); - protected override HttpMethod? DynamicHttpMethod => _id is not null || RouteValues.ContainsId ? HttpMethod.PUT : HttpMethod.POST; - } + protected override HttpMethod? DynamicHttpMethod => _id is not null || RouteValues.ContainsId ? HttpMethod.PUT : HttpMethod.POST; } diff --git a/src/Elastic.Clients.Elasticsearch/Api/ResponseItem.cs b/src/Elastic.Clients.Elasticsearch/Api/ResponseItem.cs index 79729ad31c6..cf6c182f8a4 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/ResponseItem.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/ResponseItem.cs @@ -2,26 +2,25 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch.Core.Bulk +namespace Elastic.Clients.Elasticsearch.Core.Bulk; + +public abstract partial class ResponseItem { - public abstract partial class ResponseItem - { - public abstract string Operation { get; } + public abstract string Operation { get; } - public bool IsValid + public bool IsValid + { + get { - get - { - if (Error is not null) - return false; + if (Error is not null) + return false; - return Operation.ToLowerInvariant() switch - { - "delete" => Status == 200 || Status == 404, - "update" or "index" or "create" => Status == 200 || Status == 201, - _ => false, - }; - } + return Operation.ToLowerInvariant() switch + { + "delete" => Status == 200 || Status == 404, + "update" or "index" or "create" => Status == 200 || Status == 201, + _ => false, + }; } } } diff --git a/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs index ddf31f555f2..46358a9bd93 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs @@ -5,69 +5,68 @@ using System; using Elastic.Clients.Elasticsearch.Requests; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public partial class SearchRequest { - public partial class SearchRequest + internal override void BeforeRequest() { - internal override void BeforeRequest() + if (Aggregations is not null) { - if (Aggregations is not null) - { - TypedKeys = true; - } + TypedKeys = true; } + } - protected override string ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) + protected override string ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) + { + if (Pit is not null && !string.IsNullOrEmpty(Pit.Id ?? string.Empty) && routeValues.ContainsKey("index")) { - if (Pit is not null && !string.IsNullOrEmpty(Pit.Id ?? string.Empty) && routeValues.ContainsKey("index")) - { - routeValues.Remove("index"); - } - - return base.ResolveUrl(routeValues, settings); + routeValues.Remove("index"); } + + return base.ResolveUrl(routeValues, settings); } +} - public partial class SearchRequest +public partial class SearchRequest +{ + public SearchRequest(Indices? indices) : base(indices) { - public SearchRequest(Indices? indices) : base(indices) - { - } } - - public sealed partial class SearchRequestDescriptor +} + +public sealed partial class SearchRequestDescriptor +{ + public SearchRequestDescriptor Index(Indices indices) + { + Self.RouteValues.Optional("index", indices); + return Self; + } + + public SearchRequestDescriptor Pit(string id, Action configure) { - public SearchRequestDescriptor Index(Indices indices) - { - Self.RouteValues.Optional("index", indices); - return Self; - } + PitValue = null; + PitDescriptorAction = null; + configure += a => a.Id(id); + PitDescriptorAction = configure; + return Self; + } - public SearchRequestDescriptor Pit(string id, Action configure) + internal override void BeforeRequest() + { + if (AggregationsValue is not null || AggregationsDescriptor is not null || AggregationsDescriptorAction is not null) { - PitValue = null; - PitDescriptorAction = null; - configure += a => a.Id(id); - PitDescriptorAction = configure; - return Self; + TypedKeys(true); } + } - internal override void BeforeRequest() + protected override string ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) + { + if ((Self.PitValue is not null || Self.PitDescriptor is not null || Self.PitDescriptorAction is not null) && routeValues.ContainsKey("index")) { - if (AggregationsValue is not null || AggregationsDescriptor is not null || AggregationsDescriptorAction is not null) - { - TypedKeys(true); - } + routeValues.Remove("index"); } - protected override string ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) - { - if ((Self.PitValue is not null || Self.PitDescriptor is not null || Self.PitDescriptorAction is not null) && routeValues.ContainsKey("index")) - { - routeValues.Remove("index"); - } - - return base.ResolveUrl(routeValues, settings); - } + return base.ResolveUrl(routeValues, settings); } } diff --git a/src/Elastic.Clients.Elasticsearch/Api/SourceRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/SourceRequest.cs index 3f34a52e8d0..656e2706b6e 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/SourceRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/SourceRequest.cs @@ -2,23 +2,22 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch -{ - // TODO - Should be added as a rule to the descriptor generator - //public sealed partial class SourceRequestDescriptor - //{ - // public SourceRequestDescriptor(TDocument documentWithId, IndexName index = null, Id id = null) : this(index ?? typeof(TDocument), id ?? Id.From(documentWithId)) => Doc - //} +namespace Elastic.Clients.Elasticsearch; + +// TODO - Should be added as a rule to the descriptor generator +//public sealed partial class SourceRequestDescriptor +//{ +// public SourceRequestDescriptor(TDocument documentWithId, IndexName index = null, Id id = null) : this(index ?? typeof(TDocument), id ?? Id.From(documentWithId)) => Doc +//} - public partial class SourceRequestDescriptor +public partial class SourceRequestDescriptor +{ + /// + /// A shortcut into calling Index(typeof(TOther)). + /// + public SourceRequestDescriptor Index() { - /// - /// A shortcut into calling Index(typeof(TOther)). - /// - public SourceRequestDescriptor Index() - { - RouteValues.Required("index", (IndexName)typeof(TOther)); - return Self; - } + RouteValues.Required("index", (IndexName)typeof(TOther)); + return Self; } } diff --git a/src/Elastic.Clients.Elasticsearch/Api/SourceResponse.cs b/src/Elastic.Clients.Elasticsearch/Api/SourceResponse.cs index 1e2cb42467e..4e7b2b9014c 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/SourceResponse.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/SourceResponse.cs @@ -6,26 +6,25 @@ using System.IO; using Elastic.Clients.Elasticsearch.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public partial class SourceResponse : ISelfDeserializable { - public partial class SourceResponse : ISelfDeserializable - { - public TDocument Body { get; set; } + public TDocument Body { get; set; } - public void Deserialize(ref Utf8JsonReader reader, JsonSerializerOptions options, IElasticsearchClientSettings settings) - { - using var jsonDoc = JsonSerializer.Deserialize(ref reader); + public void Deserialize(ref Utf8JsonReader reader, JsonSerializerOptions options, IElasticsearchClientSettings settings) + { + using var jsonDoc = JsonSerializer.Deserialize(ref reader); - using var stream = new MemoryStream(); + using var stream = new MemoryStream(); - var writer = new Utf8JsonWriter(stream); - jsonDoc.WriteTo(writer); - writer.Flush(); - stream.Position = 0; + var writer = new Utf8JsonWriter(stream); + jsonDoc.WriteTo(writer); + writer.Flush(); + stream.Position = 0; - var body = settings.SourceSerializer.Deserialize(stream); + var body = settings.SourceSerializer.Deserialize(stream); - Body = body; - } + Body = body; } } diff --git a/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient-Manual.cs b/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient-Manual.cs index 45bcf238e85..11c0ec5f9dd 100644 --- a/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient-Manual.cs +++ b/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient-Manual.cs @@ -6,34 +6,33 @@ using System.Threading.Tasks; using System.Threading; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public partial class ElasticsearchClient { - public partial class ElasticsearchClient + public Task> UpdateAsync(IndexName index, Id id, CancellationToken cancellationToken = default) { - public Task> UpdateAsync(IndexName index, Id id, CancellationToken cancellationToken = default) - { - var descriptor = new UpdateRequestDescriptor(index, id); - return DoRequestAsync, UpdateResponse>(descriptor); - } + var descriptor = new UpdateRequestDescriptor(index, id); + return DoRequestAsync, UpdateResponse>(descriptor); + } - public Task> UpdateAsync(IndexName index, Id id, Action> configureRequest, CancellationToken cancellationToken = default) - { - var descriptor = new UpdateRequestDescriptor(index, id); - configureRequest?.Invoke(descriptor); - return DoRequestAsync, UpdateResponse>(descriptor); - } + public Task> UpdateAsync(IndexName index, Id id, Action> configureRequest, CancellationToken cancellationToken = default) + { + var descriptor = new UpdateRequestDescriptor(index, id); + configureRequest?.Invoke(descriptor); + return DoRequestAsync, UpdateResponse>(descriptor); + } - public UpdateResponse Update(IndexName index, Id id) - { - var descriptor = new UpdateRequestDescriptor(index, id); - return DoRequest, UpdateResponse>(descriptor); - } + public UpdateResponse Update(IndexName index, Id id) + { + var descriptor = new UpdateRequestDescriptor(index, id); + return DoRequest, UpdateResponse>(descriptor); + } - public UpdateResponse Update(IndexName index, Id id, Action> configureRequest) - { - var descriptor = new UpdateRequestDescriptor(index, id); - configureRequest?.Invoke(descriptor); - return DoRequest, UpdateResponse>(descriptor); - } + public UpdateResponse Update(IndexName index, Id id, Action> configureRequest) + { + var descriptor = new UpdateRequestDescriptor(index, id); + configureRequest?.Invoke(descriptor); + return DoRequest, UpdateResponse>(descriptor); } } diff --git a/src/Elastic.Clients.Elasticsearch/Client/NamespacedClientProxy.cs b/src/Elastic.Clients.Elasticsearch/Client/NamespacedClientProxy.cs index 3a5c1dc0424..fa6332ae7e6 100644 --- a/src/Elastic.Clients.Elasticsearch/Client/NamespacedClientProxy.cs +++ b/src/Elastic.Clients.Elasticsearch/Client/NamespacedClientProxy.cs @@ -8,56 +8,55 @@ using Elastic.Clients.Elasticsearch.Requests; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +/// +/// +/// Not intended to be used directly. +/// +public class NamespacedClientProxy { - /// - /// - /// - /// Not intended to be used directly. - /// - public class NamespacedClientProxy - { - private readonly ElasticsearchClient _client; - - internal NamespacedClientProxy(ElasticsearchClient client) => _client = client; - - internal TResponse DoRequest( - TRequest request, - IRequestParameters parameters, - Action? forceConfiguration = null) - where TRequest : class, IRequest - where TResponse : class, ITransportResponse, new() => - _client.DoRequest(request, parameters, forceConfiguration); - - internal TResponse DoRequest( - TRequest request, - Action? forceConfiguration = null) - where TRequest : class, IRequest - where TResponse : class, ITransportResponse, new() => - _client.DoRequest(request, forceConfiguration); - - internal Task DoRequestAsync( - TRequest request, - IRequestParameters parameters, - CancellationToken cancellationToken = default) - where TRequest : class, IRequest - where TResponse : class, ITransportResponse, new() => - _client.DoRequestAsync(request, parameters, cancellationToken: cancellationToken); - - internal Task DoRequestAsync( - TRequest request, - CancellationToken cancellationToken = default) - where TRequest : class, IRequest - where TResponse : class, ITransportResponse, new() => - _client.DoRequestAsync(request, cancellationToken: cancellationToken); - - internal Task DoRequestAsync( - TRequest request, - IRequestParameters parameters, - Action? forceConfiguration, - CancellationToken cancellationToken = default) - where TRequest : class, IRequest - where TResponse : class, ITransportResponse, new() => - _client.DoRequestAsync(request, parameters, forceConfiguration, cancellationToken); - } + private readonly ElasticsearchClient _client; + + internal NamespacedClientProxy(ElasticsearchClient client) => _client = client; + + internal TResponse DoRequest( + TRequest request, + IRequestParameters parameters, + Action? forceConfiguration = null) + where TRequest : class, IRequest + where TResponse : class, ITransportResponse, new() => + _client.DoRequest(request, parameters, forceConfiguration); + + internal TResponse DoRequest( + TRequest request, + Action? forceConfiguration = null) + where TRequest : class, IRequest + where TResponse : class, ITransportResponse, new() => + _client.DoRequest(request, forceConfiguration); + + internal Task DoRequestAsync( + TRequest request, + IRequestParameters parameters, + CancellationToken cancellationToken = default) + where TRequest : class, IRequest + where TResponse : class, ITransportResponse, new() => + _client.DoRequestAsync(request, parameters, cancellationToken: cancellationToken); + + internal Task DoRequestAsync( + TRequest request, + CancellationToken cancellationToken = default) + where TRequest : class, IRequest + where TResponse : class, ITransportResponse, new() => + _client.DoRequestAsync(request, cancellationToken: cancellationToken); + + internal Task DoRequestAsync( + TRequest request, + IRequestParameters parameters, + Action? forceConfiguration, + CancellationToken cancellationToken = default) + where TRequest : class, IRequest + where TResponse : class, ITransportResponse, new() => + _client.DoRequestAsync(request, parameters, forceConfiguration, cancellationToken); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Configuration/ClrTypeDefaults.cs b/src/Elastic.Clients.Elasticsearch/Common/Configuration/ClrTypeDefaults.cs index 8cfd369bc8c..18759b25600 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Configuration/ClrTypeDefaults.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Configuration/ClrTypeDefaults.cs @@ -6,113 +6,112 @@ using System.Linq.Expressions; using Elastic.Clients.Elasticsearch.Fluent; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public class ClrTypeMapping +{ + /// + /// Initializes a new instance of . + /// + public ClrTypeMapping(Type type) => ClrType = type; + + /// + /// The CLR type the mapping relates to. + /// + public Type ClrType { get; } + + /// + /// The property for the given to resolve IDs from. + /// + public string IdPropertyName { get; set; } + + /// + /// The default Elasticsearch index name for the given . + /// + public string IndexName { get; set; } + + /// + /// The relation name for the given to resolve to. + /// + public string RelationName { get; set; } + + /// + /// Disables ID inference for the given . + /// By default, the _id value for a document is inferred from a property named Id, + /// or from the property named by , if set. + /// + public bool DisableIdInference { get; set; } +} + +public sealed class ClrTypeMapping : ClrTypeMapping +{ + public ClrTypeMapping() : base(typeof(TDocument)) { } + + /// + /// Set a default Id property on CLR type that NEST will evaluate + /// + public Expression> IdProperty { get; set; } + + /// + /// Provide a default routing parameter lookup based on + /// + public Expression> RoutingProperty { get; set; } +} + +public sealed class ClrTypeMappingDescriptor : Descriptor +{ + internal Type _clrType; + internal string _indexName; + internal string _relationName; + internal string _idProperty; + internal bool _disableIdInference; + + /// + /// Instantiates a new instance of + /// + /// The CLR type to map + public ClrTypeMappingDescriptor(Type type) => _clrType = type; + + /// + public ClrTypeMappingDescriptor IndexName(string indexName) => Assign(indexName, (a, v) => a._indexName = v); + + /// + public ClrTypeMappingDescriptor RelationName(string relationName) => Assign(relationName, (a, v) => a._relationName = v); + + /// + public ClrTypeMappingDescriptor IdProperty(string idProperty) => Assign(idProperty, (a, v) => a._idProperty = v); + + /// + public ClrTypeMappingDescriptor DisableIdInference(bool disable = true) => Assign(disable, (a, v) => a._disableIdInference = v); +} + +public sealed class ClrTypeMappingDescriptor : Descriptor> { - public class ClrTypeMapping - { - /// - /// Initializes a new instance of . - /// - public ClrTypeMapping(Type type) => ClrType = type; - - /// - /// The CLR type the mapping relates to. - /// - public Type ClrType { get; } - - /// - /// The property for the given to resolve IDs from. - /// - public string IdPropertyName { get; set; } - - /// - /// The default Elasticsearch index name for the given . - /// - public string IndexName { get; set; } - - /// - /// The relation name for the given to resolve to. - /// - public string RelationName { get; set; } - - /// - /// Disables ID inference for the given . - /// By default, the _id value for a document is inferred from a property named Id, - /// or from the property named by , if set. - /// - public bool DisableIdInference { get; set; } - } - - public sealed class ClrTypeMapping : ClrTypeMapping - { - public ClrTypeMapping() : base(typeof(TDocument)) { } - - /// - /// Set a default Id property on CLR type that NEST will evaluate - /// - public Expression> IdProperty { get; set; } - - /// - /// Provide a default routing parameter lookup based on - /// - public Expression> RoutingProperty { get; set; } - } - - public sealed class ClrTypeMappingDescriptor : Descriptor - { - internal Type _clrType; - internal string _indexName; - internal string _relationName; - internal string _idProperty; - internal bool _disableIdInference; - - /// - /// Instantiates a new instance of - /// - /// The CLR type to map - public ClrTypeMappingDescriptor(Type type) => _clrType = type; - - /// - public ClrTypeMappingDescriptor IndexName(string indexName) => Assign(indexName, (a, v) => a._indexName = v); - - /// - public ClrTypeMappingDescriptor RelationName(string relationName) => Assign(relationName, (a, v) => a._relationName = v); - - /// - public ClrTypeMappingDescriptor IdProperty(string idProperty) => Assign(idProperty, (a, v) => a._idProperty = v); - - /// - public ClrTypeMappingDescriptor DisableIdInference(bool disable = true) => Assign(disable, (a, v) => a._disableIdInference = v); - } - - public sealed class ClrTypeMappingDescriptor : Descriptor> - { - internal Type _clrType = typeof(TDocument); - internal string _indexName; - internal string _relationName; - internal string _idProperty; - internal bool _disableIdInference; - - internal Expression> _idPropertyExpression; - internal Expression> _routingPropertyExpression; - - /// - public ClrTypeMappingDescriptor IndexName(string indexName) => Assign(indexName, (a, v) => a._indexName = v); - - /// - public ClrTypeMappingDescriptor RelationName(string relationName) => Assign(relationName, (a, v) => a._relationName = v); - - /// - public ClrTypeMappingDescriptor IdProperty(Expression> property) => Assign(property, (a, v) => a._idPropertyExpression = v); - - /// - public ClrTypeMappingDescriptor IdProperty(string property) => Assign(property, (a, v) => a._idProperty = v); - - /// - public ClrTypeMappingDescriptor RoutingProperty(Expression> property) => - Assign(property, (a, v) => a._routingPropertyExpression = v); - - /// - public ClrTypeMappingDescriptor DisableIdInference(bool disable = true) => Assign(disable, (a, v) => a._disableIdInference = v); - } + internal Type _clrType = typeof(TDocument); + internal string _indexName; + internal string _relationName; + internal string _idProperty; + internal bool _disableIdInference; + + internal Expression> _idPropertyExpression; + internal Expression> _routingPropertyExpression; + + /// + public ClrTypeMappingDescriptor IndexName(string indexName) => Assign(indexName, (a, v) => a._indexName = v); + + /// + public ClrTypeMappingDescriptor RelationName(string relationName) => Assign(relationName, (a, v) => a._relationName = v); + + /// + public ClrTypeMappingDescriptor IdProperty(Expression> property) => Assign(property, (a, v) => a._idPropertyExpression = v); + + /// + public ClrTypeMappingDescriptor IdProperty(string property) => Assign(property, (a, v) => a._idProperty = v); + + /// + public ClrTypeMappingDescriptor RoutingProperty(Expression> property) => + Assign(property, (a, v) => a._routingPropertyExpression = v); + + /// + public ClrTypeMappingDescriptor DisableIdInference(bool disable = true) => Assign(disable, (a, v) => a._disableIdInference = v); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Configuration/ElasticsearchClientSettings.cs b/src/Elastic.Clients.Elasticsearch/Common/Configuration/ElasticsearchClientSettings.cs index 81ad2a90790..120b091bf67 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Configuration/ElasticsearchClientSettings.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Configuration/ElasticsearchClientSettings.cs @@ -14,408 +14,407 @@ using Elastic.Transport.Products; using Elastic.Transport.Products.Elasticsearch; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +public class ElasticsearchClientSettings : ElasticsearchClientSettingsBase { - /// - public class ElasticsearchClientSettings : ElasticsearchClientSettingsBase + /// + /// A delegate used to construct a serializer to serialize CLR types representing documents and other types related to + /// documents. + /// By default, the internal serializer will be used to serializer all types. + /// + public delegate Serializer SourceSerializerFactory(Serializer builtIn, + IElasticsearchClientSettings values); + + /// The default user agent for Elastic.Clients.Elasticsearch + public static readonly UserAgent DefaultUserAgent = + Transport.UserAgent.Create("elasticsearch-net", typeof(IElasticsearchClientSettings)); + + /// + /// Creates a new instance of connection settings, if is not specified will default to + /// connecting to http://localhost:9200 + /// + /// + public ElasticsearchClientSettings(Uri? uri = null) : this( + new SingleNodePool(uri ?? new Uri("http://localhost:9200"))) { - /// - /// A delegate used to construct a serializer to serialize CLR types representing documents and other types related to - /// documents. - /// By default, the internal serializer will be used to serializer all types. - /// - public delegate Serializer SourceSerializerFactory(Serializer builtIn, - IElasticsearchClientSettings values); - - /// The default user agent for Elastic.Clients.Elasticsearch - public static readonly UserAgent DefaultUserAgent = - Transport.UserAgent.Create("elasticsearch-net", typeof(IElasticsearchClientSettings)); - - /// - /// Creates a new instance of connection settings, if is not specified will default to - /// connecting to http://localhost:9200 - /// - /// - public ElasticsearchClientSettings(Uri? uri = null) : this( - new SingleNodePool(uri ?? new Uri("http://localhost:9200"))) - { - } + } - /// - /// Sets up the client to communicate to Elastic Cloud using , - /// documentation for more information on how to obtain your Cloud Id - /// - public ElasticsearchClientSettings(string cloudId, IAuthenticationHeader credentials) : this( - new CloudNodePool(cloudId, credentials)) - { - } + /// + /// Sets up the client to communicate to Elastic Cloud using , + /// documentation for more information on how to obtain your Cloud Id + /// + public ElasticsearchClientSettings(string cloudId, IAuthenticationHeader credentials) : this( + new CloudNodePool(cloudId, credentials)) + { + } - /// - /// Instantiate connection settings using a using the provided - /// that never uses any IO. - /// - public ElasticsearchClientSettings(InMemoryConnection connection) - : this(new SingleNodePool(new Uri("http://localhost:9200")), connection) - { - } + /// + /// Instantiate connection settings using a using the provided + /// that never uses any IO. + /// + public ElasticsearchClientSettings(InMemoryConnection connection) + : this(new SingleNodePool(new Uri("http://localhost:9200")), connection) + { + } - public ElasticsearchClientSettings(NodePool nodePool) : this(nodePool, null, null) { } + public ElasticsearchClientSettings(NodePool nodePool) : this(nodePool, null, null) { } - public ElasticsearchClientSettings(NodePool nodePool, SourceSerializerFactory sourceSerializer) - : this(nodePool, null, sourceSerializer) { } + public ElasticsearchClientSettings(NodePool nodePool, SourceSerializerFactory sourceSerializer) + : this(nodePool, null, sourceSerializer) { } - public ElasticsearchClientSettings(NodePool nodePool, ITransportClient connection) : this(nodePool, connection, null) { } + public ElasticsearchClientSettings(NodePool nodePool, ITransportClient connection) : this(nodePool, connection, null) { } - public ElasticsearchClientSettings(NodePool nodePool, ITransportClient connection, SourceSerializerFactory sourceSerializer) : this( - nodePool, - connection, sourceSerializer, null) - { - } + public ElasticsearchClientSettings(NodePool nodePool, ITransportClient connection, SourceSerializerFactory sourceSerializer) : this( + nodePool, + connection, sourceSerializer, null) + { + } - public ElasticsearchClientSettings( - NodePool nodePool, - ITransportClient connection, - SourceSerializerFactory sourceSerializer, - IPropertyMappingProvider propertyMappingProvider) : base(nodePool, connection, sourceSerializer, propertyMappingProvider) - { - } + public ElasticsearchClientSettings( + NodePool nodePool, + ITransportClient connection, + SourceSerializerFactory sourceSerializer, + IPropertyMappingProvider propertyMappingProvider) : base(nodePool, connection, sourceSerializer, propertyMappingProvider) + { } +} - /// - [Browsable(false)] - [EditorBrowsable(EditorBrowsableState.Never)] - public abstract class - ElasticsearchClientSettingsBase : ConnectionConfigurationBase, - IElasticsearchClientSettings - where TConnectionSettings : ElasticsearchClientSettingsBase, IElasticsearchClientSettings +/// +[Browsable(false)] +[EditorBrowsable(EditorBrowsableState.Never)] +public abstract class + ElasticsearchClientSettingsBase : ConnectionConfigurationBase, + IElasticsearchClientSettings + where TConnectionSettings : ElasticsearchClientSettingsBase, IElasticsearchClientSettings +{ + private readonly FluentDictionary _defaultIndices; + private readonly FluentDictionary _defaultRelationNames; + private readonly HashSet _disableIdInference = new(); + private readonly FluentDictionary _idProperties = new(); + + private readonly Inferrer _inferrer; + + private readonly IPropertyMappingProvider _propertyMappingProvider; + private readonly FluentDictionary _propertyMappings = new(); + private readonly FluentDictionary _routeProperties = new(); + private readonly Serializer _sourceSerializer; + private bool _experimentalEnableSerializeNullInferredValues; + private ExperimentalSettings _experimentalSettings = new (); + + private bool _defaultDisableAllInference; + private Func _defaultFieldNameInferrer; + private string _defaultIndex; + + protected ElasticsearchClientSettingsBase( + NodePool nodePool, + ITransportClient connection, + ElasticsearchClientSettings.SourceSerializerFactory? sourceSerializerFactory, + IPropertyMappingProvider propertyMappingProvider) + : base(nodePool, connection, null, ElasticsearchClientProductRegistration.DefaultForElasticsearchClientsElasticsearch) { - private readonly FluentDictionary _defaultIndices; - private readonly FluentDictionary _defaultRelationNames; - private readonly HashSet _disableIdInference = new(); - private readonly FluentDictionary _idProperties = new(); - - private readonly Inferrer _inferrer; - - private readonly IPropertyMappingProvider _propertyMappingProvider; - private readonly FluentDictionary _propertyMappings = new(); - private readonly FluentDictionary _routeProperties = new(); - private readonly Serializer _sourceSerializer; - private bool _experimentalEnableSerializeNullInferredValues; - private ExperimentalSettings _experimentalSettings = new (); - - private bool _defaultDisableAllInference; - private Func _defaultFieldNameInferrer; - private string _defaultIndex; - - protected ElasticsearchClientSettingsBase( - NodePool nodePool, - ITransportClient connection, - ElasticsearchClientSettings.SourceSerializerFactory? sourceSerializerFactory, - IPropertyMappingProvider propertyMappingProvider) - : base(nodePool, connection, null, ElasticsearchClientProductRegistration.DefaultForElasticsearchClientsElasticsearch) - { - var requestResponseSerializer = new DefaultRequestResponseSerializer(this); - var sourceSerializer = sourceSerializerFactory?.Invoke(requestResponseSerializer, this) ?? new DefaultSourceSerializer(this); + var requestResponseSerializer = new DefaultRequestResponseSerializer(this); + var sourceSerializer = sourceSerializerFactory?.Invoke(requestResponseSerializer, this) ?? new DefaultSourceSerializer(this); - _propertyMappingProvider = propertyMappingProvider ?? sourceSerializer as IPropertyMappingProvider ?? new DefaultPropertyMappingProvider(); + _propertyMappingProvider = propertyMappingProvider ?? sourceSerializer as IPropertyMappingProvider ?? new DefaultPropertyMappingProvider(); - // TODO - Serializer implementations should directly call diagnostics to avoid wrapping - //We wrap these in an internal proxy to facilitate serialization diagnostics - //_sourceSerializer = new DiagnosticsSerializerProxy(sourceSerializer, "source"); - _sourceSerializer = sourceSerializer; + // TODO - Serializer implementations should directly call diagnostics to avoid wrapping + //We wrap these in an internal proxy to facilitate serialization diagnostics + //_sourceSerializer = new DiagnosticsSerializerProxy(sourceSerializer, "source"); + _sourceSerializer = sourceSerializer; - //UseThisRequestResponseSerializer = new DiagnosticsSerializerProxy(defaultSerializer); - UseThisRequestResponseSerializer = requestResponseSerializer; + //UseThisRequestResponseSerializer = new DiagnosticsSerializerProxy(defaultSerializer); + UseThisRequestResponseSerializer = requestResponseSerializer; - _defaultFieldNameInferrer = p => p.ToCamelCase(); - _defaultIndices = new FluentDictionary(); - _defaultRelationNames = new FluentDictionary(); - _inferrer = new Inferrer(this); + _defaultFieldNameInferrer = p => p.ToCamelCase(); + _defaultIndices = new FluentDictionary(); + _defaultRelationNames = new FluentDictionary(); + _inferrer = new Inferrer(this); - UserAgent(ElasticsearchClientSettings.DefaultUserAgent); - } + UserAgent(ElasticsearchClientSettings.DefaultUserAgent); + } - public Serializer SourceSerializer => _sourceSerializer; + public Serializer SourceSerializer => _sourceSerializer; - bool IElasticsearchClientSettings.DefaultDisableIdInference => _defaultDisableAllInference; - Func IElasticsearchClientSettings.DefaultFieldNameInferrer => _defaultFieldNameInferrer; - string IElasticsearchClientSettings.DefaultIndex => _defaultIndex; - FluentDictionary IElasticsearchClientSettings.DefaultIndices => _defaultIndices; - HashSet IElasticsearchClientSettings.DisableIdInference => _disableIdInference; - FluentDictionary IElasticsearchClientSettings.DefaultRelationNames => _defaultRelationNames; - FluentDictionary IElasticsearchClientSettings.IdProperties => _idProperties; + bool IElasticsearchClientSettings.DefaultDisableIdInference => _defaultDisableAllInference; + Func IElasticsearchClientSettings.DefaultFieldNameInferrer => _defaultFieldNameInferrer; + string IElasticsearchClientSettings.DefaultIndex => _defaultIndex; + FluentDictionary IElasticsearchClientSettings.DefaultIndices => _defaultIndices; + HashSet IElasticsearchClientSettings.DisableIdInference => _disableIdInference; + FluentDictionary IElasticsearchClientSettings.DefaultRelationNames => _defaultRelationNames; + FluentDictionary IElasticsearchClientSettings.IdProperties => _idProperties; - Inferrer IElasticsearchClientSettings.Inferrer => _inferrer; + Inferrer IElasticsearchClientSettings.Inferrer => _inferrer; - IPropertyMappingProvider IElasticsearchClientSettings.PropertyMappingProvider => _propertyMappingProvider; - FluentDictionary IElasticsearchClientSettings.PropertyMappings => _propertyMappings; + IPropertyMappingProvider IElasticsearchClientSettings.PropertyMappingProvider => _propertyMappingProvider; + FluentDictionary IElasticsearchClientSettings.PropertyMappings => _propertyMappings; - FluentDictionary IElasticsearchClientSettings.RouteProperties => _routeProperties; - Serializer IElasticsearchClientSettings.SourceSerializer => _sourceSerializer; + FluentDictionary IElasticsearchClientSettings.RouteProperties => _routeProperties; + Serializer IElasticsearchClientSettings.SourceSerializer => _sourceSerializer; - ExperimentalSettings IElasticsearchClientSettings.Experimental => _experimentalSettings; + ExperimentalSettings IElasticsearchClientSettings.Experimental => _experimentalSettings; - bool IElasticsearchClientSettings.ExperimentalEnableSerializeNullInferredValues => _experimentalEnableSerializeNullInferredValues; + bool IElasticsearchClientSettings.ExperimentalEnableSerializeNullInferredValues => _experimentalEnableSerializeNullInferredValues; - /// - /// The default index to use for a request when no index has been explicitly specified - /// and no default indices are specified for the given CLR type specified for the request. - /// - public TConnectionSettings DefaultIndex(string defaultIndex) => - Assign(defaultIndex, (a, v) => a._defaultIndex = v); + /// + /// The default index to use for a request when no index has been explicitly specified + /// and no default indices are specified for the given CLR type specified for the request. + /// + public TConnectionSettings DefaultIndex(string defaultIndex) => + Assign(defaultIndex, (a, v) => a._defaultIndex = v); - /// - /// Specifies how field names are inferred from CLR property names. - /// - /// By default, Elastic.Clients.Elasticsearch camel cases property names. - /// - /// - /// CLR property EmailAddress will be inferred as "emailAddress" Elasticsearch document field name - /// - public TConnectionSettings DefaultFieldNameInferrer(Func fieldNameInferrer) + /// + /// Specifies how field names are inferred from CLR property names. + /// + /// By default, Elastic.Clients.Elasticsearch camel cases property names. + /// + /// + /// CLR property EmailAddress will be inferred as "emailAddress" Elasticsearch document field name + /// + public TConnectionSettings DefaultFieldNameInferrer(Func fieldNameInferrer) + { + if (_sourceSerializer is DefaultSourceSerializer dss) { - if (_sourceSerializer is DefaultSourceSerializer dss) - { - dss.Options.PropertyNamingPolicy = new CustomizedNamingPolicy(fieldNameInferrer); - } - - return Assign>(fieldNameInferrer, (a, v) => a._defaultFieldNameInferrer = v); + dss.Options.PropertyNamingPolicy = new CustomizedNamingPolicy(fieldNameInferrer); } + + return Assign>(fieldNameInferrer, (a, v) => a._defaultFieldNameInferrer = v); + } - public TConnectionSettings ExperimentalEnableSerializeNullInferredValues(bool enabled = true) => - Assign(enabled, (a, v) => a._experimentalEnableSerializeNullInferredValues = v); - - public TConnectionSettings Experimental(ExperimentalSettings settings) => - Assign(settings, (a, v) => a._experimentalSettings = v); - - /// - /// Disables automatic Id inference for given CLR types. - /// - /// Elastic.Clients.Elasticsearch by default will use the value of a property named Id on a CLR type as the _id to send to Elasticsearch. Adding - /// a type - /// will disable this behaviour for that CLR type. If Id inference should be disabled for all CLR types, use - /// - /// - public TConnectionSettings DefaultDisableIdInference(bool disable = true) => - Assign(disable, (a, v) => a._defaultDisableAllInference = v); - - private void MapIdPropertyFor(Expression> objectPath) - { - objectPath.ThrowIfNull(nameof(objectPath)); + public TConnectionSettings ExperimentalEnableSerializeNullInferredValues(bool enabled = true) => + Assign(enabled, (a, v) => a._experimentalEnableSerializeNullInferredValues = v); - var memberInfo = new MemberInfoResolver(objectPath); - var fieldName = memberInfo.Members.Single().Name; + public TConnectionSettings Experimental(ExperimentalSettings settings) => + Assign(settings, (a, v) => a._experimentalSettings = v); - if (_idProperties.TryGetValue(typeof(TDocument), out var idPropertyFieldName)) - { - if (idPropertyFieldName.Equals(fieldName)) - return; + /// + /// Disables automatic Id inference for given CLR types. + /// + /// Elastic.Clients.Elasticsearch by default will use the value of a property named Id on a CLR type as the _id to send to Elasticsearch. Adding + /// a type + /// will disable this behaviour for that CLR type. If Id inference should be disabled for all CLR types, use + /// + /// + public TConnectionSettings DefaultDisableIdInference(bool disable = true) => + Assign(disable, (a, v) => a._defaultDisableAllInference = v); - throw new ArgumentException( - $"Cannot map '{fieldName}' as the id property for type '{typeof(TDocument).Name}': it already has '{_idProperties[typeof(TDocument)]}' mapped."); - } + private void MapIdPropertyFor(Expression> objectPath) + { + objectPath.ThrowIfNull(nameof(objectPath)); - _idProperties.Add(typeof(TDocument), fieldName); - } + var memberInfo = new MemberInfoResolver(objectPath); + var fieldName = memberInfo.Members.Single().Name; - /// - private void MapRoutePropertyFor(Expression> objectPath) + if (_idProperties.TryGetValue(typeof(TDocument), out var idPropertyFieldName)) { - objectPath.ThrowIfNull(nameof(objectPath)); + if (idPropertyFieldName.Equals(fieldName)) + return; - var memberInfo = new MemberInfoResolver(objectPath); - var fieldName = memberInfo.Members.Single().Name; + throw new ArgumentException( + $"Cannot map '{fieldName}' as the id property for type '{typeof(TDocument).Name}': it already has '{_idProperties[typeof(TDocument)]}' mapped."); + } - if (_routeProperties.TryGetValue(typeof(TDocument), out var routePropertyFieldName)) - { - if (routePropertyFieldName.Equals(fieldName)) - return; + _idProperties.Add(typeof(TDocument), fieldName); + } - throw new ArgumentException( - $"Cannot map '{fieldName}' as the route property for type '{typeof(TDocument).Name}': it already has '{_routeProperties[typeof(TDocument)]}' mapped."); - } + /// + private void MapRoutePropertyFor(Expression> objectPath) + { + objectPath.ThrowIfNull(nameof(objectPath)); - _routeProperties.Add(typeof(TDocument), fieldName); - } + var memberInfo = new MemberInfoResolver(objectPath); + var fieldName = memberInfo.Members.Single().Name; - /// - /// Specify how the mapping is inferred for a given CLR type. - /// The mapping can infer the index, id and relation name for a given CLR type, as well as control - /// serialization behaviour for CLR properties. - /// - public TConnectionSettings DefaultMappingFor( - Action> selector) - where TDocument : class + if (_routeProperties.TryGetValue(typeof(TDocument), out var routePropertyFieldName)) { - var inferMapping = new ClrTypeMappingDescriptor(); - selector(inferMapping); + if (routePropertyFieldName.Equals(fieldName)) + return; - if (!inferMapping._indexName.IsNullOrEmpty()) - _defaultIndices[inferMapping._clrType] = inferMapping._indexName; + throw new ArgumentException( + $"Cannot map '{fieldName}' as the route property for type '{typeof(TDocument).Name}': it already has '{_routeProperties[typeof(TDocument)]}' mapped."); + } - if (!inferMapping._relationName.IsNullOrEmpty()) - _defaultRelationNames[inferMapping._clrType] = inferMapping._relationName; + _routeProperties.Add(typeof(TDocument), fieldName); + } - if (!string.IsNullOrWhiteSpace(inferMapping._idProperty)) - _idProperties[inferMapping._clrType] = inferMapping._idProperty; + /// + /// Specify how the mapping is inferred for a given CLR type. + /// The mapping can infer the index, id and relation name for a given CLR type, as well as control + /// serialization behaviour for CLR properties. + /// + public TConnectionSettings DefaultMappingFor( + Action> selector) + where TDocument : class + { + var inferMapping = new ClrTypeMappingDescriptor(); + selector(inferMapping); - if (inferMapping._idPropertyExpression != null) - MapIdPropertyFor(inferMapping._idPropertyExpression); + if (!inferMapping._indexName.IsNullOrEmpty()) + _defaultIndices[inferMapping._clrType] = inferMapping._indexName; - if (inferMapping._routingPropertyExpression != null) - MapRoutePropertyFor(inferMapping._routingPropertyExpression); + if (!inferMapping._relationName.IsNullOrEmpty()) + _defaultRelationNames[inferMapping._clrType] = inferMapping._relationName; - if (inferMapping._disableIdInference) - _disableIdInference.Add(inferMapping._clrType); - else - _disableIdInference.Remove(inferMapping._clrType); + if (!string.IsNullOrWhiteSpace(inferMapping._idProperty)) + _idProperties[inferMapping._clrType] = inferMapping._idProperty; - return (TConnectionSettings)this; - } + if (inferMapping._idPropertyExpression != null) + MapIdPropertyFor(inferMapping._idPropertyExpression); - /// - /// Specify how the mapping is inferred for a given CLR type. - /// The mapping can infer the index and relation name for a given CLR type. - /// - public TConnectionSettings DefaultMappingFor(Type documentType, - Action selector) - { - var inferMapping = new ClrTypeMappingDescriptor(documentType); + if (inferMapping._routingPropertyExpression != null) + MapRoutePropertyFor(inferMapping._routingPropertyExpression); - selector(inferMapping); - if (!inferMapping._indexName.IsNullOrEmpty()) - _defaultIndices[inferMapping._clrType] = inferMapping._indexName; + if (inferMapping._disableIdInference) + _disableIdInference.Add(inferMapping._clrType); + else + _disableIdInference.Remove(inferMapping._clrType); - if (!inferMapping._relationName.IsNullOrEmpty()) - _defaultRelationNames[inferMapping._clrType] = inferMapping._relationName; - - if (!string.IsNullOrWhiteSpace(inferMapping._idProperty)) - _idProperties[inferMapping._clrType] = inferMapping._idProperty; + return (TConnectionSettings)this; + } - return (TConnectionSettings)this; - } + /// + /// Specify how the mapping is inferred for a given CLR type. + /// The mapping can infer the index and relation name for a given CLR type. + /// + public TConnectionSettings DefaultMappingFor(Type documentType, + Action selector) + { + var inferMapping = new ClrTypeMappingDescriptor(documentType); - /// - /// Specify how the mapping is inferred for a given CLR type. - /// The mapping can infer the index and relation name for a given CLR type. - /// - public TConnectionSettings DefaultMappingFor(IEnumerable typeMappings) - { - if (typeMappings == null) - return (TConnectionSettings)this; + selector(inferMapping); + if (!inferMapping._indexName.IsNullOrEmpty()) + _defaultIndices[inferMapping._clrType] = inferMapping._indexName; - foreach (var inferMapping in typeMappings) - { - if (!inferMapping.IndexName.IsNullOrEmpty()) - _defaultIndices[inferMapping.ClrType] = inferMapping.IndexName; + if (!inferMapping._relationName.IsNullOrEmpty()) + _defaultRelationNames[inferMapping._clrType] = inferMapping._relationName; - if (!inferMapping.RelationName.IsNullOrEmpty()) - _defaultRelationNames[inferMapping.ClrType] = inferMapping.RelationName; - } + if (!string.IsNullOrWhiteSpace(inferMapping._idProperty)) + _idProperties[inferMapping._clrType] = inferMapping._idProperty; - return (TConnectionSettings)this; - } + return (TConnectionSettings)this; } - /// - public class ConnectionConfiguration : ConnectionConfigurationBase + /// + /// Specify how the mapping is inferred for a given CLR type. + /// The mapping can infer the index and relation name for a given CLR type. + /// + public TConnectionSettings DefaultMappingFor(IEnumerable typeMappings) { - /// - /// The default user agent for Elasticsearch.Net - /// - public static readonly UserAgent DefaultUserAgent = - Elastic.Transport.UserAgent.Create("elasticsearch-net", typeof(ITransportConfiguration)); - - public ConnectionConfiguration(Uri uri = null) - : this(new SingleNodePool(uri ?? new Uri("http://localhost:9200"))) - { - } + if (typeMappings == null) + return (TConnectionSettings)this; - public ConnectionConfiguration(InMemoryConnection connection) - : this(new SingleNodePool(new Uri("http://localhost:9200")), connection) + foreach (var inferMapping in typeMappings) { - } + if (!inferMapping.IndexName.IsNullOrEmpty()) + _defaultIndices[inferMapping.ClrType] = inferMapping.IndexName; - /// - /// Sets up the client to communicate to Elastic Cloud using , - /// documentation for more information on how to obtain your Cloud Id - /// - public ConnectionConfiguration(string cloudId, IAuthenticationHeader credentials) : this( - new CloudNodePool(cloudId, credentials)) - { + if (!inferMapping.RelationName.IsNullOrEmpty()) + _defaultRelationNames[inferMapping.ClrType] = inferMapping.RelationName; } - public ConnectionConfiguration(NodePool nodePool) : this(nodePool, null, null) { } + return (TConnectionSettings)this; + } +} - public ConnectionConfiguration(NodePool nodePool, ITransportClient connection) : this(nodePool, - connection, null) - { - } +/// +public class ConnectionConfiguration : ConnectionConfigurationBase +{ + /// + /// The default user agent for Elasticsearch.Net + /// + public static readonly UserAgent DefaultUserAgent = + Elastic.Transport.UserAgent.Create("elasticsearch-net", typeof(ITransportConfiguration)); + + public ConnectionConfiguration(Uri uri = null) + : this(new SingleNodePool(uri ?? new Uri("http://localhost:9200"))) + { + } - public ConnectionConfiguration(NodePool nodePool, Serializer serializer) : this( - nodePool, null, serializer) - { - } + public ConnectionConfiguration(InMemoryConnection connection) + : this(new SingleNodePool(new Uri("http://localhost:9200")), connection) + { + } - public ConnectionConfiguration(NodePool nodePool, ITransportClient connection, - Serializer serializer) - : base(nodePool, connection, serializer) - { - } + /// + /// Sets up the client to communicate to Elastic Cloud using , + /// documentation for more information on how to obtain your Cloud Id + /// + public ConnectionConfiguration(string cloudId, IAuthenticationHeader credentials) : this( + new CloudNodePool(cloudId, credentials)) + { } - /// - [Browsable(false)] - [EditorBrowsable(EditorBrowsableState.Never)] - public abstract class - ConnectionConfigurationBase : TransportConfigurationBase, - ITransportClientConfigurationValues - where TConnectionConfiguration : ConnectionConfigurationBase, - ITransportClientConfigurationValues + public ConnectionConfiguration(NodePool nodePool) : this(nodePool, null, null) { } + + public ConnectionConfiguration(NodePool nodePool, ITransportClient connection) : this(nodePool, + connection, null) + { + } + + public ConnectionConfiguration(NodePool nodePool, Serializer serializer) : this( + nodePool, null, serializer) { - private bool _includeServerStackTraceOnError; - - protected ConnectionConfigurationBase(NodePool nodePool, ITransportClient connection, - Serializer? serializer, - IProductRegistration registration = null) - : base(nodePool, connection, serializer, registration ?? new ElasticsearchProductRegistration(typeof(ElasticsearchClient))) => - UserAgent(ConnectionConfiguration.DefaultUserAgent); - - bool ITransportClientConfigurationValues.IncludeServerStackTraceOnError => _includeServerStackTraceOnError; - - public override TConnectionConfiguration EnableDebugMode(Action onRequestCompleted = null) => - base.EnableDebugMode(onRequestCompleted) - .PrettyJson() - .IncludeServerStackTraceOnError(); - - /// - /// Forces all requests to have ?pretty=true querystring parameter appended, - /// causing Elasticsearch to return formatted JSON. - /// Defaults to false - /// - public override TConnectionConfiguration PrettyJson(bool b = true) => - base.PrettyJson(b).UpdateGlobalQueryString("pretty", "true", b); - - /// - /// Forces all requests to have ?error_trace=true querystring parameter appended, - /// causing Elasticsearch to return stack traces as part of serialized exceptions - /// Defaults to false - /// - public TConnectionConfiguration IncludeServerStackTraceOnError(bool b = true) => Assign(b, (a, v) => - { - a._includeServerStackTraceOnError = true; - const string key = "error_trace"; - UpdateGlobalQueryString(key, "true", v); - }); } - public interface ITransportClientConfigurationValues : ITransportConfiguration + public ConnectionConfiguration(NodePool nodePool, ITransportClient connection, + Serializer serializer) + : base(nodePool, connection, serializer) { - /// - /// Forces all requests to have ?error_trace=true querystring parameter appended, - /// causing Elasticsearch to return stack traces as part of serialized exceptions - /// Defaults to false - /// - bool IncludeServerStackTraceOnError { get; } } } + +/// +[Browsable(false)] +[EditorBrowsable(EditorBrowsableState.Never)] +public abstract class + ConnectionConfigurationBase : TransportConfigurationBase, + ITransportClientConfigurationValues + where TConnectionConfiguration : ConnectionConfigurationBase, + ITransportClientConfigurationValues +{ + private bool _includeServerStackTraceOnError; + + protected ConnectionConfigurationBase(NodePool nodePool, ITransportClient connection, + Serializer? serializer, + IProductRegistration registration = null) + : base(nodePool, connection, serializer, registration ?? new ElasticsearchProductRegistration(typeof(ElasticsearchClient))) => + UserAgent(ConnectionConfiguration.DefaultUserAgent); + + bool ITransportClientConfigurationValues.IncludeServerStackTraceOnError => _includeServerStackTraceOnError; + + public override TConnectionConfiguration EnableDebugMode(Action onRequestCompleted = null) => + base.EnableDebugMode(onRequestCompleted) + .PrettyJson() + .IncludeServerStackTraceOnError(); + + /// + /// Forces all requests to have ?pretty=true querystring parameter appended, + /// causing Elasticsearch to return formatted JSON. + /// Defaults to false + /// + public override TConnectionConfiguration PrettyJson(bool b = true) => + base.PrettyJson(b).UpdateGlobalQueryString("pretty", "true", b); + + /// + /// Forces all requests to have ?error_trace=true querystring parameter appended, + /// causing Elasticsearch to return stack traces as part of serialized exceptions + /// Defaults to false + /// + public TConnectionConfiguration IncludeServerStackTraceOnError(bool b = true) => Assign(b, (a, v) => + { + a._includeServerStackTraceOnError = true; + const string key = "error_trace"; + UpdateGlobalQueryString(key, "true", v); + }); +} + +public interface ITransportClientConfigurationValues : ITransportConfiguration +{ + /// + /// Forces all requests to have ?error_trace=true querystring parameter appended, + /// causing Elasticsearch to return stack traces as part of serialized exceptions + /// Defaults to false + /// + bool IncludeServerStackTraceOnError { get; } +} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Configuration/IElasticsearchClientSettings.cs b/src/Elastic.Clients.Elasticsearch/Common/Configuration/IElasticsearchClientSettings.cs index d12da6ba668..5f480534fe5 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Configuration/IElasticsearchClientSettings.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Configuration/IElasticsearchClientSettings.cs @@ -8,110 +8,109 @@ using Elastic.Clients.Elasticsearch.Fluent; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +/// Provides the connection settings for Elastic.Clients.Elasticsearch's high level +/// +public interface IElasticsearchClientSettings : ITransportConfiguration +{ + /// + /// Specifies how field names are inferred from CLR property names. + /// + /// By default, Elastic.Clients.Elasticsearch camel cases property names. + /// + /// + /// CLR property EmailAddress will be inferred as "emailAddress" Elasticsearch document field name + /// + Func DefaultFieldNameInferrer { get; } + + /// + /// The default index to use for a request when no index has been explicitly specified + /// and no default indices are specified for the given CLR type specified for the request. + /// + string DefaultIndex { get; } + + /// + /// The default index/indices to use for a request for a given CLR type specified in the request. + /// + FluentDictionary DefaultIndices { get; } + + /// + /// The default relation name to use for a request for a given CLR type specified in the request. + /// + FluentDictionary DefaultRelationNames { get; } + + /// + /// Specify a property for a CLR type to use to infer the _id of the document when indexed in Elasticsearch. + /// + FluentDictionary IdProperties { get; } + + /// + /// Infers index, type, id, relation, routing and field names + /// + Inferrer Inferrer { get; } + + /// + /// Provides mappings for CLR types + /// + IPropertyMappingProvider PropertyMappingProvider { get; } + + /// + /// Provides mappings for CLR type members + /// + FluentDictionary PropertyMappings { get; } + + /// + /// Specify a property for a CLR type to use to infer the routing for of a document when indexed in Elasticsearch. + /// + FluentDictionary RouteProperties { get; } + + /// + /// Disables automatic Id inference for given CLR types. + /// + /// Elastic.Clients.Elasticsearch by default will use the value of a property named Id on a CLR type as the _id to send to Elasticsearch. Adding + /// a type + /// will disable this behaviour for that CLR type. If Id inference should be disabled for all CLR types, use + /// + /// + HashSet DisableIdInference { get; } + + /// + /// Disables automatic Id inference for all CLR types. + /// + /// Elastic.Clients.Elasticsearch by default will use the value of a property named Id on a CLR type as the _id to send to Elasticsearch. + /// Setting this to true + /// will disable this behaviour for all CLR types and cannot be overridden. If Id inference should be disabled only for + /// specific types, use + /// + /// + bool DefaultDisableIdInference { get; } + + /// + /// The serializer use to serialize CLR types representing documents and other types related to documents. + /// + Serializer SourceSerializer { get; } + + /// + /// This is an advanced setting which controls serialization behaviour for inferred properies such as ID, routing and index name. + /// When enabled, it may reduce allocations on serialisation paths where the cost can be more significant, such as in bulk operations. + /// As a by-product it may cause null values to be included in the serialized data and impact payload size. This will only be a concern should some + /// typed not have inferrence mappings defined for the required properties. + /// + /// This is marked as experiemental and may be removed or renamed in the future once its impact is evaluated. + bool ExperimentalEnableSerializeNullInferredValues { get; } + + /// + /// Experimental settings. + /// + ExperimentalSettings Experimental { get; } +} + +public sealed class ExperimentalSettings { /// - /// Provides the connection settings for Elastic.Clients.Elasticsearch's high level + /// When enabled, the parameters for a script will be serialised using the SourceSerializer. /// - public interface IElasticsearchClientSettings : ITransportConfiguration - { - /// - /// Specifies how field names are inferred from CLR property names. - /// - /// By default, Elastic.Clients.Elasticsearch camel cases property names. - /// - /// - /// CLR property EmailAddress will be inferred as "emailAddress" Elasticsearch document field name - /// - Func DefaultFieldNameInferrer { get; } - - /// - /// The default index to use for a request when no index has been explicitly specified - /// and no default indices are specified for the given CLR type specified for the request. - /// - string DefaultIndex { get; } - - /// - /// The default index/indices to use for a request for a given CLR type specified in the request. - /// - FluentDictionary DefaultIndices { get; } - - /// - /// The default relation name to use for a request for a given CLR type specified in the request. - /// - FluentDictionary DefaultRelationNames { get; } - - /// - /// Specify a property for a CLR type to use to infer the _id of the document when indexed in Elasticsearch. - /// - FluentDictionary IdProperties { get; } - - /// - /// Infers index, type, id, relation, routing and field names - /// - Inferrer Inferrer { get; } - - /// - /// Provides mappings for CLR types - /// - IPropertyMappingProvider PropertyMappingProvider { get; } - - /// - /// Provides mappings for CLR type members - /// - FluentDictionary PropertyMappings { get; } - - /// - /// Specify a property for a CLR type to use to infer the routing for of a document when indexed in Elasticsearch. - /// - FluentDictionary RouteProperties { get; } - - /// - /// Disables automatic Id inference for given CLR types. - /// - /// Elastic.Clients.Elasticsearch by default will use the value of a property named Id on a CLR type as the _id to send to Elasticsearch. Adding - /// a type - /// will disable this behaviour for that CLR type. If Id inference should be disabled for all CLR types, use - /// - /// - HashSet DisableIdInference { get; } - - /// - /// Disables automatic Id inference for all CLR types. - /// - /// Elastic.Clients.Elasticsearch by default will use the value of a property named Id on a CLR type as the _id to send to Elasticsearch. - /// Setting this to true - /// will disable this behaviour for all CLR types and cannot be overridden. If Id inference should be disabled only for - /// specific types, use - /// - /// - bool DefaultDisableIdInference { get; } - - /// - /// The serializer use to serialize CLR types representing documents and other types related to documents. - /// - Serializer SourceSerializer { get; } - - /// - /// This is an advanced setting which controls serialization behaviour for inferred properies such as ID, routing and index name. - /// When enabled, it may reduce allocations on serialisation paths where the cost can be more significant, such as in bulk operations. - /// As a by-product it may cause null values to be included in the serialized data and impact payload size. This will only be a concern should some - /// typed not have inferrence mappings defined for the required properties. - /// - /// This is marked as experiemental and may be removed or renamed in the future once its impact is evaluated. - bool ExperimentalEnableSerializeNullInferredValues { get; } - - /// - /// Experimental settings. - /// - ExperimentalSettings Experimental { get; } - } - - public sealed class ExperimentalSettings - { - /// - /// When enabled, the parameters for a script will be serialised using the SourceSerializer. - /// - public bool UseSourceSerializerForScriptParameters { get; set; } - } + public bool UseSourceSerializerForScriptParameters { get; set; } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Configuration/MemberInfoResolver.cs b/src/Elastic.Clients.Elasticsearch/Common/Configuration/MemberInfoResolver.cs index b3bf64edc09..e1401c4f9e1 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Configuration/MemberInfoResolver.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Configuration/MemberInfoResolver.cs @@ -6,22 +6,21 @@ using System.Linq.Expressions; using System.Reflection; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +/// Resolves member infos in an expression, instance may NOT be shared. +/// +public sealed class MemberInfoResolver : ExpressionVisitor { - /// - /// Resolves member infos in an expression, instance may NOT be shared. - /// - public sealed class MemberInfoResolver : ExpressionVisitor - { - // ReSharper disable once VirtualMemberCallInConstructor - public MemberInfoResolver(Expression expression) => Visit(expression); + // ReSharper disable once VirtualMemberCallInConstructor + public MemberInfoResolver(Expression expression) => Visit(expression); - public IList Members { get; } = new List(); + public IList Members { get; } = new List(); - protected override Expression VisitMember(MemberExpression expression) - { - Members.Add(expression.Member); - return base.VisitMember(expression); - } + protected override Expression VisitMember(MemberExpression expression) + { + Members.Add(expression.Member); + return base.VisitMember(expression); } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/DateTime/TimeUnit.cs b/src/Elastic.Clients.Elasticsearch/Common/DateTime/TimeUnit.cs index d6856e2f685..bb14adbe488 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/DateTime/TimeUnit.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/DateTime/TimeUnit.cs @@ -4,31 +4,30 @@ using System; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public static class TimeUnitExtensions { - public static class TimeUnitExtensions + public static string GetStringValue(this TimeUnit value) { - public static string GetStringValue(this TimeUnit value) + switch (value) { - switch (value) - { - case TimeUnit.Nanoseconds: - return "nanos"; - case TimeUnit.Microseconds: - return "micros"; - case TimeUnit.Milliseconds: - return "ms"; - case TimeUnit.Seconds: - return "s"; - case TimeUnit.Minutes: - return "m"; - case TimeUnit.Hours: - return "h"; - case TimeUnit.Days: - return "d"; - default: - throw new ArgumentOutOfRangeException(nameof(value), value, null); - } + case TimeUnit.Nanoseconds: + return "nanos"; + case TimeUnit.Microseconds: + return "micros"; + case TimeUnit.Milliseconds: + return "ms"; + case TimeUnit.Seconds: + return "s"; + case TimeUnit.Minutes: + return "m"; + case TimeUnit.Hours: + return "h"; + case TimeUnit.Days: + return "d"; + default: + throw new ArgumentOutOfRangeException(nameof(value), value, null); } } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Extensions/ExceptionExtensions.cs b/src/Elastic.Clients.Elasticsearch/Common/Extensions/ExceptionExtensions.cs index bce208ae121..9bea6600ff0 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Extensions/ExceptionExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Extensions/ExceptionExtensions.cs @@ -4,17 +4,16 @@ using System; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal static class ExceptionExtensions { - internal static class ExceptionExtensions + internal static T ThrowWhen(this T @object, Func predicate, string exceptionMessage) { - internal static T ThrowWhen(this T @object, Func predicate, string exceptionMessage) - { - var x = predicate?.Invoke(@object); - if (x.GetValueOrDefault(false)) - throw new ArgumentException(exceptionMessage); + var x = predicate?.Invoke(@object); + if (x.GetValueOrDefault(false)) + throw new ArgumentException(exceptionMessage); - return @object; - } + return @object; } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Extensions/ExpressionExtensions.cs b/src/Elastic.Clients.Elasticsearch/Common/Extensions/ExpressionExtensions.cs index 6fa0311ca17..c95b207f3c8 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Extensions/ExpressionExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Extensions/ExpressionExtensions.cs @@ -6,95 +6,94 @@ using System.Linq; using System.Linq.Expressions; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public static class ExpressionExtensions { - public static class ExpressionExtensions + /// + /// Appends to the path separating it with a dot. + /// This is especially useful with multi fields. + /// + /// the expression to which the suffix should be applied + /// the suffix + public static Expression> AppendSuffix(this Expression> expression, string suffix) { - /// - /// Appends to the path separating it with a dot. - /// This is especially useful with multi fields. - /// - /// the expression to which the suffix should be applied - /// the suffix - public static Expression> AppendSuffix(this Expression> expression, string suffix) - { - var newBody = new SuffixExpressionVisitor(suffix).Visit(expression.Body); - return Expression.Lambda>(newBody!, expression.Parameters[0]); - } - public static Expression> AppendSuffix(this Expression> expression, string suffix) - { - var newBody = new SuffixExpressionVisitor(suffix).Visit(expression.Body); - return Expression.Lambda>(newBody!, expression.Parameters[0]); - } + var newBody = new SuffixExpressionVisitor(suffix).Visit(expression.Body); + return Expression.Lambda>(newBody!, expression.Parameters[0]); + } + public static Expression> AppendSuffix(this Expression> expression, string suffix) + { + var newBody = new SuffixExpressionVisitor(suffix).Visit(expression.Body); + return Expression.Lambda>(newBody!, expression.Parameters[0]); + } - internal static object ComparisonValueFromExpression(this Expression expression, out Type type, out bool cachable) - { - type = null; - cachable = false; + internal static object ComparisonValueFromExpression(this Expression expression, out Type type, out bool cachable) + { + type = null; + cachable = false; - if (expression == null) - return null; + if (expression == null) + return null; - switch (expression) - { - case LambdaExpression lambdaExpression: - type = lambdaExpression.Parameters.FirstOrDefault()?.Type; - break; - case MemberExpression memberExpression: - type = memberExpression.Member.DeclaringType; - break; - case MethodCallExpression methodCallExpression when methodCallExpression.Method?.DeclaringType is { }: - // special case F# method call expressions on FuncConvert - // that are used to convert F# quotations representing lambda expressions, to expressions. - // https://github.com/dotnet/fsharp/blob/7adaacf150dd79f072efe42d43168c9cd6edbced/src/fsharp/FSharp.Core/Linq.fs#L796 - // - // For example: - // - // type Doc = { Message: string; State: string } - // let field (f:Expr<'a -> 'b>) = - // Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.QuotationToExpression f - // |> Elastic.Clients.Elasticsearch.Field.op_Implicit - // - // let fieldExpression = field <@ fun (d: Doc) -> d.Message @> - // - if (methodCallExpression.Method.DeclaringType.FullName == "Microsoft.FSharp.Core.FuncConvert" && - methodCallExpression.Arguments.FirstOrDefault() is LambdaExpression lambda) - type = lambda.Parameters.FirstOrDefault()?.Type; - else - throw new Exception($"Unsupported {nameof(MethodCallExpression)}: {expression}"); - break; - case MethodCallExpression _: + switch (expression) + { + case LambdaExpression lambdaExpression: + type = lambdaExpression.Parameters.FirstOrDefault()?.Type; + break; + case MemberExpression memberExpression: + type = memberExpression.Member.DeclaringType; + break; + case MethodCallExpression methodCallExpression when methodCallExpression.Method?.DeclaringType is { }: + // special case F# method call expressions on FuncConvert + // that are used to convert F# quotations representing lambda expressions, to expressions. + // https://github.com/dotnet/fsharp/blob/7adaacf150dd79f072efe42d43168c9cd6edbced/src/fsharp/FSharp.Core/Linq.fs#L796 + // + // For example: + // + // type Doc = { Message: string; State: string } + // let field (f:Expr<'a -> 'b>) = + // Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.QuotationToExpression f + // |> Elastic.Clients.Elasticsearch.Field.op_Implicit + // + // let fieldExpression = field <@ fun (d: Doc) -> d.Message @> + // + if (methodCallExpression.Method.DeclaringType.FullName == "Microsoft.FSharp.Core.FuncConvert" && + methodCallExpression.Arguments.FirstOrDefault() is LambdaExpression lambda) + type = lambda.Parameters.FirstOrDefault()?.Type; + else throw new Exception($"Unsupported {nameof(MethodCallExpression)}: {expression}"); - default: - throw new Exception( - $"Expected {nameof(LambdaExpression)}, {nameof(MemberExpression)} or " - + $"{nameof(MethodCallExpression)}, received: {expression.GetType().Name}"); + break; + case MethodCallExpression _: + throw new Exception($"Unsupported {nameof(MethodCallExpression)}: {expression}"); + default: + throw new Exception( + $"Expected {nameof(LambdaExpression)}, {nameof(MemberExpression)} or " + + $"{nameof(MethodCallExpression)}, received: {expression.GetType().Name}"); - } - - var visitor = new ToStringExpressionVisitor(); - var toString = visitor.Resolve(expression); - cachable = visitor.Cachable; - return toString; } - /// - /// Calls on a member expression. - /// - private class SuffixExpressionVisitor : ExpressionVisitor - { - private readonly string _suffix; + var visitor = new ToStringExpressionVisitor(); + var toString = visitor.Resolve(expression); + cachable = visitor.Cachable; + return toString; + } + + /// + /// Calls on a member expression. + /// + private class SuffixExpressionVisitor : ExpressionVisitor + { + private readonly string _suffix; - public SuffixExpressionVisitor(string suffix) => _suffix = suffix; + public SuffixExpressionVisitor(string suffix) => _suffix = suffix; - public override Expression Visit(Expression node) => Expression.Call( - typeof(SuffixExtensions), - nameof(SuffixExtensions.Suffix), - null, - node, - Expression.Constant(_suffix)); + public override Expression Visit(Expression node) => Expression.Call( + typeof(SuffixExtensions), + nameof(SuffixExtensions.Suffix), + null, + node, + Expression.Constant(_suffix)); - protected override Expression VisitUnary(UnaryExpression node) => node; - } + protected override Expression VisitUnary(UnaryExpression node) => node; } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Extensions/Extensions.cs b/src/Elastic.Clients.Elasticsearch/Common/Extensions/Extensions.cs index 5730b763216..f86265233ce 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Extensions/Extensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Extensions/Extensions.cs @@ -13,297 +13,296 @@ using System.Threading; using System.Threading.Tasks; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal static class Extensions { - internal static class Extensions - { - private static readonly ConcurrentDictionary EnumCache = new(); + private static readonly ConcurrentDictionary EnumCache = new(); - //internal static bool NotWritable(this QueryContainer q) => q == null || !q.IsWritable; + //internal static bool NotWritable(this QueryContainer q) => q == null || !q.IsWritable; - //internal static bool NotWritable(this IEnumerable qs) => qs == null || qs.All(q => q.NotWritable()); + //internal static bool NotWritable(this IEnumerable qs) => qs == null || qs.All(q => q.NotWritable()); - internal static string ToEnumValue(this T enumValue) where T : struct - { - var enumType = typeof(T); - var name = Enum.GetName(enumType, enumValue); - var enumMemberAttribute = enumType.GetField(name).GetCustomAttribute(); + internal static string ToEnumValue(this T enumValue) where T : struct + { + var enumType = typeof(T); + var name = Enum.GetName(enumType, enumValue); + var enumMemberAttribute = enumType.GetField(name).GetCustomAttribute(); - //if (enumMemberAttribute != null) - //return enumMemberAttribute.Value; + //if (enumMemberAttribute != null) + //return enumMemberAttribute.Value; - //var alternativeEnumMemberAttribute = enumType.GetField(name).GetCustomAttribute(); + //var alternativeEnumMemberAttribute = enumType.GetField(name).GetCustomAttribute(); - return enumMemberAttribute != null - ? enumMemberAttribute.Value - : enumValue.ToString(); - } + return enumMemberAttribute != null + ? enumMemberAttribute.Value + : enumValue.ToString(); + } - internal static T? ToEnum(this string str, StringComparison comparison = StringComparison.OrdinalIgnoreCase) where T : struct - { - if (str == null) - return null; + internal static T? ToEnum(this string str, StringComparison comparison = StringComparison.OrdinalIgnoreCase) where T : struct + { + if (str == null) + return null; - var enumType = typeof(T); - var key = $"{enumType.Name}.{str}"; - if (EnumCache.TryGetValue(key, out var value)) - return (T)value; + var enumType = typeof(T); + var key = $"{enumType.Name}.{str}"; + if (EnumCache.TryGetValue(key, out var value)) + return (T)value; - foreach (var name in Enum.GetNames(enumType)) + foreach (var name in Enum.GetNames(enumType)) + { + if (name.Equals(str, comparison)) { - if (name.Equals(str, comparison)) - { - var v = (T)Enum.Parse(enumType, name, true); - EnumCache.TryAdd(key, v); - return v; - } - - var enumFieldInfo = enumType.GetField(name); - var enumMemberAttribute = enumFieldInfo.GetCustomAttribute(); - if (enumMemberAttribute?.Value.Equals(str, comparison) ?? false) - { - var v = (T)Enum.Parse(enumType, name); - EnumCache.TryAdd(key, v); - return v; - } + var v = (T)Enum.Parse(enumType, name, true); + EnumCache.TryAdd(key, v); + return v; + } - //var alternativeEnumMemberAttribute = enumFieldInfo.GetCustomAttribute(); - //if (alternativeEnumMemberAttribute?.Value.Equals(str, comparison) ?? false) - //{ - // var v = (T)Enum.Parse(enumType, name); - // EnumCache.TryAdd(key, v); - // return v; - //} + var enumFieldInfo = enumType.GetField(name); + var enumMemberAttribute = enumFieldInfo.GetCustomAttribute(); + if (enumMemberAttribute?.Value.Equals(str, comparison) ?? false) + { + var v = (T)Enum.Parse(enumType, name); + EnumCache.TryAdd(key, v); + return v; } - return null; + //var alternativeEnumMemberAttribute = enumFieldInfo.GetCustomAttribute(); + //if (alternativeEnumMemberAttribute?.Value.Equals(str, comparison) ?? false) + //{ + // var v = (T)Enum.Parse(enumType, name); + // EnumCache.TryAdd(key, v); + // return v; + //} } - internal static TReturn InvokeOrDefault(this Func func, T @default) - where T : class, TReturn where TReturn : class => - func?.Invoke(@default) ?? @default; + return null; + } - internal static TReturn InvokeOrDefault(this Func func, T1 @default, - T2 param2) - where T1 : class, TReturn where TReturn : class => - func?.Invoke(@default, param2) ?? @default; + internal static TReturn InvokeOrDefault(this Func func, T @default) + where T : class, TReturn where TReturn : class => + func?.Invoke(@default) ?? @default; - internal static IEnumerable DistinctBy(this IEnumerable items, Func property) => - items.GroupBy(property).Select(x => x.First()); + internal static TReturn InvokeOrDefault(this Func func, T1 @default, + T2 param2) + where T1 : class, TReturn where TReturn : class => + func?.Invoke(@default, param2) ?? @default; - internal static string Utf8String(this byte[] bytes) => - bytes == null ? null : Encoding.UTF8.GetString(bytes, 0, bytes.Length); + internal static IEnumerable DistinctBy(this IEnumerable items, Func property) => + items.GroupBy(property).Select(x => x.First()); - internal static byte[] Utf8Bytes(this string s) => s.IsNullOrEmpty() ? null : Encoding.UTF8.GetBytes(s); + internal static string Utf8String(this byte[] bytes) => + bytes == null ? null : Encoding.UTF8.GetString(bytes, 0, bytes.Length); - internal static bool IsNullOrEmpty(this IndexName value) => value == null || value.GetHashCode() == 0; + internal static byte[] Utf8Bytes(this string s) => s.IsNullOrEmpty() ? null : Encoding.UTF8.GetBytes(s); - internal static bool IsNullable(this Type type) => - type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + internal static bool IsNullOrEmpty(this IndexName value) => value == null || value.GetHashCode() == 0; - internal static void ThrowIfNullOrEmpty(this string @object, string parameterName, string when = null) - { - @object.ThrowIfNull(parameterName, when); - if (string.IsNullOrWhiteSpace(@object)) - { - throw new ArgumentException( - "Argument can't be null or empty" + (when.IsNullOrEmpty() ? "" : " when " + when), parameterName); - } - } + internal static bool IsNullable(this Type type) => + type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); - // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Global - internal static void ThrowIfEmpty(this IEnumerable @object, string parameterName) + internal static void ThrowIfNullOrEmpty(this string @object, string parameterName, string when = null) + { + @object.ThrowIfNull(parameterName, when); + if (string.IsNullOrWhiteSpace(@object)) { - if (@object == null) - throw new ArgumentNullException(parameterName); - if (!@object.Any()) - throw new ArgumentException("Argument can not be an empty collection", parameterName); + throw new ArgumentException( + "Argument can't be null or empty" + (when.IsNullOrEmpty() ? "" : " when " + when), parameterName); } + } - // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Global - internal static T[] NotEmpty(this IEnumerable @object, string parameterName) - { - if (!@object.HasAny(out var enumerated)) - throw new ArgumentException("Argument can not be an empty collection", parameterName); - return enumerated; - } + // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Global + internal static void ThrowIfEmpty(this IEnumerable @object, string parameterName) + { + if (@object == null) + throw new ArgumentNullException(parameterName); + if (!@object.Any()) + throw new ArgumentException("Argument can not be an empty collection", parameterName); + } - internal static bool HasAny(this IEnumerable list, out T[] enumerated) - { - enumerated = list == null ? null : list as T[] ?? list.ToArray(); - return enumerated.HasAny(); - } + // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Global + internal static T[] NotEmpty(this IEnumerable @object, string parameterName) + { + if (!@object.HasAny(out var enumerated)) + throw new ArgumentException("Argument can not be an empty collection", parameterName); + return enumerated; + } - internal static List AsInstanceOrToListOrDefault(this IEnumerable list) => - list as List ?? list?.ToList() ?? new List(); + internal static bool HasAny(this IEnumerable list, out T[] enumerated) + { + enumerated = list == null ? null : list as T[] ?? list.ToArray(); + return enumerated.HasAny(); + } - internal static List AsInstanceOrToListOrNull(this IEnumerable list) => - list as List ?? list?.ToList(); + internal static List AsInstanceOrToListOrDefault(this IEnumerable list) => + list as List ?? list?.ToList() ?? new List(); - internal static List EagerConcat(this IEnumerable list, IEnumerable other) - { - var first = list.AsInstanceOrToListOrDefault(); - if (other == null) - return first; - - var second = other.AsInstanceOrToListOrDefault(); - var newList = new List(first.Count + second.Count); - newList.AddRange(first); - newList.AddRange(second); - return newList; - } + internal static List AsInstanceOrToListOrNull(this IEnumerable list) => + list as List ?? list?.ToList(); - internal static IEnumerable AddIfNotNull(this IEnumerable list, T other) - { - if (other == null) - return list; + internal static List EagerConcat(this IEnumerable list, IEnumerable other) + { + var first = list.AsInstanceOrToListOrDefault(); + if (other == null) + return first; + + var second = other.AsInstanceOrToListOrDefault(); + var newList = new List(first.Count + second.Count); + newList.AddRange(first); + newList.AddRange(second); + return newList; + } - var l = list.AsInstanceOrToListOrDefault(); - l.Add(other); - return l; - } + internal static IEnumerable AddIfNotNull(this IEnumerable list, T other) + { + if (other == null) + return list; - internal static bool HasAny(this IEnumerable list, Func predicate) => - list != null && list.Any(predicate); + var l = list.AsInstanceOrToListOrDefault(); + l.Add(other); + return l; + } - internal static bool HasAny(this IEnumerable list) => list != null && list.Any(); + internal static bool HasAny(this IEnumerable list, Func predicate) => + list != null && list.Any(predicate); - internal static bool IsEmpty(this IEnumerable list) - { - if (list == null) - return true; + internal static bool HasAny(this IEnumerable list) => list != null && list.Any(); - var enumerable = list as T[] ?? list.ToArray(); - return !enumerable.Any() || enumerable.All(t => t == null); - } + internal static bool IsEmpty(this IEnumerable list) + { + if (list == null) + return true; - internal static void ThrowIfNull(this T value, string name, string message = null) - { - if (value == null && message.IsNullOrEmpty()) - throw new ArgumentNullException(name); - else if (value == null) - throw new ArgumentNullException(name, "Argument can not be null when " + message); - } + var enumerable = list as T[] ?? list.ToArray(); + return !enumerable.Any() || enumerable.All(t => t == null); + } - internal static bool IsNullOrEmpty(this string value) => string.IsNullOrWhiteSpace(value); + internal static void ThrowIfNull(this T value, string name, string message = null) + { + if (value == null && message.IsNullOrEmpty()) + throw new ArgumentNullException(name); + else if (value == null) + throw new ArgumentNullException(name, "Argument can not be null when " + message); + } - internal static bool IsNullOrEmptyCommaSeparatedList(this string value, out string[] split) - { - split = null; - if (string.IsNullOrWhiteSpace(value)) - return true; - - split = value.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) - .Where(t => !t.IsNullOrEmpty()) - .Select(t => t.Trim()) - .ToArray(); - return split.Length == 0; - } + internal static bool IsNullOrEmpty(this string value) => string.IsNullOrWhiteSpace(value); - internal static List ToListOrNullIfEmpty(this IEnumerable enumerable) - { - var list = enumerable.AsInstanceOrToListOrNull(); - return list != null && list.Count > 0 ? list : null; - } + internal static bool IsNullOrEmptyCommaSeparatedList(this string value, out string[] split) + { + split = null; + if (string.IsNullOrWhiteSpace(value)) + return true; + + split = value.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) + .Where(t => !t.IsNullOrEmpty()) + .Select(t => t.Trim()) + .ToArray(); + return split.Length == 0; + } - internal static void AddIfNotNull(this IList list, T item) where T : class - { - if (item == null) - return; + internal static List ToListOrNullIfEmpty(this IEnumerable enumerable) + { + var list = enumerable.AsInstanceOrToListOrNull(); + return list != null && list.Count > 0 ? list : null; + } - list.Add(item); - } + internal static void AddIfNotNull(this IList list, T item) where T : class + { + if (item == null) + return; - internal static void AddRangeIfNotNull(this List list, IEnumerable item) where T : class - { - if (item == null) - return; + list.Add(item); + } - list.AddRange(item.Where(x => x != null)); - } + internal static void AddRangeIfNotNull(this List list, IEnumerable item) where T : class + { + if (item == null) + return; - internal static Dictionary NullIfNoKeys(this Dictionary dictionary) - { - var i = dictionary?.Count; - return i.GetValueOrDefault(0) > 0 ? dictionary : null; - } + list.AddRange(item.Where(x => x != null)); + } - internal static async Task ForEachAsync( - this IEnumerable lazyList, - Func> taskSelector, - Action resultProcessor, - Action done, - int maxDegreeOfParallelism, - SemaphoreSlim additionalRateLimiter = null - ) - { - var semaphore = new SemaphoreSlim(maxDegreeOfParallelism, maxDegreeOfParallelism); - long page = 0; + internal static Dictionary NullIfNoKeys(this Dictionary dictionary) + { + var i = dictionary?.Count; + return i.GetValueOrDefault(0) > 0 ? dictionary : null; + } - try + internal static async Task ForEachAsync( + this IEnumerable lazyList, + Func> taskSelector, + Action resultProcessor, + Action done, + int maxDegreeOfParallelism, + SemaphoreSlim additionalRateLimiter = null + ) + { + var semaphore = new SemaphoreSlim(maxDegreeOfParallelism, maxDegreeOfParallelism); + long page = 0; + + try + { + var tasks = new List(maxDegreeOfParallelism); + foreach (var item in lazyList) { - var tasks = new List(maxDegreeOfParallelism); - foreach (var item in lazyList) + tasks.Add(ProcessAsync(item, taskSelector, resultProcessor, semaphore, additionalRateLimiter, + page++)); + if (tasks.Count < maxDegreeOfParallelism) + continue; + + var task = await Task.WhenAny(tasks).ConfigureAwait(false); + if (task.Exception != null && task.IsFaulted && task.Exception.Flatten().InnerExceptions.First() is + { } e) { - tasks.Add(ProcessAsync(item, taskSelector, resultProcessor, semaphore, additionalRateLimiter, - page++)); - if (tasks.Count < maxDegreeOfParallelism) - continue; - - var task = await Task.WhenAny(tasks).ConfigureAwait(false); - if (task.Exception != null && task.IsFaulted && task.Exception.Flatten().InnerExceptions.First() is - { } e) - { - ExceptionDispatchInfo.Capture(e).Throw(); - return; - } - - tasks.Remove(task); + ExceptionDispatchInfo.Capture(e).Throw(); + return; } - await Task.WhenAll(tasks).ConfigureAwait(false); - done(null); + tasks.Remove(task); } - catch (Exception e) - { - done(e); - throw; - } - } - private static async Task ProcessAsync( - TSource item, - Func> taskSelector, - Action resultProcessor, - SemaphoreSlim localRateLimiter, - SemaphoreSlim additionalRateLimiter, - long page - ) + await Task.WhenAll(tasks).ConfigureAwait(false); + done(null); + } + catch (Exception e) { - if (localRateLimiter != null) - await localRateLimiter.WaitAsync().ConfigureAwait(false); - if (additionalRateLimiter != null) - await additionalRateLimiter.WaitAsync().ConfigureAwait(false); - try - { - var result = await taskSelector(item, page).ConfigureAwait(false); - resultProcessor(item, result); - } - finally - { - localRateLimiter?.Release(); - additionalRateLimiter?.Release(); - } + done(e); + throw; } + } - internal static bool NullOrEquals(this T o, T other) + private static async Task ProcessAsync( + TSource item, + Func> taskSelector, + Action resultProcessor, + SemaphoreSlim localRateLimiter, + SemaphoreSlim additionalRateLimiter, + long page + ) + { + if (localRateLimiter != null) + await localRateLimiter.WaitAsync().ConfigureAwait(false); + if (additionalRateLimiter != null) + await additionalRateLimiter.WaitAsync().ConfigureAwait(false); + try { - if (o == null && other == null) - return true; - if (o == null || other == null) - return false; - - return o.Equals(other); + var result = await taskSelector(item, page).ConfigureAwait(false); + resultProcessor(item, result); } + finally + { + localRateLimiter?.Release(); + additionalRateLimiter?.Release(); + } + } + + internal static bool NullOrEquals(this T o, T other) + { + if (o == null && other == null) + return true; + if (o == null || other == null) + return false; + + return o.Equals(other); } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Extensions/StringExtensions.cs b/src/Elastic.Clients.Elasticsearch/Common/Extensions/StringExtensions.cs index 236c5f4a466..a281af466d7 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Extensions/StringExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Extensions/StringExtensions.cs @@ -2,23 +2,22 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal static class StringExtensions { - internal static class StringExtensions + internal static string ToCamelCase(this string s) { - internal static string ToCamelCase(this string s) - { - if (string.IsNullOrEmpty(s)) - return s; + if (string.IsNullOrEmpty(s)) + return s; - if (!char.IsUpper(s[0])) - return s; + if (!char.IsUpper(s[0])) + return s; - var camelCase = char.ToLowerInvariant(s[0]).ToString(); - if (s.Length > 1) - camelCase += s.Substring(1); + var camelCase = char.ToLowerInvariant(s[0]).ToString(); + if (s.Length > 1) + camelCase += s.Substring(1); - return camelCase; - } + return camelCase; } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Extensions/SuffixExtensions.cs b/src/Elastic.Clients.Elasticsearch/Common/Extensions/SuffixExtensions.cs index 1b218e0aa4c..2fe7f90222a 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Extensions/SuffixExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Extensions/SuffixExtensions.cs @@ -2,15 +2,14 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public static class SuffixExtensions { - public static class SuffixExtensions - { - /// - /// This extension method should only be used in expressions which are analysed by Elastic.Clients.Elasticsearch. - /// When analysed it will append to the path separating it with a dot. - /// This is especially useful with multi fields. - /// - public static object Suffix(this object @object, string suffix) => @object; - } + /// + /// This extension method should only be used in expressions which are analysed by Elastic.Clients.Elasticsearch. + /// When analysed it will append to the path separating it with a dot. + /// This is especially useful with multi fields. + /// + public static object Suffix(this object @object, string suffix) => @object; } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Extensions/TypeExtensions.cs b/src/Elastic.Clients.Elasticsearch/Common/Extensions/TypeExtensions.cs index 5d87ae23a3f..331b4ed39c0 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Extensions/TypeExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Extensions/TypeExtensions.cs @@ -10,182 +10,181 @@ using System.Reflection; using System.Text; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal static class TypeExtensions { - internal static class TypeExtensions - { - internal static readonly MethodInfo GetActivatorMethodInfo = - typeof(TypeExtensions).GetMethod(nameof(GetActivator), BindingFlags.Static | BindingFlags.NonPublic); + internal static readonly MethodInfo GetActivatorMethodInfo = + typeof(TypeExtensions).GetMethod(nameof(GetActivator), BindingFlags.Static | BindingFlags.NonPublic); - private static readonly ConcurrentDictionary> CachedActivators = - new(); + private static readonly ConcurrentDictionary> CachedActivators = + new(); - private static readonly ConcurrentDictionary CachedGenericClosedTypes = - new(); + private static readonly ConcurrentDictionary CachedGenericClosedTypes = + new(); - private static readonly ConcurrentDictionary> CachedTypePropertyInfos = - new(); + private static readonly ConcurrentDictionary> CachedTypePropertyInfos = + new(); - internal static object CreateGenericInstance(this Type t, Type closeOver, params object[] args) => - t.CreateGenericInstance(new[] { closeOver }, args); + internal static object CreateGenericInstance(this Type t, Type closeOver, params object[] args) => + t.CreateGenericInstance(new[] { closeOver }, args); - internal static object CreateGenericInstance(this Type t, Type[] closeOver, params object[] args) + internal static object CreateGenericInstance(this Type t, Type[] closeOver, params object[] args) + { + var key = closeOver.Aggregate(new StringBuilder(t.FullName), (sb, gt) => { - var key = closeOver.Aggregate(new StringBuilder(t.FullName), (sb, gt) => - { - sb.Append("--"); - return sb.Append(gt.FullName); - }, sb => sb.ToString()); - if (!CachedGenericClosedTypes.TryGetValue(key, out var closedType)) - { - closedType = t.MakeGenericType(closeOver); - CachedGenericClosedTypes.TryAdd(key, closedType); - } - return closedType.CreateInstance(args); + sb.Append("--"); + return sb.Append(gt.FullName); + }, sb => sb.ToString()); + if (!CachedGenericClosedTypes.TryGetValue(key, out var closedType)) + { + closedType = t.MakeGenericType(closeOver); + CachedGenericClosedTypes.TryAdd(key, closedType); } + return closedType.CreateInstance(args); + } - internal static T CreateInstance(this Type t, params object[] args) => (T)t.CreateInstance(args); + internal static T CreateInstance(this Type t, params object[] args) => (T)t.CreateInstance(args); - internal static object CreateInstance(this Type t, params object[] args) - { - var key = t.FullName; - var argKey = args.Length; - if (args.Length > 0) - key = argKey + "--" + key; - if (CachedActivators.TryGetValue(key, out var activator)) - return activator(args); - - var generic = GetActivatorMethodInfo.MakeGenericMethod(t); - var constructors = from c in t.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) - let p = c.GetParameters() - where p.Length == args.Length - select c; - - var ctor = constructors.FirstOrDefault(); - if (ctor == null) - throw new Exception($"Cannot create an instance of {t.FullName} because it has no constructor taking {args.Length} arguments"); - - activator = (ObjectActivator)generic.Invoke(null, new object[] { ctor }); - CachedActivators.TryAdd(key, activator); + internal static object CreateInstance(this Type t, params object[] args) + { + var key = t.FullName; + var argKey = args.Length; + if (args.Length > 0) + key = argKey + "--" + key; + if (CachedActivators.TryGetValue(key, out var activator)) return activator(args); - } - //do not remove this is referenced through GetActivatorMethod - internal static ObjectActivator GetActivator(ConstructorInfo ctor) - { - var paramsInfo = ctor.GetParameters(); + var generic = GetActivatorMethodInfo.MakeGenericMethod(t); + var constructors = from c in t.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + let p = c.GetParameters() + where p.Length == args.Length + select c; - //create a single param of type object[] - var param = Expression.Parameter(typeof(object[]), "args"); + var ctor = constructors.FirstOrDefault(); + if (ctor == null) + throw new Exception($"Cannot create an instance of {t.FullName} because it has no constructor taking {args.Length} arguments"); - var argsExp = new Expression[paramsInfo.Length]; + activator = (ObjectActivator)generic.Invoke(null, new object[] { ctor }); + CachedActivators.TryAdd(key, activator); + return activator(args); + } - //pick each arg from the params array - //and create a typed expression of them - for (var i = 0; i < paramsInfo.Length; i++) - { - var index = Expression.Constant(i); - var paramType = paramsInfo[i].ParameterType; - var paramAccessorExp = Expression.ArrayIndex(param, index); - var paramCastExp = Expression.Convert(paramAccessorExp, paramType); - argsExp[i] = paramCastExp; - } + //do not remove this is referenced through GetActivatorMethod + internal static ObjectActivator GetActivator(ConstructorInfo ctor) + { + var paramsInfo = ctor.GetParameters(); - //make a NewExpression that calls the - //ctor with the args we just created - var newExp = Expression.New(ctor, argsExp); + //create a single param of type object[] + var param = Expression.Parameter(typeof(object[]), "args"); - //create a lambda with the New - //Expression as body and our param object[] as arg - var lambda = Expression.Lambda(typeof(ObjectActivator), newExp, param); + var argsExp = new Expression[paramsInfo.Length]; - //compile it - var compiled = (ObjectActivator)lambda.Compile(); - return compiled; + //pick each arg from the params array + //and create a typed expression of them + for (var i = 0; i < paramsInfo.Length; i++) + { + var index = Expression.Constant(i); + var paramType = paramsInfo[i].ParameterType; + var paramAccessorExp = Expression.ArrayIndex(param, index); + var paramCastExp = Expression.Convert(paramAccessorExp, paramType); + argsExp[i] = paramCastExp; } - internal static List GetAllProperties(this Type type) - { - if (CachedTypePropertyInfos.TryGetValue(type, out var propertyInfos)) - return propertyInfos; + //make a NewExpression that calls the + //ctor with the args we just created + var newExp = Expression.New(ctor, argsExp); + + //create a lambda with the New + //Expression as body and our param object[] as arg + var lambda = Expression.Lambda(typeof(ObjectActivator), newExp, param); - var properties = new Dictionary(); - GetAllPropertiesCore(type, properties); - propertyInfos = properties.Values.ToList(); - CachedTypePropertyInfos.TryAdd(type, propertyInfos); + //compile it + var compiled = (ObjectActivator)lambda.Compile(); + return compiled; + } + + internal static List GetAllProperties(this Type type) + { + if (CachedTypePropertyInfos.TryGetValue(type, out var propertyInfos)) return propertyInfos; - } - /// - /// Returns inherited properties with reflectedType set to base type - /// - private static void GetAllPropertiesCore(Type type, Dictionary collectedProperties) + var properties = new Dictionary(); + GetAllPropertiesCore(type, properties); + propertyInfos = properties.Values.ToList(); + CachedTypePropertyInfos.TryAdd(type, propertyInfos); + return propertyInfos; + } + + /// + /// Returns inherited properties with reflectedType set to base type + /// + private static void GetAllPropertiesCore(Type type, Dictionary collectedProperties) + { + foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { - foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) + if (collectedProperties.TryGetValue(property.Name, out var existingProperty)) { - if (collectedProperties.TryGetValue(property.Name, out var existingProperty)) + if (IsHidingMember(property)) + collectedProperties[property.Name] = property; + else if (!type.IsInterface && property.IsVirtual()) { - if (IsHidingMember(property)) - collectedProperties[property.Name] = property; - else if (!type.IsInterface && property.IsVirtual()) - { - var propertyDeclaringType = property.GetDeclaringType(); + var propertyDeclaringType = property.GetDeclaringType(); - if (!(existingProperty.IsVirtual() && existingProperty.GetDeclaringType().IsAssignableFrom(propertyDeclaringType))) - collectedProperties[property.Name] = property; - } + if (!(existingProperty.IsVirtual() && existingProperty.GetDeclaringType().IsAssignableFrom(propertyDeclaringType))) + collectedProperties[property.Name] = property; } - else - collectedProperties.Add(property.Name, property); } - - if (type.BaseType != null) - GetAllPropertiesCore(type.BaseType, collectedProperties); + else + collectedProperties.Add(property.Name, property); } - /// - /// Determines if a is hiding/shadowing a - /// from a base type - /// - private static bool IsHidingMember(PropertyInfo propertyInfo) - { - var baseType = propertyInfo.DeclaringType?.BaseType; - var baseProperty = baseType?.GetProperty(propertyInfo.Name); - if (baseProperty == null) - return false; + if (type.BaseType != null) + GetAllPropertiesCore(type.BaseType, collectedProperties); + } - var derivedGetMethod = propertyInfo.GetBaseDefinition(); - return derivedGetMethod?.ReturnType != propertyInfo.PropertyType; - } + /// + /// Determines if a is hiding/shadowing a + /// from a base type + /// + private static bool IsHidingMember(PropertyInfo propertyInfo) + { + var baseType = propertyInfo.DeclaringType?.BaseType; + var baseProperty = baseType?.GetProperty(propertyInfo.Name); + if (baseProperty == null) + return false; - private static Type GetDeclaringType(this PropertyInfo propertyInfo) => - propertyInfo.GetBaseDefinition()?.DeclaringType ?? propertyInfo.DeclaringType; + var derivedGetMethod = propertyInfo.GetBaseDefinition(); + return derivedGetMethod?.ReturnType != propertyInfo.PropertyType; + } - private static MethodInfo GetBaseDefinition(this PropertyInfo propertyInfo) - { - var m = propertyInfo.GetMethod; - return m != null - ? m.GetBaseDefinition() - : propertyInfo.SetMethod?.GetBaseDefinition(); - } + private static Type GetDeclaringType(this PropertyInfo propertyInfo) => + propertyInfo.GetBaseDefinition()?.DeclaringType ?? propertyInfo.DeclaringType; - /// - /// Determines if a is virtual - /// - private static bool IsVirtual(this PropertyInfo propertyInfo) - { - var methodInfo = propertyInfo.GetMethod; - if (methodInfo != null && methodInfo.IsVirtual) - return true; + private static MethodInfo GetBaseDefinition(this PropertyInfo propertyInfo) + { + var m = propertyInfo.GetMethod; + return m != null + ? m.GetBaseDefinition() + : propertyInfo.SetMethod?.GetBaseDefinition(); + } - methodInfo = propertyInfo.SetMethod; - return methodInfo != null && methodInfo.IsVirtual; - } + /// + /// Determines if a is virtual + /// + private static bool IsVirtual(this PropertyInfo propertyInfo) + { + var methodInfo = propertyInfo.GetMethod; + if (methodInfo != null && methodInfo.IsVirtual) + return true; - internal delegate T ObjectActivator(params object[] args); + methodInfo = propertyInfo.SetMethod; + return methodInfo != null && methodInfo.IsVirtual; + } - private static readonly Assembly ElasticsearchClientsElasticsearchAssembly = typeof(TypeExtensions).Assembly; + internal delegate T ObjectActivator(params object[] args); - public static bool IsElasticsearchClientsElasticsearchType(this Type type) => type.Assembly == ElasticsearchClientsElasticsearchAssembly; - } + private static readonly Assembly ElasticsearchClientsElasticsearchAssembly = typeof(TypeExtensions).Assembly; + + public static bool IsElasticsearchClientsElasticsearchType(this Type type) => type.Assembly == ElasticsearchClientsElasticsearchAssembly; } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValue.cs b/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValue.cs index 532a27e1018..5c7fe52b9db 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValue.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValue.cs @@ -9,385 +9,384 @@ using System.Collections.Generic; using Elastic.Clients.Elasticsearch.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +/// Represents a value for a field which depends on the field mapping and is only known at runtime, +/// therefore cannot be specifically typed. +/// +[JsonConverter(typeof(FieldValueConverter))] +public readonly struct FieldValue : IEquatable { + internal FieldValue(ValueKind kind, object? value) { Kind = kind; Value = value; } + /// - /// Represents a value for a field which depends on the field mapping and is only known at runtime, - /// therefore cannot be specifically typed. + /// The kind of value contained within this . /// - [JsonConverter(typeof(FieldValueConverter))] - public readonly struct FieldValue : IEquatable + public readonly ValueKind Kind { get; } + + /// + /// The value contained within within this . + /// + public readonly object? Value { get; } + + /// + /// An enumeration of the possible value kinds that the may contain. + /// + public enum ValueKind { - internal FieldValue(ValueKind kind, object? value) { Kind = kind; Value = value; } - - /// - /// The kind of value contained within this . - /// - public readonly ValueKind Kind { get; } - - /// - /// The value contained within within this . - /// - public readonly object? Value { get; } - - /// - /// An enumeration of the possible value kinds that the may contain. - /// - public enum ValueKind - { - Null, - Double, - Long, - Boolean, - String, - LazyDocument, - Composite - } + Null, + Double, + Long, + Boolean, + String, + LazyDocument, + Composite + } - /// - /// Represents a null value. - /// - public static FieldValue Null { get; } = new(ValueKind.Null, null); - - /// - /// Represents a true boolean value. - /// - public static FieldValue True { get; } = new(ValueKind.Boolean, true); - - /// - /// Represents a false boolean value. - /// - public static FieldValue False { get; } = new(ValueKind.Boolean, false); - - /// - /// Factory method to create a containing a long value. - /// - /// The long to store as the value. - /// The new . - public static FieldValue Long(long value) => new(ValueKind.Long, value); - - /// - /// Factory method to create a containing a boolean value. - /// - /// The boolean to store as the value. - /// The new . - public static FieldValue Boolean(bool value) => new(ValueKind.Boolean, value); - - /// - /// Factory method to create a containing a double value. - /// - /// The double to store as the value. - /// The new . - public static FieldValue Double(double value) => new(ValueKind.Double, value); - - /// - /// Factory method to create a containing a string value. - /// - /// The string to store as the value. - /// The new . - public static FieldValue String(string value) => new(ValueKind.String, value); - - // These are not expected to be required for consumer values but are used internally. - internal static FieldValue Any(LazyJson value) => new(ValueKind.LazyDocument, value); - internal static FieldValue Composite(object value) => new(ValueKind.Composite, value); - - /// - /// Checks if the value of . - /// - public bool IsString => Kind == ValueKind.String; - - /// - /// Checks if the value of . - /// - public bool IsBool => Kind == ValueKind.Boolean; - - /// - /// Checks if the value of . - /// - public bool IsLong => Kind == ValueKind.Long; - - /// - /// Checks if the value of . - /// - public bool IsDouble => Kind == ValueKind.Double; - - /// - /// Checks if the value of . - /// - public bool IsLazyDocument => Kind == ValueKind.LazyDocument; - - /// - /// Checks if the value of . - /// - public bool IsNull => Kind == ValueKind.Null; - - /// - /// Checks if the value of . - /// - public bool IsComposite => Kind == ValueKind.Composite; - - /// - /// Gets the value when the value kind is . - /// - /// When this method returns, contains the value associated with this , - /// if the value kind is ; otherwise, the default value for the type of the value parameter. - /// This parameter is passed uninitialized. - /// True if the value is a . - public bool TryGetString([NotNullWhen(returnValue: true)] out string? value) - { - value = null; + /// + /// Represents a null value. + /// + public static FieldValue Null { get; } = new(ValueKind.Null, null); - if (!IsString) - return false; + /// + /// Represents a true boolean value. + /// + public static FieldValue True { get; } = new(ValueKind.Boolean, true); - value = (string)Value; - return true; - } + /// + /// Represents a false boolean value. + /// + public static FieldValue False { get; } = new(ValueKind.Boolean, false); - /// - /// Gets the value when the value kind is . - /// - /// When this method returns, contains the value associated with this , - /// if the value kind is ; otherwise, the default value for the type of the value parameter. - /// This parameter is passed uninitialized. - /// True if the value is a . - public bool TryGetBool([NotNullWhen(returnValue: true)] out bool? value) - { - value = null; + /// + /// Factory method to create a containing a long value. + /// + /// The long to store as the value. + /// The new . + public static FieldValue Long(long value) => new(ValueKind.Long, value); - if (!IsBool) - return false; + /// + /// Factory method to create a containing a boolean value. + /// + /// The boolean to store as the value. + /// The new . + public static FieldValue Boolean(bool value) => new(ValueKind.Boolean, value); - value = (bool)Value; - return true; - } + /// + /// Factory method to create a containing a double value. + /// + /// The double to store as the value. + /// The new . + public static FieldValue Double(double value) => new(ValueKind.Double, value); - /// - /// Gets the value when the value kind is . - /// - /// When this method returns, contains the value associated with this , - /// if the value kind is ; otherwise, the default value for the type of the value parameter. - /// This parameter is passed uninitialized. - /// True if the value is a . - public bool TryGetLong([NotNullWhen(returnValue: true)] out long? value) - { - value = null; + /// + /// Factory method to create a containing a string value. + /// + /// The string to store as the value. + /// The new . + public static FieldValue String(string value) => new(ValueKind.String, value); - if (!IsLong) - return false; + // These are not expected to be required for consumer values but are used internally. + internal static FieldValue Any(LazyJson value) => new(ValueKind.LazyDocument, value); + internal static FieldValue Composite(object value) => new(ValueKind.Composite, value); - value = (long)Value; - return true; - } + /// + /// Checks if the value of . + /// + public bool IsString => Kind == ValueKind.String; - /// - /// Gets the value when the value kind is . - /// - /// When this method returns, contains the value associated with this , - /// if the value kind is ; otherwise, the default value for the type of the value parameter. - /// This parameter is passed uninitialized. - /// True if the value is a . - public bool TryGetDouble([NotNullWhen(returnValue: true)] out double? value) - { - value = null; + /// + /// Checks if the value of . + /// + public bool IsBool => Kind == ValueKind.Boolean; - if (!IsDouble) - return false; + /// + /// Checks if the value of . + /// + public bool IsLong => Kind == ValueKind.Long; - value = (double)Value; - return true; - } + /// + /// Checks if the value of . + /// + public bool IsDouble => Kind == ValueKind.Double; - /// - /// Gets the value when the value kind is . - /// - /// When this method returns, contains the value associated with this , - /// if the value kind is ; otherwise, the default value for the type of the value parameter. - /// This parameter is passed uninitialized. - /// True if the value is a . - public bool TryGetLazyDocument([NotNullWhen(returnValue: true)] out LazyJson? value) - { - value = null; + /// + /// Checks if the value of . + /// + public bool IsLazyDocument => Kind == ValueKind.LazyDocument; - if (!IsLazyDocument) - return false; + /// + /// Checks if the value of . + /// + public bool IsNull => Kind == ValueKind.Null; - value = (LazyJson)Value; - return true; - } + /// + /// Checks if the value of . + /// + public bool IsComposite => Kind == ValueKind.Composite; + + /// + /// Gets the value when the value kind is . + /// + /// When this method returns, contains the value associated with this , + /// if the value kind is ; otherwise, the default value for the type of the value parameter. + /// This parameter is passed uninitialized. + /// True if the value is a . + public bool TryGetString([NotNullWhen(returnValue: true)] out string? value) + { + value = null; + + if (!IsString) + return false; + + value = (string)Value; + return true; + } + + /// + /// Gets the value when the value kind is . + /// + /// When this method returns, contains the value associated with this , + /// if the value kind is ; otherwise, the default value for the type of the value parameter. + /// This parameter is passed uninitialized. + /// True if the value is a . + public bool TryGetBool([NotNullWhen(returnValue: true)] out bool? value) + { + value = null; + + if (!IsBool) + return false; + + value = (bool)Value; + return true; + } + + /// + /// Gets the value when the value kind is . + /// + /// When this method returns, contains the value associated with this , + /// if the value kind is ; otherwise, the default value for the type of the value parameter. + /// This parameter is passed uninitialized. + /// True if the value is a . + public bool TryGetLong([NotNullWhen(returnValue: true)] out long? value) + { + value = null; - /// - /// Gets the value when the value kind is and the value type is . - /// - /// The type expected for the value. - /// When this method returns, contains the value associated with this , - /// if the value kind is and the value type is ; otherwise, the default - /// value for the type of the value parameter. This parameter is passed uninitialized. - /// True if the value is of the specified type. - public bool TryGet([NotNullWhen(returnValue: true)] out T? value) + if (!IsLong) + return false; + + value = (long)Value; + return true; + } + + /// + /// Gets the value when the value kind is . + /// + /// When this method returns, contains the value associated with this , + /// if the value kind is ; otherwise, the default value for the type of the value parameter. + /// This parameter is passed uninitialized. + /// True if the value is a . + public bool TryGetDouble([NotNullWhen(returnValue: true)] out double? value) + { + value = null; + + if (!IsDouble) + return false; + + value = (double)Value; + return true; + } + + /// + /// Gets the value when the value kind is . + /// + /// When this method returns, contains the value associated with this , + /// if the value kind is ; otherwise, the default value for the type of the value parameter. + /// This parameter is passed uninitialized. + /// True if the value is a . + public bool TryGetLazyDocument([NotNullWhen(returnValue: true)] out LazyJson? value) + { + value = null; + + if (!IsLazyDocument) + return false; + + value = (LazyJson)Value; + return true; + } + + /// + /// Gets the value when the value kind is and the value type is . + /// + /// The type expected for the value. + /// When this method returns, contains the value associated with this , + /// if the value kind is and the value type is ; otherwise, the default + /// value for the type of the value parameter. This parameter is passed uninitialized. + /// True if the value is of the specified type. + public bool TryGet([NotNullWhen(returnValue: true)] out T? value) + { + value = default; + + if (!IsComposite || Value is not T typedValue) + return false; + + value = typedValue; + return true; + } + + internal bool TryGetComposite([NotNullWhen(returnValue: true)] out object? value) + { + value = default; + + if (!IsComposite) + return false; + + value = Value; + return true; + } + + public override string ToString() + { + if (Kind == ValueKind.String) + { + return Value as string; + } + else if (Kind == ValueKind.Double) { - value = default; + return ((double)Value).ToString(); + } + else if (Kind == ValueKind.Long) + { + return ((long)Value).ToString(); + } + else if (Kind == ValueKind.Boolean) + { + return ((bool)Value).ToString(); + } + else if (Kind == ValueKind.Null) + { + return "null"; + } + else if (Kind == ValueKind.LazyDocument || Kind == ValueKind.Composite) + { + throw new InvalidOperationException("Composite field value cannot be formatted as a string."); + } + else + { + throw new InvalidOperationException($"Unknown kind '{Kind}'"); + } + } - if (!IsComposite || Value is not T typedValue) - return false; + public override bool Equals(object? obj) => obj is FieldValue value && Equals(value); + public bool Equals(FieldValue other) => Kind == other.Kind && EqualityComparer.Default.Equals(Value, other.Value); - value = typedValue; - return true; + public override int GetHashCode() + { + unchecked + { + var hashCode = 1484969029; + hashCode = hashCode * -1521134295 + Kind.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Value); + return hashCode; } + } + + public static bool operator ==(FieldValue left, FieldValue right) => left.Equals(right); + public static bool operator !=(FieldValue left, FieldValue right) => !(left == right); + + public static implicit operator FieldValue(string value) => String(value); + public static implicit operator FieldValue(bool value) => Boolean(value); + public static implicit operator FieldValue(int value) => Long(value); + public static implicit operator FieldValue(long value) => Long(value); + public static implicit operator FieldValue(double value) => Double(value); +} - internal bool TryGetComposite([NotNullWhen(returnValue: true)] out object? value) +internal sealed class FieldValueConverter : JsonConverter +{ + public override FieldValue Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + switch (reader.TokenType) { - value = default; + case JsonTokenType.Null: + return FieldValue.Null; + + case JsonTokenType.String: + var stringValue = reader.GetString(); + return FieldValue.String(stringValue); + + case JsonTokenType.Number: + if (reader.TryGetInt64(out var l)) + { + return FieldValue.Long(l); + } + else if (reader.TryGetDouble(out var d)) + { + return FieldValue.Double(d); + } + else + { + throw new JsonException("Unexpected number format which cannot be deserialised as a FieldValue."); + } + + case JsonTokenType.True: + return FieldValue.True; + + case JsonTokenType.False: + return FieldValue.False; + + case JsonTokenType.StartObject: + case JsonTokenType.StartArray: + var value = JsonSerializer.Deserialize(ref reader, options); + return FieldValue.Any(value); + } - if (!IsComposite) - return false; + throw new JsonException($"Unexpected token type '{reader.TokenType}' read while deserializing a FieldValue."); + } + + public override void Write(Utf8JsonWriter writer, FieldValue value, JsonSerializerOptions options) + { + if (value.TryGetString(out var stringValue)) + { + writer.WriteStringValue(stringValue); + } - value = Value; - return true; + else if (value.TryGetBool(out var boolValue)) + { + writer.WriteBooleanValue(boolValue.Value); } - public override string ToString() + else if (value.TryGetLong(out var longValue)) { - if (Kind == ValueKind.String) - { - return Value as string; - } - else if (Kind == ValueKind.Double) - { - return ((double)Value).ToString(); - } - else if (Kind == ValueKind.Long) - { - return ((long)Value).ToString(); - } - else if (Kind == ValueKind.Boolean) - { - return ((bool)Value).ToString(); - } - else if (Kind == ValueKind.Null) - { - return "null"; - } - else if (Kind == ValueKind.LazyDocument || Kind == ValueKind.Composite) - { - throw new InvalidOperationException("Composite field value cannot be formatted as a string."); - } - else - { - throw new InvalidOperationException($"Unknown kind '{Kind}'"); - } + writer.WriteNumberValue(longValue.Value); } - public override bool Equals(object? obj) => obj is FieldValue value && Equals(value); - public bool Equals(FieldValue other) => Kind == other.Kind && EqualityComparer.Default.Equals(Value, other.Value); + else if (value.TryGetDouble(out var doubleValue)) + { + writer.WriteNumberValue(doubleValue.Value); + } - public override int GetHashCode() + else if (value.TryGetLazyDocument(out var lazyDocument)) { - unchecked - { - var hashCode = 1484969029; - hashCode = hashCode * -1521134295 + Kind.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Value); - return hashCode; - } + writer.WriteRawValue(lazyDocument.Value.Bytes); } - public static bool operator ==(FieldValue left, FieldValue right) => left.Equals(right); - public static bool operator !=(FieldValue left, FieldValue right) => !(left == right); + else if (value.TryGetComposite(out var objectValue)) + { + if (!options.TryGetClientSettings(out var settings)) + throw new JsonException("Unable to retrieve ElasticsearchClientSettings in order to access source serializer."); - public static implicit operator FieldValue(string value) => String(value); - public static implicit operator FieldValue(bool value) => Boolean(value); - public static implicit operator FieldValue(int value) => Long(value); - public static implicit operator FieldValue(long value) => Long(value); - public static implicit operator FieldValue(double value) => Double(value); - } + SourceSerialisation.Serialize(objectValue, objectValue.GetType(), writer, settings); + } - internal sealed class FieldValueConverter : JsonConverter - { - public override FieldValue Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + else if (value.Kind == FieldValue.ValueKind.Null) { - switch (reader.TokenType) - { - case JsonTokenType.Null: - return FieldValue.Null; - - case JsonTokenType.String: - var stringValue = reader.GetString(); - return FieldValue.String(stringValue); - - case JsonTokenType.Number: - if (reader.TryGetInt64(out var l)) - { - return FieldValue.Long(l); - } - else if (reader.TryGetDouble(out var d)) - { - return FieldValue.Double(d); - } - else - { - throw new JsonException("Unexpected number format which cannot be deserialised as a FieldValue."); - } - - case JsonTokenType.True: - return FieldValue.True; - - case JsonTokenType.False: - return FieldValue.False; - - case JsonTokenType.StartObject: - case JsonTokenType.StartArray: - var value = JsonSerializer.Deserialize(ref reader, options); - return FieldValue.Any(value); - } - - throw new JsonException($"Unexpected token type '{reader.TokenType}' read while deserializing a FieldValue."); + writer.WriteNullValue(); } - public override void Write(Utf8JsonWriter writer, FieldValue value, JsonSerializerOptions options) + else { - if (value.TryGetString(out var stringValue)) - { - writer.WriteStringValue(stringValue); - } - - else if (value.TryGetBool(out var boolValue)) - { - writer.WriteBooleanValue(boolValue.Value); - } - - else if (value.TryGetLong(out var longValue)) - { - writer.WriteNumberValue(longValue.Value); - } - - else if (value.TryGetDouble(out var doubleValue)) - { - writer.WriteNumberValue(doubleValue.Value); - } - - else if (value.TryGetLazyDocument(out var lazyDocument)) - { - writer.WriteRawValue(lazyDocument.Value.Bytes); - } - - else if (value.TryGetComposite(out var objectValue)) - { - if (!options.TryGetClientSettings(out var settings)) - throw new JsonException("Unable to retrieve ElasticsearchClientSettings in order to access source serializer."); - - SourceSerialisation.Serialize(objectValue, objectValue.GetType(), writer, settings); - } - - else if (value.Kind == FieldValue.ValueKind.Null) - { - writer.WriteNullValue(); - } - - else - { - throw new JsonException($"Unsupported FieldValue kind. This is likely a bug and should be reported as an issue."); - } + throw new JsonException($"Unsupported FieldValue kind. This is likely a bug and should be reported as an issue."); } } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValues.cs b/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValues.cs index c7ecb779b1d..7431de9cf2a 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValues.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValues.cs @@ -9,122 +9,121 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +[JsonConverter(typeof(FieldValuesConverter))] +public sealed class FieldValues : IsADictionary { - [JsonConverter(typeof(FieldValuesConverter))] - public sealed class FieldValues : IsADictionary + public static readonly FieldValues Empty = new(); + + private static readonly HashSet NumericTypes = new() { - public static readonly FieldValues Empty = new(); + typeof(int), typeof(double), typeof(decimal), + typeof(long), typeof(short), typeof(sbyte), + typeof(byte), typeof(ulong), typeof(ushort), + typeof(uint), typeof(float) + }; - private static readonly HashSet NumericTypes = new() - { - typeof(int), typeof(double), typeof(decimal), - typeof(long), typeof(short), typeof(sbyte), - typeof(byte), typeof(ulong), typeof(ushort), - typeof(uint), typeof(float) - }; + private readonly Inferrer _inferrer; - private readonly Inferrer _inferrer; + private FieldValues() { } - private FieldValues() { } + internal FieldValues(Inferrer inferrer, IDictionary container) + : base(container) => _inferrer = inferrer; - internal FieldValues(Inferrer inferrer, IDictionary container) - : base(container) => _inferrer = inferrer; + public TValue Value(Field field) + { + var values = Values(field); + return values != null + ? values.FirstOrDefault() + : default; + } - public TValue Value(Field field) - { - var values = Values(field); - return values != null - ? values.FirstOrDefault() - : default; - } + public TValue ValueOf(Expression> objectPath) + { + var values = ValuesOf(objectPath); + return values != null + ? values.FirstOrDefault() + : default; + } - public TValue ValueOf(Expression> objectPath) - { - var values = ValuesOf(objectPath); - return values != null - ? values.FirstOrDefault() - : default; - } + public TValue[] Values(Field field) + { + if (_inferrer == null) + return Array.Empty(); - public TValue[] Values(Field field) - { - if (_inferrer == null) - return Array.Empty(); + var path = _inferrer.Field(field); + return FieldArray(path); + } - var path = _inferrer.Field(field); - return FieldArray(path); - } + public TValue[] ValuesOf(Expression> objectPath) + { + if (_inferrer == null) + return Array.Empty(); - public TValue[] ValuesOf(Expression> objectPath) - { - if (_inferrer == null) - return Array.Empty(); + var field = _inferrer.Field(objectPath); + return FieldArray(field); + } - var field = _inferrer.Field(objectPath); - return FieldArray(field); - } + public static bool IsNumeric(Type myType) => NumericTypes.Contains(Nullable.GetUnderlyingType(myType) ?? myType); - public static bool IsNumeric(Type myType) => NumericTypes.Contains(Nullable.GetUnderlyingType(myType) ?? myType); + public static bool IsNullable(Type type) => type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); - public static bool IsNullable(Type type) => type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); + private TValue[] FieldArray(string field) + { + //unknown field + if (BackingDictionary == null || !BackingDictionary.TryGetValue(field, out var o)) + return null; - private TValue[] FieldArray(string field) - { - //unknown field - if (BackingDictionary == null || !BackingDictionary.TryGetValue(field, out var o)) - return null; - - //numerics are always returned as doubles by Elasticsearch. - if (!IsNumeric(typeof(TValue))) - return o.As(); - - //here we support casting to the desired numeric type whether its nullable or not. - if (!IsNullable(typeof(TValue))) - return o.As().Select(d => (TValue)Convert.ChangeType(d, typeof(TValue))).ToArray(); - - var underlyingType = Nullable.GetUnderlyingType(typeof(TValue)); - return o.As() - .Select(d => - { - if (d == null) - return default; - - return (TValue)Convert.ChangeType(d, underlyingType); - }) - .ToArray(); - } + //numerics are always returned as doubles by Elasticsearch. + if (!IsNumeric(typeof(TValue))) + return o.As(); + + //here we support casting to the desired numeric type whether its nullable or not. + if (!IsNullable(typeof(TValue))) + return o.As().Select(d => (TValue)Convert.ChangeType(d, typeof(TValue))).ToArray(); + + var underlyingType = Nullable.GetUnderlyingType(typeof(TValue)); + return o.As() + .Select(d => + { + if (d == null) + return default; + + return (TValue)Convert.ChangeType(d, underlyingType); + }) + .ToArray(); } +} - internal sealed class FieldValuesConverter : JsonConverter - { - private readonly IElasticsearchClientSettings _settings; +internal sealed class FieldValuesConverter : JsonConverter +{ + private readonly IElasticsearchClientSettings _settings; - public FieldValuesConverter(IElasticsearchClientSettings settings) => _settings = settings; + public FieldValuesConverter(IElasticsearchClientSettings settings) => _settings = settings; - public override FieldValues? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override FieldValues? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) { - if (reader.TokenType != JsonTokenType.StartObject) - { - return null; - } - - var fields = new Dictionary(); + return null; + } - while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) - { - if (reader.TokenType != JsonTokenType.PropertyName) - throw new JsonException($"Unexpected token. Expected {JsonTokenType.PropertyName}, but read {reader.TokenType}"); + var fields = new Dictionary(); - var propertyName = reader.GetString(); - reader.Read(); - var lazyDocument = JsonSerializer.Deserialize(ref reader, options); - fields[propertyName] = lazyDocument; - } + while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) + { + if (reader.TokenType != JsonTokenType.PropertyName) + throw new JsonException($"Unexpected token. Expected {JsonTokenType.PropertyName}, but read {reader.TokenType}"); - return new FieldValues(_settings.Inferrer, fields); + var propertyName = reader.GetString(); + reader.Read(); + var lazyDocument = JsonSerializer.Deserialize(ref reader, options); + fields[propertyName] = lazyDocument; } - public override void Write(Utf8JsonWriter writer, FieldValues value, JsonSerializerOptions options) => throw new NotImplementedException(); + return new FieldValues(_settings.Inferrer, fields); } + + public override void Write(Utf8JsonWriter writer, FieldValues value, JsonSerializerOptions options) => throw new NotImplementedException(); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/DefaultPropertyMappingProvider.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/DefaultPropertyMappingProvider.cs index 2dabe4fbda1..434f54e30ad 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/DefaultPropertyMappingProvider.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/DefaultPropertyMappingProvider.cs @@ -6,42 +6,41 @@ using System.Reflection; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +public class DefaultPropertyMappingProvider : IPropertyMappingProvider { + protected readonly ConcurrentDictionary Properties = new(); + /// - public class DefaultPropertyMappingProvider : IPropertyMappingProvider + public virtual PropertyMapping CreatePropertyMapping(MemberInfo memberInfo) { - protected readonly ConcurrentDictionary Properties = new(); - - /// - public virtual PropertyMapping CreatePropertyMapping(MemberInfo memberInfo) - { - // FUTURE: Perf: Can we avoid this string allocation by using a ValueTuple as the key? - // This is only called once per property on each `PropertyName` as the `FieldResolver` also caches the final string. - // We'd need to benchmark this before assuming a ValueTuple is better as we'd keep the FullName and Name strings alive in the - // dictionary which may have more overall impact that the string creation. - var memberInfoString = $"{memberInfo.DeclaringType?.FullName}.{memberInfo.Name}"; - - if (Properties.TryGetValue(memberInfoString, out var mapping)) - return mapping; + // FUTURE: Perf: Can we avoid this string allocation by using a ValueTuple as the key? + // This is only called once per property on each `PropertyName` as the `FieldResolver` also caches the final string. + // We'd need to benchmark this before assuming a ValueTuple is better as we'd keep the FullName and Name strings alive in the + // dictionary which may have more overall impact that the string creation. + var memberInfoString = $"{memberInfo.DeclaringType?.FullName}.{memberInfo.Name}"; - mapping = PropertyMappingFromAttributes(memberInfo); - Properties.TryAdd(memberInfoString, mapping); + if (Properties.TryGetValue(memberInfoString, out var mapping)) return mapping; - } - private static PropertyMapping PropertyMappingFromAttributes(MemberInfo memberInfo) - { - // If the property includes a System.Text.Json `JsonPropertyName` attribute, grab the name from that. - var jsonPropertyName = memberInfo.GetCustomAttribute(true); + mapping = PropertyMappingFromAttributes(memberInfo); + Properties.TryAdd(memberInfoString, mapping); + return mapping; + } - if (jsonPropertyName is null) - return default; + private static PropertyMapping PropertyMappingFromAttributes(MemberInfo memberInfo) + { + // If the property includes a System.Text.Json `JsonPropertyName` attribute, grab the name from that. + var jsonPropertyName = memberInfo.GetCustomAttribute(true); - return new PropertyMapping - { - Name = jsonPropertyName?.Name - }; - } + if (jsonPropertyName is null) + return default; + + return new PropertyMapping + { + Name = jsonPropertyName?.Name + }; } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldExpressionVisitor.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldExpressionVisitor.cs index 9e5c4c7ffa4..237ec3a2a80 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldExpressionVisitor.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldExpressionVisitor.cs @@ -11,107 +11,106 @@ using System.Text; using System.Collections; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal class FieldExpressionVisitor : ExpressionVisitor { - internal class FieldExpressionVisitor : ExpressionVisitor + private readonly IElasticsearchClientSettings _settings; + private readonly Stack _stack = new(); + + public FieldExpressionVisitor(IElasticsearchClientSettings settings) => _settings = settings; + + public string Resolve(Expression expression, bool toLastToken = false) { - private readonly IElasticsearchClientSettings _settings; - private readonly Stack _stack = new(); + Visit(expression); + if (toLastToken) + return _stack.Last(); + + var builder = new StringBuilder(_stack.Sum(s => s.Length) + (_stack.Count - 1)); + + return _stack + .Aggregate( + builder, + (sb, name) => + (sb.Length > 0 ? sb.Append(".") : sb).Append(name)) + .ToString(); + } - public FieldExpressionVisitor(IElasticsearchClientSettings settings) => _settings = settings; + public string Resolve(MemberInfo info) + { + if (info == null) + return null; - public string Resolve(Expression expression, bool toLastToken = false) - { - Visit(expression); - if (toLastToken) - return _stack.Last(); - - var builder = new StringBuilder(_stack.Sum(s => s.Length) + (_stack.Count - 1)); - - return _stack - .Aggregate( - builder, - (sb, name) => - (sb.Length > 0 ? sb.Append(".") : sb).Append(name)) - .ToString(); - } + var name = info.Name; - public string Resolve(MemberInfo info) - { - if (info == null) - return null; + if (_settings.PropertyMappings.TryGetValue(info, out var propertyMapping)) + return propertyMapping.Name; - var name = info.Name; + // If an IPropertyMappingProvider is available, first attempt to create a mapping and access the name. + // If no IPropertyMappingProvider is available or a null PropertyMapping is returned, fallback to the configured DefaultFieldNameInferrer function. + return _settings.PropertyMappingProvider?.CreatePropertyMapping(info).Name ?? _settings.DefaultFieldNameInferrer(name); + } - if (_settings.PropertyMappings.TryGetValue(info, out var propertyMapping)) - return propertyMapping.Name; + protected override Expression VisitMember(MemberExpression expression) + { + if (_stack == null) + return base.VisitMember(expression); - // If an IPropertyMappingProvider is available, first attempt to create a mapping and access the name. - // If no IPropertyMappingProvider is available or a null PropertyMapping is returned, fallback to the configured DefaultFieldNameInferrer function. - return _settings.PropertyMappingProvider?.CreatePropertyMapping(info).Name ?? _settings.DefaultFieldNameInferrer(name); - } + var name = Resolve(expression.Member); + _stack.Push(name); + return base.VisitMember(expression); + } - protected override Expression VisitMember(MemberExpression expression) + protected override Expression VisitMethodCall(MethodCallExpression methodCall) + { + if (methodCall.Method.Name == nameof(SuffixExtensions.Suffix) && methodCall.Arguments.Any()) { - if (_stack == null) - return base.VisitMember(expression); - - var name = Resolve(expression.Member); - _stack.Push(name); - return base.VisitMember(expression); + VisitConstantOrVariable(methodCall, _stack); + var callingMember = new ReadOnlyCollection( + new List { { methodCall.Arguments.First() } } + ); + Visit(callingMember); + return methodCall; } - - protected override Expression VisitMethodCall(MethodCallExpression methodCall) + else if (methodCall.Method.Name == "get_Item" && methodCall.Arguments.Any()) { - if (methodCall.Method.Name == nameof(SuffixExtensions.Suffix) && methodCall.Arguments.Any()) - { - VisitConstantOrVariable(methodCall, _stack); - var callingMember = new ReadOnlyCollection( - new List { { methodCall.Arguments.First() } } - ); - Visit(callingMember); - return methodCall; - } - else if (methodCall.Method.Name == "get_Item" && methodCall.Arguments.Any()) - { - var t = methodCall.Object.Type; - var isDict = - typeof(IDictionary).IsAssignableFrom(t) - || typeof(IDictionary<,>).IsAssignableFrom(t) - || t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IDictionary<,>); - - if (!isDict) - return base.VisitMethodCall(methodCall); - - VisitConstantOrVariable(methodCall, _stack); - Visit(methodCall.Object); - return methodCall; - } - else if (IsLinqOperator(methodCall.Method)) - { - for (var i = 1; i < methodCall.Arguments.Count; i++) - Visit(methodCall.Arguments[i]); - Visit(methodCall.Arguments[0]); - return methodCall; - } - return base.VisitMethodCall(methodCall); + var t = methodCall.Object.Type; + var isDict = + typeof(IDictionary).IsAssignableFrom(t) + || typeof(IDictionary<,>).IsAssignableFrom(t) + || t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IDictionary<,>); + + if (!isDict) + return base.VisitMethodCall(methodCall); + + VisitConstantOrVariable(methodCall, _stack); + Visit(methodCall.Object); + return methodCall; } - - private static void VisitConstantOrVariable(MethodCallExpression methodCall, Stack stack) + else if (IsLinqOperator(methodCall.Method)) { - var lastArg = methodCall.Arguments.Last(); - var value = lastArg is ConstantExpression constantExpression - ? constantExpression.Value.ToString() - : Expression.Lambda(lastArg).Compile().DynamicInvoke().ToString(); - stack.Push(value); + for (var i = 1; i < methodCall.Arguments.Count; i++) + Visit(methodCall.Arguments[i]); + Visit(methodCall.Arguments[0]); + return methodCall; } + return base.VisitMethodCall(methodCall); + } - private static bool IsLinqOperator(MethodInfo methodInfo) - { - if (methodInfo.DeclaringType != typeof(Queryable) && methodInfo.DeclaringType != typeof(Enumerable)) - return false; + private static void VisitConstantOrVariable(MethodCallExpression methodCall, Stack stack) + { + var lastArg = methodCall.Arguments.Last(); + var value = lastArg is ConstantExpression constantExpression + ? constantExpression.Value.ToString() + : Expression.Lambda(lastArg).Compile().DynamicInvoke().ToString(); + stack.Push(value); + } - return methodInfo.GetCustomAttribute() != null; - } + private static bool IsLinqOperator(MethodInfo methodInfo) + { + if (methodInfo.DeclaringType != typeof(Queryable) && methodInfo.DeclaringType != typeof(Enumerable)) + return false; + + return methodInfo.GetCustomAttribute() != null; } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldExtensions.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldExtensions.cs index dcace7b0637..8752441d6ef 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldExtensions.cs @@ -2,14 +2,12 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch -{ - //internal static class FieldExtensions - //{ - // internal static bool IsConditionless(this Field field) => - // field == null || field.Name.IsNullOrEmpty() && field.Expression == null && field.Property == null; +namespace Elastic.Clients.Elasticsearch; +//internal static class FieldExtensions +//{ +// internal static bool IsConditionless(this Field field) => +// field == null || field.Name.IsNullOrEmpty() && field.Expression == null && field.Property == null; - // internal static bool IsConditionless(this Fields field) => - // field?.ListOfFields == null || field.ListOfFields.All(l => l.IsConditionless()); - //} -} +// internal static bool IsConditionless(this Fields field) => +// field?.ListOfFields == null || field.ListOfFields.All(l => l.IsConditionless()); +//} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldResolver.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldResolver.cs index 9edf73bb243..82b17ff3f3a 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldResolver.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/FieldResolver.cs @@ -8,76 +8,75 @@ using System.Globalization; using System.Linq.Expressions; -namespace Elastic.Clients.Elasticsearch -{ - internal class FieldResolver - { - protected readonly ConcurrentDictionary Fields = new(); - protected readonly ConcurrentDictionary Properties = new(); - private readonly IElasticsearchClientSettings _settings; +namespace Elastic.Clients.Elasticsearch; - public FieldResolver(IElasticsearchClientSettings settings) - { - settings.ThrowIfNull(nameof(settings)); - _settings = settings; - } +internal class FieldResolver +{ + protected readonly ConcurrentDictionary Fields = new(); + protected readonly ConcurrentDictionary Properties = new(); + private readonly IElasticsearchClientSettings _settings; - public string Resolve(Field field) - { - var name = ResolveFieldName(field); - if (field.Boost.HasValue) - name += $"^{field.Boost.Value.ToString(CultureInfo.InvariantCulture)}"; - return name; - } + public FieldResolver(IElasticsearchClientSettings settings) + { + settings.ThrowIfNull(nameof(settings)); + _settings = settings; + } - private string ResolveFieldName(Field field) - { - //if (field.IsConditionless()) - // return null; - if (!field.Name.IsNullOrEmpty()) - return field.Name; - if (field.Expression != null && !field.CachableExpression) - return Resolve(field.Expression, field.Property); + public string Resolve(Field field) + { + var name = ResolveFieldName(field); + if (field.Boost.HasValue) + name += $"^{field.Boost.Value.ToString(CultureInfo.InvariantCulture)}"; + return name; + } - if (Fields.TryGetValue(field, out var fieldName)) - return fieldName; + private string ResolveFieldName(Field field) + { + //if (field.IsConditionless()) + // return null; + if (!field.Name.IsNullOrEmpty()) + return field.Name; + if (field.Expression != null && !field.CachableExpression) + return Resolve(field.Expression, field.Property); - fieldName = Resolve(field.Expression, field.Property); - Fields.TryAdd(field, fieldName); + if (Fields.TryGetValue(field, out var fieldName)) return fieldName; - } - public string Resolve(PropertyName property) - { - //if (property.IsConditionless()) - // return null; - if (!property.Name.IsNullOrEmpty()) - return property.Name; + fieldName = Resolve(field.Expression, field.Property); + Fields.TryAdd(field, fieldName); + return fieldName; + } - if (property.Expression != null && !property.CacheableExpression) - return Resolve(property.Expression, property.Property); + public string Resolve(PropertyName property) + { + //if (property.IsConditionless()) + // return null; + if (!property.Name.IsNullOrEmpty()) + return property.Name; - if (Properties.TryGetValue(property, out var propertyName)) - return propertyName; + if (property.Expression != null && !property.CacheableExpression) + return Resolve(property.Expression, property.Property); - propertyName = Resolve(property.Expression, property.Property, true); - Properties.TryAdd(property, propertyName); + if (Properties.TryGetValue(property, out var propertyName)) return propertyName; - } - private string Resolve(Expression expression, MemberInfo member, bool toLastToken = false) - { - var visitor = new FieldExpressionVisitor(_settings); - var name = expression != null - ? visitor.Resolve(expression, toLastToken) - : member != null - ? visitor.Resolve(member) - : null; + propertyName = Resolve(property.Expression, property.Property, true); + Properties.TryAdd(property, propertyName); + return propertyName; + } + + private string Resolve(Expression expression, MemberInfo member, bool toLastToken = false) + { + var visitor = new FieldExpressionVisitor(_settings); + var name = expression != null + ? visitor.Resolve(expression, toLastToken) + : member != null + ? visitor.Resolve(member) + : null; - if (name == null) - throw new ArgumentException("Name resolved to null for the given Expression or MemberInfo."); + if (name == null) + throw new ArgumentException("Name resolved to null for the given Expression or MemberInfo."); - return name; - } + return name; } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/ToStringExpressionVisitor.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/ToStringExpressionVisitor.cs index 4c0173581eb..a84cc653f6e 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/ToStringExpressionVisitor.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Field/ToStringExpressionVisitor.cs @@ -11,100 +11,99 @@ using System.Runtime.CompilerServices; using System.Text; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal class ToStringExpressionVisitor : ExpressionVisitor { - internal class ToStringExpressionVisitor : ExpressionVisitor + private readonly Stack _stack = new(); + + public bool Cachable { get; private set; } = true; + + public string Resolve(Expression expression, bool toLastToken = false) { - private readonly Stack _stack = new(); + Visit(expression); + if (toLastToken) + return _stack.Last(); - public bool Cachable { get; private set; } = true; + return _stack + .Aggregate( + new StringBuilder(), + (sb, name) => + (sb.Length > 0 ? sb.Append(".") : sb).Append(name)) + .ToString(); + } - public string Resolve(Expression expression, bool toLastToken = false) - { - Visit(expression); - if (toLastToken) - return _stack.Last(); + public string Resolve(MemberInfo info) => info?.Name; - return _stack - .Aggregate( - new StringBuilder(), - (sb, name) => - (sb.Length > 0 ? sb.Append(".") : sb).Append(name)) - .ToString(); - } + protected override Expression VisitMember(MemberExpression expression) + { + if (_stack == null) + return base.VisitMember(expression); - public string Resolve(MemberInfo info) => info?.Name; + var name = Resolve(expression.Member); + _stack.Push(name); + return base.VisitMember(expression); + } - protected override Expression VisitMember(MemberExpression expression) + protected override Expression VisitMethodCall(MethodCallExpression methodCall) + { + if (methodCall.Method.Name == nameof(SuffixExtensions.Suffix) && methodCall.Arguments.Any()) { - if (_stack == null) - return base.VisitMember(expression); - - var name = Resolve(expression.Member); - _stack.Push(name); - return base.VisitMember(expression); + VisitConstantOrVariable(methodCall, _stack); + var callingMember = new ReadOnlyCollection( + new List { { methodCall.Arguments.First() } } + ); + Visit(callingMember); + return methodCall; } - - protected override Expression VisitMethodCall(MethodCallExpression methodCall) + else if (methodCall.Method.Name == "get_Item" && methodCall.Arguments.Any()) { - if (methodCall.Method.Name == nameof(SuffixExtensions.Suffix) && methodCall.Arguments.Any()) - { - VisitConstantOrVariable(methodCall, _stack); - var callingMember = new ReadOnlyCollection( - new List { { methodCall.Arguments.First() } } - ); - Visit(callingMember); - return methodCall; - } - else if (methodCall.Method.Name == "get_Item" && methodCall.Arguments.Any()) - { - var t = methodCall.Object.Type; - var isDict = - typeof(IDictionary).IsAssignableFrom(t) - || typeof(IDictionary<,>).IsAssignableFrom(t) - || t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IDictionary<,>); + var t = methodCall.Object.Type; + var isDict = + typeof(IDictionary).IsAssignableFrom(t) + || typeof(IDictionary<,>).IsAssignableFrom(t) + || t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IDictionary<,>); - if (!isDict) - return base.VisitMethodCall(methodCall); + if (!isDict) + return base.VisitMethodCall(methodCall); - VisitConstantOrVariable(methodCall, _stack); - Visit(methodCall.Object); - return methodCall; - } - else if (IsLinqOperator(methodCall.Method)) - { - for (var i = 1; i < methodCall.Arguments.Count; i++) - Visit(methodCall.Arguments[i]); - Visit(methodCall.Arguments[0]); - return methodCall; - } - return base.VisitMethodCall(methodCall); + VisitConstantOrVariable(methodCall, _stack); + Visit(methodCall.Object); + return methodCall; + } + else if (IsLinqOperator(methodCall.Method)) + { + for (var i = 1; i < methodCall.Arguments.Count; i++) + Visit(methodCall.Arguments[i]); + Visit(methodCall.Arguments[0]); + return methodCall; } + return base.VisitMethodCall(methodCall); + } - private void VisitConstantOrVariable(MethodCallExpression methodCall, Stack stack) + private void VisitConstantOrVariable(MethodCallExpression methodCall, Stack stack) + { + var lastArg = methodCall.Arguments.Last(); + if (lastArg is ConstantExpression constantExpression) + { + stack.Push(constantExpression.Value.ToString()); + return; + } + if (lastArg is MemberExpression memberExpression) { - var lastArg = methodCall.Arguments.Last(); - if (lastArg is ConstantExpression constantExpression) - { - stack.Push(constantExpression.Value.ToString()); - return; - } - if (lastArg is MemberExpression memberExpression) - { - Cachable = false; - stack.Push(memberExpression.Member.Name); - return; - } Cachable = false; - stack.Push(lastArg.ToString()); + stack.Push(memberExpression.Member.Name); + return; } + Cachable = false; + stack.Push(lastArg.ToString()); + } - private static bool IsLinqOperator(MethodInfo methodInfo) - { - if (methodInfo.DeclaringType != typeof(Queryable) && methodInfo.DeclaringType != typeof(Enumerable)) - return false; + private static bool IsLinqOperator(MethodInfo methodInfo) + { + if (methodInfo.DeclaringType != typeof(Queryable) && methodInfo.DeclaringType != typeof(Enumerable)) + return false; - return methodInfo.GetCustomAttribute() != null; - } + return methodInfo.GetCustomAttribute() != null; } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Fields/FieldsDescriptor.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Fields/FieldsDescriptor.cs index 42aa548beb8..a7eb3d5b8ba 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Fields/FieldsDescriptor.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Fields/FieldsDescriptor.cs @@ -2,28 +2,26 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch -{ - //public class FieldsDescriptor : DescriptorPromiseBase, Fields> - // where T : class - //{ - // public FieldsDescriptor() : base(new Fields()) { } +namespace Elastic.Clients.Elasticsearch; +//public class FieldsDescriptor : DescriptorPromiseBase, Fields> +// where T : class +//{ +// public FieldsDescriptor() : base(new Fields()) { } - // public FieldsDescriptor Fields(params Expression>[] fields) => - // Assign(fields, (f, v) => f.And(v)); +// public FieldsDescriptor Fields(params Expression>[] fields) => +// Assign(fields, (f, v) => f.And(v)); - // public FieldsDescriptor Fields(params string[] fields) => Assign(fields, (f, v) => f.And(v)); +// public FieldsDescriptor Fields(params string[] fields) => Assign(fields, (f, v) => f.And(v)); - // public FieldsDescriptor Fields(IEnumerable fields) => - // Assign(fields, (f, v) => f.ListOfFields.AddRange(v)); +// public FieldsDescriptor Fields(IEnumerable fields) => +// Assign(fields, (f, v) => f.ListOfFields.AddRange(v)); - // public FieldsDescriptor Field(Expression> field, double? boost = null, - // string format = null) => - // Assign(new Field(field, boost, format), (f, v) => f.And(v)); +// public FieldsDescriptor Field(Expression> field, double? boost = null, +// string format = null) => +// Assign(new Field(field, boost, format), (f, v) => f.And(v)); - // public FieldsDescriptor Field(string field, double? boost = null, string format = null) => - // Assign(new Field(field, boost, format), (f, v) => f.And(v)); +// public FieldsDescriptor Field(string field, double? boost = null, string format = null) => +// Assign(new Field(field, boost, format), (f, v) => f.And(v)); - // public FieldsDescriptor Field(Field field) => Assign(field, (f, v) => f.And(v)); - //} -} +// public FieldsDescriptor Field(Field field) => Assign(field, (f, v) => f.And(v)); +//} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/IPropertyMappingProvider.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/IPropertyMappingProvider.cs index de3e5fcdff9..27d4b0e6bb1 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/IPropertyMappingProvider.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/IPropertyMappingProvider.cs @@ -4,16 +4,15 @@ using System.Reflection; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +/// Provides mappings for CLR types. +/// +public interface IPropertyMappingProvider { /// - /// Provides mappings for CLR types. + /// Creates an for a . /// - public interface IPropertyMappingProvider - { - /// - /// Creates an for a . - /// - PropertyMapping CreatePropertyMapping(MemberInfo memberInfo); - } + PropertyMapping CreatePropertyMapping(MemberInfo memberInfo); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/Id.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/Id.cs index 7b10365b9c3..1adab333a9e 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/Id.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/Id.cs @@ -9,104 +9,103 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +[DebuggerDisplay("{DebugDisplay,nq}")] +[JsonConverter(typeof(IdConverter))] +public class Id : IEquatable, IUrlParameter { - [DebuggerDisplay("{DebugDisplay,nq}")] - [JsonConverter(typeof(IdConverter))] - public class Id : IEquatable, IUrlParameter + public Id(string id) { - public Id(string id) - { - Tag = 0; - StringValue = id; - } + Tag = 0; + StringValue = id; + } - public Id(long id) - { - Tag = 1; - LongValue = id; - } + public Id(long id) + { + Tag = 1; + LongValue = id; + } - public Id(object document) - { - Tag = 2; - Document = document; - } + public Id(object document) + { + Tag = 2; + Document = document; + } - internal object Document { get; } - internal long? LongValue { get; } - internal string StringOrLongValue => StringValue ?? LongValue?.ToString(CultureInfo.InvariantCulture); - internal string StringValue { get; } - internal int Tag { get; } + internal object Document { get; } + internal long? LongValue { get; } + internal string StringOrLongValue => StringValue ?? LongValue?.ToString(CultureInfo.InvariantCulture); + internal string StringValue { get; } + internal int Tag { get; } - private string DebugDisplay => StringOrLongValue ?? "Id from instance typeof: " + Document?.GetType().Name; + private string DebugDisplay => StringOrLongValue ?? "Id from instance typeof: " + Document?.GetType().Name; - private static int TypeHashCode { get; } = typeof(Id).GetHashCode(); + private static int TypeHashCode { get; } = typeof(Id).GetHashCode(); - public bool Equals(Id other) - { - if (Tag + other.Tag == 1) - return StringOrLongValue == other.StringOrLongValue; - else if (Tag != other.Tag) - return false; - - return Tag switch - { - 0 or 1 => StringOrLongValue == other.StringOrLongValue, - _ => Document?.Equals(other.Document) ?? false, - }; - } + public bool Equals(Id other) + { + if (Tag + other.Tag == 1) + return StringOrLongValue == other.StringOrLongValue; + else if (Tag != other.Tag) + return false; - string IUrlParameter.GetString(ITransportConfiguration? settings) + return Tag switch { - var elasticClientSettings = (IElasticsearchClientSettings)settings; - return GetString(elasticClientSettings); - } + 0 or 1 => StringOrLongValue == other.StringOrLongValue, + _ => Document?.Equals(other.Document) ?? false, + }; + } + + string IUrlParameter.GetString(ITransportConfiguration? settings) + { + var elasticClientSettings = (IElasticsearchClientSettings)settings; + return GetString(elasticClientSettings); + } - internal string GetString(IElasticsearchClientSettings settings) => settings.Inferrer.Id(Document) ?? StringOrLongValue; + internal string GetString(IElasticsearchClientSettings settings) => settings.Inferrer.Id(Document) ?? StringOrLongValue; - public static implicit operator Id(string id) => id.IsNullOrEmpty() ? null : new Id(id); + public static implicit operator Id(string id) => id.IsNullOrEmpty() ? null : new Id(id); - public static implicit operator Id(long id) => new(id); + public static implicit operator Id(long id) => new(id); - public static implicit operator Id(Guid id) => new(id.ToString("D")); + public static implicit operator Id(Guid id) => new(id.ToString("D")); - public static Id From(T document) => new(document); + public static Id From(T document) => new(document); - public override string ToString() => DebugDisplay; + public override string ToString() => DebugDisplay; - public override bool Equals(object obj) + public override bool Equals(object obj) + { + switch (obj) { - switch (obj) - { - case Id r: - return Equals(r); - case string s: - return Equals(s); - case int l: - return Equals(l); - case long l: - return Equals(l); - case Guid g: - return Equals(g); - } - return Equals(new Id(obj)); + case Id r: + return Equals(r); + case string s: + return Equals(s); + case int l: + return Equals(l); + case long l: + return Equals(l); + case Guid g: + return Equals(g); } + return Equals(new Id(obj)); + } - public override int GetHashCode() + public override int GetHashCode() + { + unchecked { - unchecked - { - var result = TypeHashCode; - result = (result * 397) ^ (StringValue?.GetHashCode() ?? 0); - result = (result * 397) ^ (LongValue?.GetHashCode() ?? 0); - result = (result * 397) ^ (Document?.GetHashCode() ?? 0); - return result; - } + var result = TypeHashCode; + result = (result * 397) ^ (StringValue?.GetHashCode() ?? 0); + result = (result * 397) ^ (LongValue?.GetHashCode() ?? 0); + result = (result * 397) ^ (Document?.GetHashCode() ?? 0); + return result; } + } - public static bool operator ==(Id left, Id right) => Equals(left, right); + public static bool operator ==(Id left, Id right) => Equals(left, right); - public static bool operator !=(Id left, Id right) => !Equals(left, right); - } + public static bool operator !=(Id left, Id right) => !Equals(left, right); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdConverter.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdConverter.cs index 6cd7abec2f4..d723880259e 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdConverter.cs @@ -7,44 +7,43 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal sealed class IdConverter : JsonConverter { - internal sealed class IdConverter : JsonConverter - { - private readonly IElasticsearchClientSettings _settings; + private readonly IElasticsearchClientSettings _settings; + + public IdConverter(IElasticsearchClientSettings settings) => _settings = settings; - public IdConverter(IElasticsearchClientSettings settings) => _settings = settings; + public override void WriteAsPropertyName(Utf8JsonWriter writer, Id value, JsonSerializerOptions options) => writer.WritePropertyName(((IUrlParameter)value).GetString(_settings)); - public override void WriteAsPropertyName(Utf8JsonWriter writer, Id value, JsonSerializerOptions options) => writer.WritePropertyName(((IUrlParameter)value).GetString(_settings)); + public override Id ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.GetString(); - public override Id ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.GetString(); + public override Id? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + reader.TokenType == JsonTokenType.Number + ? new Id(reader.GetInt64()) + : new Id(reader.GetString()); - public override Id? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => - reader.TokenType == JsonTokenType.Number - ? new Id(reader.GetInt64()) - : new Id(reader.GetString()); + public override void Write(Utf8JsonWriter writer, Id value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } - public override void Write(Utf8JsonWriter writer, Id value, JsonSerializerOptions options) + if (value.Document is not null) + { + var documentId = _settings.Inferrer.Id(value.Document.GetType(), value.Document); + writer.WriteStringValue(documentId); + } + else if (value.LongValue.HasValue) + { + writer.WriteNumberValue(value.LongValue.Value); + } + else { - if (value is null) - { - writer.WriteNullValue(); - return; - } - - if (value.Document is not null) - { - var documentId = _settings.Inferrer.Id(value.Document.GetType(), value.Document); - writer.WriteStringValue(documentId); - } - else if (value.LongValue.HasValue) - { - writer.WriteNumberValue(value.LongValue.Value); - } - else - { - writer.WriteStringValue(value.StringValue); - } + writer.WriteStringValue(value.StringValue); } } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdExtensions.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdExtensions.cs index b0e267dd04d..b246a83173f 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdExtensions.cs @@ -2,11 +2,9 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch -{ - //internal static class IdExtensions - //{ - // internal static bool IsConditionless(this Id id) => - // id == null || id.StringOrLongValue == null && id.Document == null; - //} -} +namespace Elastic.Clients.Elasticsearch; +//internal static class IdExtensions +//{ +// internal static bool IsConditionless(this Id id) => +// id == null || id.StringOrLongValue == null && id.Document == null; +//} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdResolver.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdResolver.cs index 16f621b1445..7994d96e599 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdResolver.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/IdResolver.cs @@ -6,88 +6,87 @@ using System.Collections.Concurrent; using System.Reflection; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public class IdResolver { - public class IdResolver - { - private static readonly ConcurrentDictionary> IdDelegates = new(); + private static readonly ConcurrentDictionary> IdDelegates = new(); - private static readonly MethodInfo MakeDelegateMethodInfo = - typeof(IdResolver).GetMethod(nameof(MakeDelegate), BindingFlags.Static | BindingFlags.NonPublic); + private static readonly MethodInfo MakeDelegateMethodInfo = + typeof(IdResolver).GetMethod(nameof(MakeDelegate), BindingFlags.Static | BindingFlags.NonPublic); - private readonly IElasticsearchClientSettings _elasticsearchClientSettings; - private readonly ConcurrentDictionary> _localIdDelegates = new(); + private readonly IElasticsearchClientSettings _elasticsearchClientSettings; + private readonly ConcurrentDictionary> _localIdDelegates = new(); - public IdResolver(IElasticsearchClientSettings elasticsearchClientSettings) => - _elasticsearchClientSettings = elasticsearchClientSettings; + public IdResolver(IElasticsearchClientSettings elasticsearchClientSettings) => + _elasticsearchClientSettings = elasticsearchClientSettings; - private PropertyInfo GetPropertyCaseInsensitive(Type type, string fieldName) - => type.GetProperty(fieldName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); + private PropertyInfo GetPropertyCaseInsensitive(Type type, string fieldName) + => type.GetProperty(fieldName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); - internal Func CreateIdSelector() where T : class - { - Func idSelector = Resolve; - return idSelector; - } + internal Func CreateIdSelector() where T : class + { + Func idSelector = Resolve; + return idSelector; + } - internal static Func MakeDelegate(MethodInfo @get) - { - var f = (Func)@get.CreateDelegate(typeof(Func)); - return t => f((T)t); - } + internal static Func MakeDelegate(MethodInfo @get) + { + var f = (Func)@get.CreateDelegate(typeof(Func)); + return t => f((T)t); + } - public string Resolve(T @object) => - _elasticsearchClientSettings.DefaultDisableIdInference || @object == null - ? null - : Resolve(@object.GetType(), @object); + public string Resolve(T @object) => + _elasticsearchClientSettings.DefaultDisableIdInference || @object == null + ? null + : Resolve(@object.GetType(), @object); - public string Resolve(Type type, object @object) - { - if (type == null || @object == null) - return null; - if (_elasticsearchClientSettings.DefaultDisableIdInference || - _elasticsearchClientSettings.DisableIdInference.Contains(type)) - return null; - - var preferLocal = _elasticsearchClientSettings.IdProperties.TryGetValue(type, out _); - - if (_localIdDelegates.TryGetValue(type, out var cachedLookup)) - return cachedLookup(@object); - - if (!preferLocal && IdDelegates.TryGetValue(type, out cachedLookup)) - return cachedLookup(@object); - - var idProperty = GetInferredId(type); - if (idProperty == null) - return null; - - var getMethod = idProperty.GetMethod; - var generic = MakeDelegateMethodInfo.MakeGenericMethod(type, getMethod.ReturnType); - var func = (Func)generic.Invoke(null, new object[] {getMethod}); - cachedLookup = o => - { - var v = func(o); - return v?.ToString(); - }; - if (preferLocal) - _localIdDelegates.TryAdd(type, cachedLookup); - else - IdDelegates.TryAdd(type, cachedLookup); + public string Resolve(Type type, object @object) + { + if (type == null || @object == null) + return null; + if (_elasticsearchClientSettings.DefaultDisableIdInference || + _elasticsearchClientSettings.DisableIdInference.Contains(type)) + return null; + + var preferLocal = _elasticsearchClientSettings.IdProperties.TryGetValue(type, out _); + + if (_localIdDelegates.TryGetValue(type, out var cachedLookup)) return cachedLookup(@object); - } - private PropertyInfo GetInferredId(Type type) - { - // if the type specifies through ElasticAttribute what the id prop is - // use that no matter what + if (!preferLocal && IdDelegates.TryGetValue(type, out cachedLookup)) + return cachedLookup(@object); + + var idProperty = GetInferredId(type); + if (idProperty == null) + return null; - _elasticsearchClientSettings.IdProperties.TryGetValue(type, out var propertyName); - if (!propertyName.IsNullOrEmpty()) - return GetPropertyCaseInsensitive(type, propertyName); + var getMethod = idProperty.GetMethod; + var generic = MakeDelegateMethodInfo.MakeGenericMethod(type, getMethod.ReturnType); + var func = (Func)generic.Invoke(null, new object[] {getMethod}); + cachedLookup = o => + { + var v = func(o); + return v?.ToString(); + }; + if (preferLocal) + _localIdDelegates.TryAdd(type, cachedLookup); + else + IdDelegates.TryAdd(type, cachedLookup); + return cachedLookup(@object); + } - propertyName = "Id"; + private PropertyInfo GetInferredId(Type type) + { + // if the type specifies through ElasticAttribute what the id prop is + // use that no matter what + _elasticsearchClientSettings.IdProperties.TryGetValue(type, out var propertyName); + if (!propertyName.IsNullOrEmpty()) return GetPropertyCaseInsensitive(type, propertyName); - } + + propertyName = "Id"; + + return GetPropertyCaseInsensitive(type, propertyName); } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/Ids.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/Ids.cs index d28dd8c663a..7bf874043da 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/Ids.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Id/Ids.cs @@ -10,121 +10,120 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +[DebuggerDisplay("{DebugDisplay,nq}")] +[JsonConverter(typeof(IdsConverter))] +public partial class Ids : IUrlParameter, IEquatable { - [DebuggerDisplay("{DebugDisplay,nq}")] - [JsonConverter(typeof(IdsConverter))] - public partial class Ids : IUrlParameter, IEquatable - { - private readonly IList _ids; + private readonly IList _ids; - public Ids(IEnumerable ids) => _ids = ids.ToList(); + public Ids(IEnumerable ids) => _ids = ids.ToList(); - public Ids(IList ids) => _ids = ids; + public Ids(IList ids) => _ids = ids; - public Ids(IEnumerable ids) => _ids = ids?.Select(i => new Id(i)).ToList(); + public Ids(IEnumerable ids) => _ids = ids?.Select(i => new Id(i)).ToList(); - public Ids(string value) - { - if (!value.IsNullOrEmptyCommaSeparatedList(out var arr)) - _ids = arr.Select(i => new Id(i)).ToList(); - } + public Ids(string value) + { + if (!value.IsNullOrEmptyCommaSeparatedList(out var arr)) + _ids = arr.Select(i => new Id(i)).ToList(); + } - internal IList IdsToSerialize => _ids; + internal IList IdsToSerialize => _ids; - private string DebugDisplay => ((IUrlParameter)this).GetString(null); + private string DebugDisplay => ((IUrlParameter)this).GetString(null); - public bool Equals(Ids other) - { - if (other == null) - return false; - if (_ids == null && other._ids == null) - return true; - if (_ids == null || other._ids == null) - return false; - - return _ids.Count == other._ids.Count && - _ids.OrderBy(id => id).SequenceEqual(other._ids.OrderBy(id => id)); - } + public bool Equals(Ids other) + { + if (other == null) + return false; + if (_ids == null && other._ids == null) + return true; + if (_ids == null || other._ids == null) + return false; + + return _ids.Count == other._ids.Count && + _ids.OrderBy(id => id).SequenceEqual(other._ids.OrderBy(id => id)); + } - string IUrlParameter.GetString(ITransportConfiguration? settings) + string IUrlParameter.GetString(ITransportConfiguration? settings) + { + if (settings is not ElasticsearchClientSettings elasticsearchClientSettings) { - if (settings is not ElasticsearchClientSettings elasticsearchClientSettings) - { - throw new Exception("Unexpected settings type."); - } - - return string.Join(",", _ids.Select(i => i.GetString(elasticsearchClientSettings)) ?? Enumerable.Empty()); + throw new Exception("Unexpected settings type."); } - public override string ToString() => DebugDisplay; + return string.Join(",", _ids.Select(i => i.GetString(elasticsearchClientSettings)) ?? Enumerable.Empty()); + } + + public override string ToString() => DebugDisplay; - public static implicit operator Ids(string value) => - value.IsNullOrEmptyCommaSeparatedList(out var arr) ? null : new Ids(arr); + public static implicit operator Ids(string value) => + value.IsNullOrEmptyCommaSeparatedList(out var arr) ? null : new Ids(arr); - public static implicit operator Ids(string[] value) => - value.IsEmpty() ? null : new Ids(value); + public static implicit operator Ids(string[] value) => + value.IsEmpty() ? null : new Ids(value); - public override bool Equals(object obj) => obj is Ids other && Equals(other); + public override bool Equals(object obj) => obj is Ids other && Equals(other); - public override int GetHashCode() + public override int GetHashCode() + { + if (_ids == null) + return 0; + unchecked { - if (_ids == null) - return 0; - unchecked - { - var hc = 0; - foreach (var id in _ids.OrderBy(id => id)) - hc = hc * 17 + id.GetHashCode(); - return hc; - } + var hc = 0; + foreach (var id in _ids.OrderBy(id => id)) + hc = hc * 17 + id.GetHashCode(); + return hc; } - - public static bool operator ==(Ids left, Ids right) => Equals(left, right); - - public static bool operator !=(Ids left, Ids right) => !Equals(left, right); } - internal sealed class IdsConverter : JsonConverter - { - private readonly IElasticsearchClientSettings _settings; + public static bool operator ==(Ids left, Ids right) => Equals(left, right); - public IdsConverter(IElasticsearchClientSettings settings) => _settings = settings; + public static bool operator !=(Ids left, Ids right) => !Equals(left, right); +} - public override Ids? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.StartArray) - throw new JsonException($"Unexpected JSON token. Expected {JsonTokenType.StartArray} but read {reader.TokenType}"); +internal sealed class IdsConverter : JsonConverter +{ + private readonly IElasticsearchClientSettings _settings; + + public IdsConverter(IElasticsearchClientSettings settings) => _settings = settings; - var ids = new List(); + public override Ids? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartArray) + throw new JsonException($"Unexpected JSON token. Expected {JsonTokenType.StartArray} but read {reader.TokenType}"); - while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) - { - var id = JsonSerializer.Deserialize(ref reader, options); + var ids = new List(); - if (id is not null) - ids.Add(id); - } + while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) + { + var id = JsonSerializer.Deserialize(ref reader, options); - return new Ids(ids); + if (id is not null) + ids.Add(id); } - public override void Write(Utf8JsonWriter writer, Ids value, JsonSerializerOptions options) - { - if (value is null) - { - writer.WriteNullValue(); - return; - } + return new Ids(ids); + } - writer.WriteStartArray(); + public override void Write(Utf8JsonWriter writer, Ids value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } - foreach (var id in value.IdsToSerialize) - { - JsonSerializer.Serialize(writer, id, options); - } + writer.WriteStartArray(); - writer.WriteEndArray(); + foreach (var id in value.IdsToSerialize) + { + JsonSerializer.Serialize(writer, id, options); } + + writer.WriteEndArray(); } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameConverter.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameConverter.cs index 5119ca62a4d..1c083c60a77 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameConverter.cs @@ -7,42 +7,41 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +/// Converts an to and from its JSON representation. +/// +internal class IndexNameConverter : JsonConverter { - /// - /// Converts an to and from its JSON representation. - /// - internal class IndexNameConverter : JsonConverter - { - private readonly IElasticsearchClientSettings _settings; + private readonly IElasticsearchClientSettings _settings; - public IndexNameConverter(IElasticsearchClientSettings settings) => _settings = settings; + public IndexNameConverter(IElasticsearchClientSettings settings) => _settings = settings; - public override void WriteAsPropertyName(Utf8JsonWriter writer, IndexName value, JsonSerializerOptions options) => writer.WritePropertyName(((IUrlParameter)value).GetString(_settings)); + public override void WriteAsPropertyName(Utf8JsonWriter writer, IndexName value, JsonSerializerOptions options) => writer.WritePropertyName(((IUrlParameter)value).GetString(_settings)); - public override IndexName ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.GetString(); + public override IndexName ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.GetString(); - public override IndexName? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override IndexName? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.String) { - if (reader.TokenType != JsonTokenType.String) - { - reader.Read(); - return null; - } - - IndexName? indexName = reader.GetString(); - return indexName; + reader.Read(); + return null; } - public override void Write(Utf8JsonWriter writer, IndexName? value, JsonSerializerOptions options) - { - if (value is null) - { - writer.WriteNullValue(); - return; - } + IndexName? indexName = reader.GetString(); + return indexName; + } - writer.WriteStringValue(_settings.Inferrer.IndexName(value)); + public override void Write(Utf8JsonWriter writer, IndexName? value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; } + + writer.WriteStringValue(_settings.Inferrer.IndexName(value)); } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameExtensions.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameExtensions.cs index c8485af65f9..44075fc9d6e 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameExtensions.cs @@ -2,20 +2,18 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch -{ - //public static class IndexNameExtensions - //{ - // public static string? Resolve(this IndexName? marker, IElasticsearchClientSettings elasticsearchClientSettings) - // { - // if (marker == null) - // return null; +namespace Elastic.Clients.Elasticsearch; +//public static class IndexNameExtensions +//{ +// public static string? Resolve(this IndexName? marker, IElasticsearchClientSettings elasticsearchClientSettings) +// { +// if (marker == null) +// return null; - // elasticsearchClientSettings.ThrowIfNull(nameof(elasticsearchClientSettings)); +// elasticsearchClientSettings.ThrowIfNull(nameof(elasticsearchClientSettings)); - // return marker.Type == null - // ? marker.Name - // : new IndexNameResolver(elasticsearchClientSettings).Resolve(marker.Type); - // } - //} -} +// return marker.Type == null +// ? marker.Name +// : new IndexNameResolver(elasticsearchClientSettings).Resolve(marker.Type); +// } +//} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameResolver.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameResolver.cs index c709a0ec394..82526235753 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameResolver.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/IndexName/IndexNameResolver.cs @@ -4,53 +4,52 @@ using System; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal class IndexNameResolver { - internal class IndexNameResolver - { - private readonly IElasticsearchClientSettings _transportClientSettings; + private readonly IElasticsearchClientSettings _transportClientSettings; - public IndexNameResolver(IElasticsearchClientSettings connectionSettings) - { - connectionSettings.ThrowIfNull(nameof(connectionSettings)); - _transportClientSettings = connectionSettings; - } + public IndexNameResolver(IElasticsearchClientSettings connectionSettings) + { + connectionSettings.ThrowIfNull(nameof(connectionSettings)); + _transportClientSettings = connectionSettings; + } - public string Resolve() => Resolve(typeof(T)); + public string Resolve() => Resolve(typeof(T)); - public string Resolve(IndexName i) - { - if (string.IsNullOrEmpty(i?.Name)) - return PrefixClusterName(i, Resolve(i?.Type)); + public string Resolve(IndexName i) + { + if (string.IsNullOrEmpty(i?.Name)) + return PrefixClusterName(i, Resolve(i?.Type)); - ValidateIndexName(i.Name); - return PrefixClusterName(i, i.Name); - } + ValidateIndexName(i.Name); + return PrefixClusterName(i, i.Name); + } - public string Resolve(Type type) + public string Resolve(Type type) + { + var indexName = _transportClientSettings.DefaultIndex; + var defaultIndices = _transportClientSettings.DefaultIndices; + if (defaultIndices != null && type != null) { - var indexName = _transportClientSettings.DefaultIndex; - var defaultIndices = _transportClientSettings.DefaultIndices; - if (defaultIndices != null && type != null) - { - if (defaultIndices.TryGetValue(type, out var value) && !string.IsNullOrEmpty(value)) - indexName = value; - } - ValidateIndexName(indexName); - return indexName; + if (defaultIndices.TryGetValue(type, out var value) && !string.IsNullOrEmpty(value)) + indexName = value; } + ValidateIndexName(indexName); + return indexName; + } - private static string PrefixClusterName(IndexName i, string name) => i.Cluster.IsNullOrEmpty() ? name : $"{i.Cluster}:{name}"; + private static string PrefixClusterName(IndexName i, string name) => i.Cluster.IsNullOrEmpty() ? name : $"{i.Cluster}:{name}"; - // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local - private static void ValidateIndexName(string indexName) - { - if (string.IsNullOrWhiteSpace(indexName)) - throw new ArgumentException( - "Index name is null for the given type and no default index is set. " - + "Map an index name using ConnectionSettings.DefaultMappingFor() " - + "or set a default index using ConnectionSettings.DefaultIndex()." - ); - } + // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local + private static void ValidateIndexName(string indexName) + { + if (string.IsNullOrWhiteSpace(indexName)) + throw new ArgumentException( + "Index name is null for the given type and no default index is set. " + + "Map an index name using ConnectionSettings.DefaultMappingFor() " + + "or set a default index using ConnectionSettings.DefaultIndex()." + ); } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Inferrer.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Inferrer.cs index 3e1d47560fa..5b9f8140d79 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Inferrer.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Inferrer.cs @@ -5,64 +5,63 @@ using System; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch -{ - public sealed class Inferrer - { - private readonly IElasticsearchClientSettings _elasticsearchClientSettings; +namespace Elastic.Clients.Elasticsearch; - public Inferrer(IElasticsearchClientSettings elasticsearchClientSettings) - { - elasticsearchClientSettings.ThrowIfNull(nameof(elasticsearchClientSettings)); - _elasticsearchClientSettings = elasticsearchClientSettings; - IdResolver = new IdResolver(elasticsearchClientSettings); - IndexNameResolver = new IndexNameResolver(elasticsearchClientSettings); - RelationNameResolver = new RelationNameResolver(elasticsearchClientSettings); - FieldResolver = new FieldResolver(elasticsearchClientSettings); - RoutingResolver = new RoutingResolver(elasticsearchClientSettings, IdResolver); +public sealed class Inferrer +{ + private readonly IElasticsearchClientSettings _elasticsearchClientSettings; - //CreateMultiHitDelegates = - // new ConcurrentDictionary>>>(); - //CreateSearchResponseDelegates = - // new ConcurrentDictionary>>(); - } + public Inferrer(IElasticsearchClientSettings elasticsearchClientSettings) + { + elasticsearchClientSettings.ThrowIfNull(nameof(elasticsearchClientSettings)); + _elasticsearchClientSettings = elasticsearchClientSettings; + IdResolver = new IdResolver(elasticsearchClientSettings); + IndexNameResolver = new IndexNameResolver(elasticsearchClientSettings); + RelationNameResolver = new RelationNameResolver(elasticsearchClientSettings); + FieldResolver = new FieldResolver(elasticsearchClientSettings); + RoutingResolver = new RoutingResolver(elasticsearchClientSettings, IdResolver); + + //CreateMultiHitDelegates = + // new ConcurrentDictionary>>>(); + //CreateSearchResponseDelegates = + // new ConcurrentDictionary>>(); + } - //internal ConcurrentDictionary>> - // > - // CreateMultiHitDelegates { get; } + //internal ConcurrentDictionary>> + // > + // CreateMultiHitDelegates { get; } - //internal ConcurrentDictionary>> - // CreateSearchResponseDelegates { get; } + //internal ConcurrentDictionary>> + // CreateSearchResponseDelegates { get; } - private FieldResolver FieldResolver { get; } - private IdResolver IdResolver { get; } - private IndexNameResolver IndexNameResolver { get; } - private RelationNameResolver RelationNameResolver { get; } - private RoutingResolver RoutingResolver { get; } + private FieldResolver FieldResolver { get; } + private IdResolver IdResolver { get; } + private IndexNameResolver IndexNameResolver { get; } + private RelationNameResolver RelationNameResolver { get; } + private RoutingResolver RoutingResolver { get; } - public string Resolve(IUrlParameter urlParameter) => urlParameter.GetString(_elasticsearchClientSettings); + public string Resolve(IUrlParameter urlParameter) => urlParameter.GetString(_elasticsearchClientSettings); - public string Field(Field field) => FieldResolver.Resolve(field); + public string Field(Field field) => FieldResolver.Resolve(field); - public string PropertyName(PropertyName property) => FieldResolver.Resolve(property); + public string PropertyName(PropertyName property) => FieldResolver.Resolve(property); - public string IndexName() => IndexNameResolver.Resolve(); + public string IndexName() => IndexNameResolver.Resolve(); - public string IndexName(IndexName index) => IndexNameResolver.Resolve(index); + public string IndexName(IndexName index) => IndexNameResolver.Resolve(index); - public string Id(T instance) => IdResolver.Resolve(instance); + public string Id(T instance) => IdResolver.Resolve(instance); - public string Id(Type type, object instance) => IdResolver.Resolve(type, instance); + public string Id(Type type, object instance) => IdResolver.Resolve(type, instance); - public string RelationName() => RelationNameResolver.Resolve(); + public string RelationName() => RelationNameResolver.Resolve(); - public string RelationName(RelationName type) => RelationNameResolver.Resolve(type); + public string RelationName(RelationName type) => RelationNameResolver.Resolve(type); - public string Routing(T document) => RoutingResolver.Resolve(document); + public string Routing(T document) => RoutingResolver.Resolve(document); - public string Routing(Type type, object instance) => RoutingResolver.Resolve(type, instance); - } + public string Routing(Type type, object instance) => RoutingResolver.Resolve(type, instance); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinField.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinField.cs index 19d3b1e58e3..d3b791c999a 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinField.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinField.cs @@ -5,91 +5,90 @@ using System; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +[JsonConverter(typeof(JoinFieldConverter))] +public class JoinField { - [JsonConverter(typeof(JoinFieldConverter))] - public class JoinField - { - internal Child ChildOption { get; } - internal Parent ParentOption { get; } - internal int Tag { get; } + internal Child ChildOption { get; } + internal Parent ParentOption { get; } + internal int Tag { get; } - public JoinField(Parent parentName) - { - ParentOption = parentName; - Tag = 0; - } + public JoinField(Parent parentName) + { + ParentOption = parentName; + Tag = 0; + } - public JoinField(Child child) - { - ChildOption = child; - Tag = 1; - } + public JoinField(Child child) + { + ChildOption = child; + Tag = 1; + } - public static JoinField Root() => new Parent(typeof(TParent)); + public static JoinField Root() => new Parent(typeof(TParent)); - public static JoinField Root(RelationName parent) => new Parent(parent); + public static JoinField Root(RelationName parent) => new Parent(parent); - public static JoinField Link(RelationName child, Id parentId) => new Child(child, parentId); + public static JoinField Link(RelationName child, Id parentId) => new Child(child, parentId); - public static JoinField Link(TParentDocument parent) where TParentDocument : class => - new Child(typeof(TChild), Id.From(parent)); + public static JoinField Link(TParentDocument parent) where TParentDocument : class => + new Child(typeof(TChild), Id.From(parent)); - public static JoinField Link(Id parentId) => new Child(typeof(TChild), parentId); + public static JoinField Link(Id parentId) => new Child(typeof(TChild), parentId); - public static implicit operator JoinField(Parent parent) => new(parent); + public static implicit operator JoinField(Parent parent) => new(parent); - public static implicit operator JoinField(string parentName) => new(new Parent(parentName)); + public static implicit operator JoinField(string parentName) => new(new Parent(parentName)); - public static implicit operator JoinField(Type parentType) => new(new Parent(parentType)); + public static implicit operator JoinField(Type parentType) => new(new Parent(parentType)); - public static implicit operator JoinField(Child child) => new(child); + public static implicit operator JoinField(Child child) => new(child); - public T Match(Func first, Func second) + public T Match(Func first, Func second) + { + switch (Tag) { - switch (Tag) - { - case 0: - return first(ParentOption); - case 1: - return second(ChildOption); - default: - throw new Exception($"Unrecognized tag value: {Tag}"); - } + case 0: + return first(ParentOption); + case 1: + return second(ChildOption); + default: + throw new Exception($"Unrecognized tag value: {Tag}"); } + } - public void Match(Action first, Action second) + public void Match(Action first, Action second) + { + switch (Tag) { - switch (Tag) - { - case 0: - first(ParentOption); - break; - case 1: - second(ChildOption); - break; - default: - throw new Exception($"Unrecognized tag value: {Tag}"); - } + case 0: + first(ParentOption); + break; + case 1: + second(ChildOption); + break; + default: + throw new Exception($"Unrecognized tag value: {Tag}"); } + } - public class Parent - { - public Parent(RelationName name) => Name = name; + public class Parent + { + public Parent(RelationName name) => Name = name; - public RelationName Name { get; } - } + public RelationName Name { get; } + } - public class Child + public class Child + { + public Child(RelationName name, Id parent) { - public Child(RelationName name, Id parent) - { - Name = name; - ParentId = parent; - } - - public RelationName Name { get; } - public Id ParentId { get; } + Name = name; + ParentId = parent; } + + public RelationName Name { get; } + public Id ParentId { get; } } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldConverter.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldConverter.cs index 9a1c9e775e2..a389b788388 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldConverter.cs @@ -7,75 +7,74 @@ using System.Text.Json; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal sealed class JoinFieldConverter : JsonConverter { - internal sealed class JoinFieldConverter : JsonConverter - { - private readonly IElasticsearchClientSettings _elasticsearchClientSettings; + private readonly IElasticsearchClientSettings _elasticsearchClientSettings; - public JoinFieldConverter(IElasticsearchClientSettings elasticsearchClientSettings) => _elasticsearchClientSettings = elasticsearchClientSettings; + public JoinFieldConverter(IElasticsearchClientSettings elasticsearchClientSettings) => _elasticsearchClientSettings = elasticsearchClientSettings; - public override JoinField? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override JoinField? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) { - if (reader.TokenType == JsonTokenType.String) - { - var parent = reader.GetString(); - return new JoinField(new JoinField.Parent(parent)); - } + var parent = reader.GetString(); + return new JoinField(new JoinField.Parent(parent)); + } - Id parentId = null; - string name = null; + Id parentId = null; + string name = null; - while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) - { - if (reader.TokenType != JsonTokenType.PropertyName) - throw new JsonException($"Unexpected token. Expected {JsonTokenType.PropertyName}, but read {reader.TokenType}."); + while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) + { + if (reader.TokenType != JsonTokenType.PropertyName) + throw new JsonException($"Unexpected token. Expected {JsonTokenType.PropertyName}, but read {reader.TokenType}."); - var propertyName = reader.GetString(); - reader.Read(); + var propertyName = reader.GetString(); + reader.Read(); - switch (propertyName) - { - case "parent": - parentId = JsonSerializer.Deserialize(ref reader, options); - break; - case "name": - name = reader.GetString(); - break; - default: - throw new JsonException($"Read an unexpected property name {propertyName}."); - } + switch (propertyName) + { + case "parent": + parentId = JsonSerializer.Deserialize(ref reader, options); + break; + case "name": + name = reader.GetString(); + break; + default: + throw new JsonException($"Read an unexpected property name {propertyName}."); } - - return parentId != null - ? new JoinField(new JoinField.Child(name, parentId)) - : new JoinField(new JoinField.Parent(name)); } - public override void Write(Utf8JsonWriter writer, JoinField value, JsonSerializerOptions options) + return parentId != null + ? new JoinField(new JoinField.Child(name, parentId)) + : new JoinField(new JoinField.Parent(name)); + } + + public override void Write(Utf8JsonWriter writer, JoinField value, JsonSerializerOptions options) + { + if (value is null) { - if (value is null) - { - writer.WriteNullValue(); - return; - } + writer.WriteNullValue(); + return; + } - switch (value.Tag) - { - case 0: - JsonSerializer.Serialize(writer, value.ParentOption.Name, options); - break; + switch (value.Tag) + { + case 0: + JsonSerializer.Serialize(writer, value.ParentOption.Name, options); + break; - case 1: - writer.WriteStartObject(); - writer.WritePropertyName("name"); - JsonSerializer.Serialize(writer, value.ChildOption.Name, options); - writer.WritePropertyName("parent"); - var id = (value.ChildOption.ParentId as IUrlParameter)?.GetString(_elasticsearchClientSettings); - writer.WriteStringValue(id); - writer.WriteEndObject(); - break; - } + case 1: + writer.WriteStartObject(); + writer.WritePropertyName("name"); + JsonSerializer.Serialize(writer, value.ChildOption.Name, options); + writer.WritePropertyName("parent"); + var id = (value.ChildOption.ParentId as IUrlParameter)?.GetString(_elasticsearchClientSettings); + writer.WriteStringValue(id); + writer.WriteEndObject(); + break; } } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldRouting/Routing.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldRouting/Routing.cs index 6f62f96c46e..f88d48eb558 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldRouting/Routing.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldRouting/Routing.cs @@ -10,168 +10,167 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +[JsonConverter(typeof(RoutingConverter))] +[DebuggerDisplay("{" + nameof(DebugDisplay) + ",nq}")] +public class Routing : IEquatable, IUrlParameter { - [JsonConverter(typeof(RoutingConverter))] - [DebuggerDisplay("{" + nameof(DebugDisplay) + ",nq}")] - public class Routing : IEquatable, IUrlParameter - { - private static readonly char[] Separator = {','}; + private static readonly char[] Separator = {','}; - internal Routing(Func documentGetter) - { - Tag = 0; - DocumentGetter = documentGetter; - } + internal Routing(Func documentGetter) + { + Tag = 0; + DocumentGetter = documentGetter; + } - public Routing(string routing) - { - Tag = 1; - StringValue = routing; - } + public Routing(string routing) + { + Tag = 1; + StringValue = routing; + } - public Routing(long routing) - { - Tag = 2; - LongValue = routing; - } + public Routing(long routing) + { + Tag = 2; + LongValue = routing; + } - public Routing(object document) - { - Tag = 4; - Document = document; - } + public Routing(object document) + { + Tag = 4; + Document = document; + } - internal object Document { get; } - internal Func DocumentGetter { get; } - internal long? LongValue { get; } - internal string StringOrLongValue => StringValue ?? LongValue?.ToString(CultureInfo.InvariantCulture); - internal string StringValue { get; } + internal object Document { get; } + internal Func DocumentGetter { get; } + internal long? LongValue { get; } + internal string StringOrLongValue => StringValue ?? LongValue?.ToString(CultureInfo.InvariantCulture); + internal string StringValue { get; } - internal int Tag { get; } + internal int Tag { get; } - private string DebugDisplay => StringOrLongValue ?? "Routing from instance typeof: " + Document?.GetType().Name; + private string DebugDisplay => StringOrLongValue ?? "Routing from instance typeof: " + Document?.GetType().Name; - private static int TypeHashCode { get; } = typeof(Routing).GetHashCode(); + private static int TypeHashCode { get; } = typeof(Routing).GetHashCode(); - public bool Equals(Routing other) + public bool Equals(Routing other) + { + if (other == null) + return false; + if (Tag == other.Tag) { - if (other == null) - return false; - if (Tag == other.Tag) + switch (Tag) { - switch (Tag) - { - case 0: - var t = DocumentGetter(); - var o = other.DocumentGetter(); - return t?.Equals(o) ?? false; - case 4: - return Document?.Equals(other.Document) ?? false; - default: - return StringEquals(StringOrLongValue, other.StringOrLongValue); - } + case 0: + var t = DocumentGetter(); + var o = other.DocumentGetter(); + return t?.Equals(o) ?? false; + case 4: + return Document?.Equals(other.Document) ?? false; + default: + return StringEquals(StringOrLongValue, other.StringOrLongValue); } - else if (Tag + other.Tag == 3) - return StringEquals(StringOrLongValue, other.StringOrLongValue); - else - return false; } + else if (Tag + other.Tag == 3) + return StringEquals(StringOrLongValue, other.StringOrLongValue); + else + return false; + } - string IUrlParameter.GetString(ITransportConfiguration? settings) - { - var ElasticsearchClientSettings = settings as IElasticsearchClientSettings; - return GetString(ElasticsearchClientSettings); - } + string IUrlParameter.GetString(ITransportConfiguration? settings) + { + var ElasticsearchClientSettings = settings as IElasticsearchClientSettings; + return GetString(ElasticsearchClientSettings); + } - public override string ToString() => DebugDisplay; + public override string ToString() => DebugDisplay; - public static implicit operator Routing(string routing) => - routing.IsNullOrEmptyCommaSeparatedList(out _) ? null : new Routing(routing); + public static implicit operator Routing(string routing) => + routing.IsNullOrEmptyCommaSeparatedList(out _) ? null : new Routing(routing); - public static implicit operator Routing(string[] routing) => - routing.IsEmpty() ? null : new Routing(string.Join(",", routing)); + public static implicit operator Routing(string[] routing) => + routing.IsEmpty() ? null : new Routing(string.Join(",", routing)); - public static implicit operator Routing(long routing) => new(routing); + public static implicit operator Routing(long routing) => new(routing); - public static implicit operator Routing(Guid routing) => new(routing.ToString("D")); + public static implicit operator Routing(Guid routing) => new(routing.ToString("D")); - /// Use the inferred routing from - public static Routing From(T document) where T : class => new(document); + /// Use the inferred routing from + public static Routing From(T document) where T : class => new(document); - internal string GetString(IElasticsearchClientSettings settings) + internal string GetString(IElasticsearchClientSettings settings) + { + string value = null; + if (DocumentGetter != null) { - string value = null; - if (DocumentGetter != null) - { - var doc = DocumentGetter(); - value = settings.Inferrer.Routing(doc); - } - else if (Document != null) - value = settings.Inferrer.Routing(Document); - - return value ?? StringOrLongValue; + var doc = DocumentGetter(); + value = settings.Inferrer.Routing(doc); } + else if (Document != null) + value = settings.Inferrer.Routing(Document); - public static bool operator ==(Routing left, Routing right) => Equals(left, right); + return value ?? StringOrLongValue; + } - public static bool operator !=(Routing left, Routing right) => !Equals(left, right); + public static bool operator ==(Routing left, Routing right) => Equals(left, right); - private static bool StringEquals(string left, string right) - { - if (left == null && right == null) - return true; - else if (left == null || right == null) - return false; + public static bool operator !=(Routing left, Routing right) => !Equals(left, right); - if (!left.Contains(",") || !right.Contains(",")) - return left == right; + private static bool StringEquals(string left, string right) + { + if (left == null && right == null) + return true; + else if (left == null || right == null) + return false; - var l1 = left.Split(Separator, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()).ToList(); - var l2 = right.Split(Separator, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()).ToList(); - if (l1.Count != l2.Count) - return false; + if (!left.Contains(",") || !right.Contains(",")) + return left == right; - return l1.Count == l2.Count && !l1.Except(l2).Any(); - } + var l1 = left.Split(Separator, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()).ToList(); + var l2 = right.Split(Separator, StringSplitOptions.RemoveEmptyEntries).Select(v => v.Trim()).ToList(); + if (l1.Count != l2.Count) + return false; - public override bool Equals(object obj) - { - switch (obj) - { - case Routing r: - return Equals(r); - case string s: - return Equals(s); - case int l: - return Equals(l); - case long l: - return Equals(l); - case Guid g: - return Equals(g); - } + return l1.Count == l2.Count && !l1.Except(l2).Any(); + } - return Equals(new Routing(obj)); + public override bool Equals(object obj) + { + switch (obj) + { + case Routing r: + return Equals(r); + case string s: + return Equals(s); + case int l: + return Equals(l); + case long l: + return Equals(l); + case Guid g: + return Equals(g); } - public override int GetHashCode() + return Equals(new Routing(obj)); + } + + public override int GetHashCode() + { + unchecked { - unchecked - { - var result = TypeHashCode; - result = (result * 397) ^ (StringValue?.GetHashCode() ?? 0); - result = (result * 397) ^ (LongValue?.GetHashCode() ?? 0); - result = (result * 397) ^ (DocumentGetter?.GetHashCode() ?? 0); - result = (result * 397) ^ (Document?.GetHashCode() ?? 0); - return result; - } + var result = TypeHashCode; + result = (result * 397) ^ (StringValue?.GetHashCode() ?? 0); + result = (result * 397) ^ (LongValue?.GetHashCode() ?? 0); + result = (result * 397) ^ (DocumentGetter?.GetHashCode() ?? 0); + result = (result * 397) ^ (Document?.GetHashCode() ?? 0); + return result; } - - //internal bool ShouldSerialize(IJsonFormatterResolver formatterResolver) - //{ - // var inferrer = formatterResolver.GetConnectionSettings().Inferrer; - // var resolved = inferrer.Resolve(this); - // return !resolved.IsNullOrEmpty(); - //} } + + //internal bool ShouldSerialize(IJsonFormatterResolver formatterResolver) + //{ + // var inferrer = formatterResolver.GetConnectionSettings().Inferrer; + // var resolved = inferrer.Resolve(this); + // return !resolved.IsNullOrEmpty(); + //} } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldRouting/RoutingConverter.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldRouting/RoutingConverter.cs index f61510dae58..1ee6b32718c 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldRouting/RoutingConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/JoinFieldRouting/RoutingConverter.cs @@ -6,53 +6,52 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal sealed class RoutingConverter : JsonConverter { - internal sealed class RoutingConverter : JsonConverter - { - private readonly IElasticsearchClientSettings _settings; + private readonly IElasticsearchClientSettings _settings; + + public RoutingConverter(IElasticsearchClientSettings settings) => _settings = settings; - public RoutingConverter(IElasticsearchClientSettings settings) => _settings = settings; + public override Routing? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + reader.TokenType == JsonTokenType.Number + ? new Routing(reader.GetInt64()) + : new Routing(reader.GetString()); - public override Routing? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => - reader.TokenType == JsonTokenType.Number - ? new Routing(reader.GetInt64()) - : new Routing(reader.GetString()); + public override void Write(Utf8JsonWriter writer, Routing value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } - public override void Write(Utf8JsonWriter writer, Routing value, JsonSerializerOptions options) + if (value.Document is not null) { - if (value is null) + var documentId = _settings.Inferrer.Routing(value.Document.GetType(), value.Document); + + if (documentId is null) { writer.WriteNullValue(); return; } - if (value.Document is not null) - { - var documentId = _settings.Inferrer.Routing(value.Document.GetType(), value.Document); - - if (documentId is null) - { - writer.WriteNullValue(); - return; - } - - writer.WriteStringValue(documentId); - } - else if (value.DocumentGetter is not null) - { - var doc = value.DocumentGetter(); - var documentId = _settings.Inferrer.Routing(doc.GetType(), doc); - writer.WriteStringValue(documentId); - } - else if (value.LongValue.HasValue) - { - writer.WriteNumberValue(value.LongValue.Value); - } - else - { - writer.WriteStringValue(value.StringValue); - } + writer.WriteStringValue(documentId); + } + else if (value.DocumentGetter is not null) + { + var doc = value.DocumentGetter(); + var documentId = _settings.Inferrer.Routing(doc.GetType(), doc); + writer.WriteStringValue(documentId); + } + else if (value.LongValue.HasValue) + { + writer.WriteNumberValue(value.LongValue.Value); + } + else + { + writer.WriteStringValue(value.StringValue); } } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyMapping.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyMapping.cs index 45d548510ed..3292fe6cdb6 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyMapping.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyMapping.cs @@ -5,34 +5,33 @@ using System; using Elastic.Clients.Elasticsearch.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +/// Represents meta data about a property which may be used by inferrence and during serialization. +/// +public readonly struct PropertyMapping : IEquatable { + public static PropertyMapping Ignored = new() { Ignore = true }; + /// - /// Represents meta data about a property which may be used by inferrence and during serialization. + /// The property should be ignored during serialization. + /// + /// NOTE: This only applies if a custom source serializer is registered which supports + /// modifying the JSON contract. The does not support + /// ignoring properties via a . + /// /// - public readonly struct PropertyMapping : IEquatable - { - public static PropertyMapping Ignored = new() { Ignore = true }; - - /// - /// The property should be ignored during serialization. - /// - /// NOTE: This only applies if a custom source serializer is registered which supports - /// modifying the JSON contract. The does not support - /// ignoring properties via a . - /// - /// - public bool Ignore { get; init; } + public bool Ignore { get; init; } - /// - /// The JSON name for the property. - /// - public string? Name { get; init; } + /// + /// The JSON name for the property. + /// + public string? Name { get; init; } - public override bool Equals(object? obj) => obj is PropertyMapping mapping && Equals(mapping); - public bool Equals(PropertyMapping other) => Ignore.Equals(other.Ignore) && Name.Equals(other.Name); - public static bool operator ==(PropertyMapping a, PropertyMapping b) => a.Equals(b); - public static bool operator !=(PropertyMapping a, PropertyMapping b) => !(a == b); - public override int GetHashCode() => (Ignore, Name).GetHashCode(); - } + public override bool Equals(object? obj) => obj is PropertyMapping mapping && Equals(mapping); + public bool Equals(PropertyMapping other) => Ignore.Equals(other.Ignore) && Name.Equals(other.Name); + public static bool operator ==(PropertyMapping a, PropertyMapping b) => a.Equals(b); + public static bool operator !=(PropertyMapping a, PropertyMapping b) => !(a == b); + public override int GetHashCode() => (Ignore, Name).GetHashCode(); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyName.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyName.cs index ece36b82d7d..03db8f0d4d4 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyName.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyName.cs @@ -10,96 +10,95 @@ using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +[DebuggerDisplay("{" + nameof(DebugDisplay) + ",nq}")] +[JsonConverter(typeof(PropertyNameConverter))] +public sealed class PropertyName : IEquatable, IUrlParameter { - [DebuggerDisplay("{" + nameof(DebugDisplay) + ",nq}")] - [JsonConverter(typeof(PropertyNameConverter))] - public sealed class PropertyName : IEquatable, IUrlParameter - { - private readonly object _comparisonValue; - private readonly Type _type; + private readonly object _comparisonValue; + private readonly Type _type; - public PropertyName(string name) - { - Name = name; - _comparisonValue = name; - } + public PropertyName(string name) + { + Name = name; + _comparisonValue = name; + } - public PropertyName(Expression expression) - { - Expression = expression; - _comparisonValue = expression.ComparisonValueFromExpression(out var type, out var cachable); - CacheableExpression = cachable; - _type = type; - } + public PropertyName(Expression expression) + { + Expression = expression; + _comparisonValue = expression.ComparisonValueFromExpression(out var type, out var cachable); + CacheableExpression = cachable; + _type = type; + } - public PropertyName(PropertyInfo property) - { - Property = property; - _comparisonValue = property; - _type = property.DeclaringType; - } + public PropertyName(PropertyInfo property) + { + Property = property; + _comparisonValue = property; + _type = property.DeclaringType; + } - public bool CacheableExpression { get; } - public Expression Expression { get; } + public bool CacheableExpression { get; } + public Expression Expression { get; } - public string? Name { get; } - public PropertyInfo Property { get; } + public string? Name { get; } + public PropertyInfo Property { get; } - internal string DebugDisplay => - $"{Expression?.ToString() ?? PropertyDebug ?? Name}{(_type == null ? "" : " typeof: " + _type.Name)}"; + internal string DebugDisplay => + $"{Expression?.ToString() ?? PropertyDebug ?? Name}{(_type == null ? "" : " typeof: " + _type.Name)}"; - private string PropertyDebug => Property == null ? null : $"PropertyInfo: {Property.Name}"; - private static int TypeHashCode { get; } = typeof(PropertyName).GetHashCode(); + private string PropertyDebug => Property == null ? null : $"PropertyInfo: {Property.Name}"; + private static int TypeHashCode { get; } = typeof(PropertyName).GetHashCode(); - public bool Equals(PropertyName other) => EqualsMarker(other); + public bool Equals(PropertyName other) => EqualsMarker(other); - string IUrlParameter.GetString(ITransportConfiguration? settings) + string IUrlParameter.GetString(ITransportConfiguration? settings) + { + if (settings is not IElasticsearchClientSettings elasticsearchSettings) { - if (settings is not IElasticsearchClientSettings elasticsearchSettings) - { - throw new ArgumentNullException(nameof(settings), - $"Can not resolve {nameof(PropertyName)} if no {nameof(IElasticsearchClientSettings)} is provided"); - } - - return GetInferredString(elasticsearchSettings); + throw new ArgumentNullException(nameof(settings), + $"Can not resolve {nameof(PropertyName)} if no {nameof(IElasticsearchClientSettings)} is provided"); } - private string GetInferredString(IElasticsearchClientSettings settings) => settings.Inferrer.PropertyName(this); + return GetInferredString(elasticsearchSettings); + } + + private string GetInferredString(IElasticsearchClientSettings settings) => settings.Inferrer.PropertyName(this); - public override string ToString() => DebugDisplay; + public override string ToString() => DebugDisplay; - public static implicit operator PropertyName(string name) => - name.IsNullOrEmpty() ? null : new PropertyName(name); + public static implicit operator PropertyName(string name) => + name.IsNullOrEmpty() ? null : new PropertyName(name); - public static implicit operator PropertyName(Expression expression) => - expression == null ? null : new PropertyName(expression); + public static implicit operator PropertyName(Expression expression) => + expression == null ? null : new PropertyName(expression); - public static implicit operator PropertyName(PropertyInfo property) => - property == null ? null : new PropertyName(property); + public static implicit operator PropertyName(PropertyInfo property) => + property == null ? null : new PropertyName(property); - public override int GetHashCode() + public override int GetHashCode() + { + unchecked { - unchecked - { - var result = TypeHashCode; - result = (result * 397) ^ (_comparisonValue?.GetHashCode() ?? 0); - result = (result * 397) ^ (_type?.GetHashCode() ?? 0); - return result; - } + var result = TypeHashCode; + result = (result * 397) ^ (_comparisonValue?.GetHashCode() ?? 0); + result = (result * 397) ^ (_type?.GetHashCode() ?? 0); + return result; } + } - public override bool Equals(object obj) => - obj is string s ? EqualsString(s) : obj is PropertyName r && EqualsMarker(r); + public override bool Equals(object obj) => + obj is string s ? EqualsString(s) : obj is PropertyName r && EqualsMarker(r); - private bool EqualsString(string other) => !other.IsNullOrEmpty() && other == Name; + private bool EqualsString(string other) => !other.IsNullOrEmpty() && other == Name; - public bool EqualsMarker(PropertyName other) => _type != null - ? other != null && _type == other._type && _comparisonValue.Equals(other._comparisonValue) - : other != null && _comparisonValue.Equals(other._comparisonValue); + public bool EqualsMarker(PropertyName other) => _type != null + ? other != null && _type == other._type && _comparisonValue.Equals(other._comparisonValue) + : other != null && _comparisonValue.Equals(other._comparisonValue); - public static bool operator ==(PropertyName left, PropertyName right) => Equals(left, right); + public static bool operator ==(PropertyName left, PropertyName right) => Equals(left, right); - public static bool operator !=(PropertyName left, PropertyName right) => !Equals(left, right); - } + public static bool operator !=(PropertyName left, PropertyName right) => !Equals(left, right); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyNameExtensions.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyNameExtensions.cs index f4167d78319..e24e1559818 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyNameExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyNameExtensions.cs @@ -2,12 +2,10 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch -{ - //internal static class PropertyNameExtensions - //{ - // internal static bool IsConditionless(this PropertyName property) => - // property == null || property.Name.IsNullOrEmpty() && property.Expression == null && - // property.Property == null; - //} -} +namespace Elastic.Clients.Elasticsearch; +//internal static class PropertyNameExtensions +//{ +// internal static bool IsConditionless(this PropertyName property) => +// property == null || property.Name.IsNullOrEmpty() && property.Expression == null && +// property.Property == null; +//} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/RoutingResolver.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/RoutingResolver.cs index a1b58072cc1..dac444251ac 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/RoutingResolver.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/RoutingResolver.cs @@ -7,120 +7,119 @@ using System.Reflection; using System.Linq; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public class RoutingResolver { - public class RoutingResolver - { - private static readonly ConcurrentDictionary> PropertyGetDelegates = - new(); + private static readonly ConcurrentDictionary> PropertyGetDelegates = + new(); - private static readonly MethodInfo MakeDelegateMethodInfo = - typeof(RoutingResolver).GetMethod(nameof(MakeDelegate), BindingFlags.Static | BindingFlags.NonPublic); + private static readonly MethodInfo MakeDelegateMethodInfo = + typeof(RoutingResolver).GetMethod(nameof(MakeDelegate), BindingFlags.Static | BindingFlags.NonPublic); - private readonly IElasticsearchClientSettings _transportClientSettings; - private readonly IdResolver _idResolver; + private readonly IElasticsearchClientSettings _transportClientSettings; + private readonly IdResolver _idResolver; - private readonly ConcurrentDictionary> - _localRouteDelegates = new(); + private readonly ConcurrentDictionary> + _localRouteDelegates = new(); - public RoutingResolver(IElasticsearchClientSettings connectionSettings, IdResolver idResolver) - { - _transportClientSettings = connectionSettings; - _idResolver = idResolver; - } + public RoutingResolver(IElasticsearchClientSettings connectionSettings, IdResolver idResolver) + { + _transportClientSettings = connectionSettings; + _idResolver = idResolver; + } - private PropertyInfo GetPropertyCaseInsensitive(Type type, string fieldName) => - type.GetProperty(fieldName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); + private PropertyInfo GetPropertyCaseInsensitive(Type type, string fieldName) => + type.GetProperty(fieldName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); - internal static Func MakeDelegate(MethodInfo @get) - { - var f = (Func)@get.CreateDelegate(typeof(Func)); - return t => f((T)t); - } + internal static Func MakeDelegate(MethodInfo @get) + { + var f = (Func)@get.CreateDelegate(typeof(Func)); + return t => f((T)t); + } - public string Resolve(T @object) => @object == null ? null : Resolve(@object.GetType(), @object); + public string Resolve(T @object) => @object == null ? null : Resolve(@object.GetType(), @object); - public string Resolve(Type type, object @object) - { - if (TryConnectionSettingsRoute(type, @object, out var route)) - return route; + public string Resolve(Type type, object @object) + { + if (TryConnectionSettingsRoute(type, @object, out var route)) + return route; - var joinField = GetJoinFieldFromObject(type, @object); - return joinField?.Match(p => _idResolver.Resolve(@object), c => ResolveId(c.ParentId, _transportClientSettings)); - } + var joinField = GetJoinFieldFromObject(type, @object); + return joinField?.Match(p => _idResolver.Resolve(@object), c => ResolveId(c.ParentId, _transportClientSettings)); + } + + private bool TryConnectionSettingsRoute(Type type, object @object, out string route) + { + route = null; + if (!_transportClientSettings.RouteProperties.TryGetValue(type, out var propertyName)) + return false; - private bool TryConnectionSettingsRoute(Type type, object @object, out string route) + if (_localRouteDelegates.TryGetValue(type, out var cachedLookup)) { - route = null; - if (!_transportClientSettings.RouteProperties.TryGetValue(type, out var propertyName)) - return false; - - if (_localRouteDelegates.TryGetValue(type, out var cachedLookup)) - { - route = cachedLookup(@object); - return true; - } - var property = GetPropertyCaseInsensitive(type, propertyName); - var func = CreateGetterFunc(type, property); - cachedLookup = o => - { - var v = func(o); - return v?.ToString(); - }; - _localRouteDelegates.TryAdd(type, cachedLookup); route = cachedLookup(@object); return true; } + var property = GetPropertyCaseInsensitive(type, propertyName); + var func = CreateGetterFunc(type, property); + cachedLookup = o => + { + var v = func(o); + return v?.ToString(); + }; + _localRouteDelegates.TryAdd(type, cachedLookup); + route = cachedLookup(@object); + return true; + } - private string ResolveId(Id id, IElasticsearchClientSettings settings) => - id.Document != null ? settings.Inferrer.Id(id.Document) : id.StringOrLongValue; + private string ResolveId(Id id, IElasticsearchClientSettings settings) => + id.Document != null ? settings.Inferrer.Id(id.Document) : id.StringOrLongValue; - private static JoinField GetJoinFieldFromObject(Type type, object @object) - { - if (type == null || @object == null) - return null; - - if (PropertyGetDelegates.TryGetValue(type, out var cachedLookup)) - return cachedLookup(@object); - - var joinProperty = GetJoinFieldProperty(type); - if (joinProperty == null) - { - PropertyGetDelegates.TryAdd(type, o => null); - return null; - } - - var func = CreateGetterFunc(type, joinProperty); - cachedLookup = o => - { - var v = func(o); - return v as JoinField; - }; - PropertyGetDelegates.TryAdd(type, cachedLookup); + private static JoinField GetJoinFieldFromObject(Type type, object @object) + { + if (type == null || @object == null) + return null; + + if (PropertyGetDelegates.TryGetValue(type, out var cachedLookup)) return cachedLookup(@object); - } - private static Func CreateGetterFunc(Type type, PropertyInfo joinProperty) + var joinProperty = GetJoinFieldProperty(type); + if (joinProperty == null) { - var getMethod = joinProperty.GetMethod; - var generic = MakeDelegateMethodInfo.MakeGenericMethod(type, getMethod.ReturnType); - var func = (Func)generic.Invoke(null, new object[] { getMethod }); - return func; + PropertyGetDelegates.TryAdd(type, o => null); + return null; } - private static PropertyInfo GetJoinFieldProperty(Type type) + var func = CreateGetterFunc(type, joinProperty); + cachedLookup = o => + { + var v = func(o); + return v as JoinField; + }; + PropertyGetDelegates.TryAdd(type, cachedLookup); + return cachedLookup(@object); + } + + private static Func CreateGetterFunc(Type type, PropertyInfo joinProperty) + { + var getMethod = joinProperty.GetMethod; + var generic = MakeDelegateMethodInfo.MakeGenericMethod(type, getMethod.ReturnType); + var func = (Func)generic.Invoke(null, new object[] { getMethod }); + return func; + } + + private static PropertyInfo GetJoinFieldProperty(Type type) + { + var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); + try + { + var joinField = properties.SingleOrDefault(p => p.PropertyType == typeof(JoinField)); + return joinField; + } + catch (InvalidOperationException e) { - var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); - try - { - var joinField = properties.SingleOrDefault(p => p.PropertyType == typeof(JoinField)); - return joinField; - } - catch (InvalidOperationException e) - { - throw new ArgumentException($"{type.Name} has more than one JoinField property", e); - } + throw new ArgumentException($"{type.Name} has more than one JoinField property", e); } } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/Timestamp/Timestamp.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/Timestamp/Timestamp.cs index f00931cd739..a5912010db1 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/Timestamp/Timestamp.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/Timestamp/Timestamp.cs @@ -6,37 +6,36 @@ using System.Globalization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public sealed class Timestamp : IUrlParameter, IEquatable { - public sealed class Timestamp : IUrlParameter, IEquatable - { - internal readonly long Value; + internal readonly long Value; - public Timestamp(long value) => Value = value; + public Timestamp(long value) => Value = value; - public bool Equals(Timestamp other) => Value == other.Value; + public bool Equals(Timestamp other) => Value == other.Value; - // ReSharper disable once ImpureMethodCallOnReadonlyValueField - public string GetString(ITransportConfiguration settings) => Value.ToString(CultureInfo.InvariantCulture); + // ReSharper disable once ImpureMethodCallOnReadonlyValueField + public string GetString(ITransportConfiguration settings) => Value.ToString(CultureInfo.InvariantCulture); - public static implicit operator Timestamp(DateTimeOffset categoryId) => new(categoryId.ToUnixTimeMilliseconds()); + public static implicit operator Timestamp(DateTimeOffset categoryId) => new(categoryId.ToUnixTimeMilliseconds()); - public static implicit operator Timestamp(long categoryId) => new(categoryId); + public static implicit operator Timestamp(long categoryId) => new(categoryId); - public static implicit operator long(Timestamp categoryId) => categoryId.Value; + public static implicit operator long(Timestamp categoryId) => categoryId.Value; - public override bool Equals(object obj) => obj switch - { - int l => Value == l, - long l => Value == l, - Timestamp i => Value == i.Value, - _ => false, - }; + public override bool Equals(object obj) => obj switch + { + int l => Value == l, + long l => Value == l, + Timestamp i => Value == i.Value, + _ => false, + }; - public override int GetHashCode() => Value.GetHashCode(); + public override int GetHashCode() => Value.GetHashCode(); - public static bool operator ==(Timestamp left, Timestamp right) => Equals(left, right); + public static bool operator ==(Timestamp left, Timestamp right) => Equals(left, right); - public static bool operator !=(Timestamp left, Timestamp right) => !Equals(left, right); - } + public static bool operator !=(Timestamp left, Timestamp right) => !Equals(left, right); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/IsADictionaryBase.cs b/src/Elastic.Clients.Elasticsearch/Common/IsADictionary.cs similarity index 100% rename from src/Elastic.Clients.Elasticsearch/Common/IsADictionaryBase.cs rename to src/Elastic.Clients.Elasticsearch/Common/IsADictionary.cs diff --git a/src/Elastic.Clients.Elasticsearch/Common/LazyJson.cs b/src/Elastic.Clients.Elasticsearch/Common/LazyJson.cs index 597e56bbccb..a09bd9c56bd 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/LazyJson.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/LazyJson.cs @@ -6,57 +6,56 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +/// Lazily deserializable JSON. +/// Holds raw JSON bytes which can be lazily deserialized to a specific using the source serializer at a later time. +/// +[JsonConverter(typeof(LazyJsonConverter))] +public readonly struct LazyJson { - /// - /// Lazily deserializable JSON. - /// Holds raw JSON bytes which can be lazily deserialized to a specific using the source serializer at a later time. - /// - [JsonConverter(typeof(LazyJsonConverter))] - public readonly struct LazyJson + internal LazyJson(byte[] bytes, IElasticsearchClientSettings settings) { - internal LazyJson(byte[] bytes, IElasticsearchClientSettings settings) - { - Bytes = bytes; - Settings = settings; - } - - internal byte[]? Bytes { get; } - internal IElasticsearchClientSettings? Settings { get; } - - /// - /// Creates an instance of from this - /// instance. - /// - /// The type - public T? As() - { - if (Bytes is null || Settings is null || Bytes.Length == 0) - return default; - - using var ms = Settings.MemoryStreamFactory.Create(Bytes); - return Settings.SourceSerializer.Deserialize(ms); - } + Bytes = bytes; + Settings = settings; } - internal sealed class LazyJsonConverter : JsonConverter + internal byte[]? Bytes { get; } + internal IElasticsearchClientSettings? Settings { get; } + + /// + /// Creates an instance of from this + /// instance. + /// + /// The type + public T? As() { - private readonly IElasticsearchClientSettings _settings; + if (Bytes is null || Settings is null || Bytes.Length == 0) + return default; - public LazyJsonConverter(IElasticsearchClientSettings settings) => _settings = settings; + using var ms = Settings.MemoryStreamFactory.Create(Bytes); + return Settings.SourceSerializer.Deserialize(ms); + } +} - public override LazyJson Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - using var jsonDoc = JsonSerializer.Deserialize(ref reader); - using var stream = _settings.MemoryStreamFactory.Create(); +internal sealed class LazyJsonConverter : JsonConverter +{ + private readonly IElasticsearchClientSettings _settings; - var writer = new Utf8JsonWriter(stream); - jsonDoc.WriteTo(writer); - writer.Flush(); + public LazyJsonConverter(IElasticsearchClientSettings settings) => _settings = settings; - return new LazyJson(stream.ToArray(), _settings); - } + public override LazyJson Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + using var jsonDoc = JsonSerializer.Deserialize(ref reader); + using var stream = _settings.MemoryStreamFactory.Create(); - public override void Write(Utf8JsonWriter writer, LazyJson value, JsonSerializerOptions options) => throw new NotImplementedException("We only ever expect to deserialize LazyJson on responses."); + var writer = new Utf8JsonWriter(stream); + jsonDoc.WriteTo(writer); + writer.Flush(); + + return new LazyJson(stream.ToArray(), _settings); } + + public override void Write(Utf8JsonWriter writer, LazyJson value, JsonSerializerOptions options) => throw new NotImplementedException("We only ever expect to deserialize LazyJson on responses."); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/MinimumShouldMatch.cs b/src/Elastic.Clients.Elasticsearch/Common/MinimumShouldMatch.cs index ddff47e538d..b8a954eff2e 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/MinimumShouldMatch.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/MinimumShouldMatch.cs @@ -2,22 +2,21 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public sealed class MinimumShouldMatch : Union { - public sealed class MinimumShouldMatch : Union - { - public MinimumShouldMatch(int count) : base(count) { } + public MinimumShouldMatch(int count) : base(count) { } - public MinimumShouldMatch(string percentage) : base(percentage) { } + public MinimumShouldMatch(string percentage) : base(percentage) { } - public static MinimumShouldMatch Fixed(int count) => count; + public static MinimumShouldMatch Fixed(int count) => count; - public static MinimumShouldMatch Percentage(double percentage) => $"{percentage}%"; + public static MinimumShouldMatch Percentage(double percentage) => $"{percentage}%"; - public static implicit operator MinimumShouldMatch(string first) => new(first); + public static implicit operator MinimumShouldMatch(string first) => new(first); - public static implicit operator MinimumShouldMatch(int second) => new(second); + public static implicit operator MinimumShouldMatch(int second) => new(second); - public static implicit operator MinimumShouldMatch(double second) => Percentage(second); - } + public static implicit operator MinimumShouldMatch(double second) => Percentage(second); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Query/Query.cs b/src/Elastic.Clients.Elasticsearch/Common/Query/Query.cs index d1ea24c91d4..659d94cbc4d 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Query/Query.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Query/Query.cs @@ -2,85 +2,84 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch.QueryDsl +namespace Elastic.Clients.Elasticsearch.QueryDsl; + +public abstract partial class Query { - public abstract partial class Query - { - //[JsonIgnore] - //public bool IsWritable => throw new NotImplementedException(); + //[JsonIgnore] + //public bool IsWritable => throw new NotImplementedException(); - ////protected abstract bool Conditionless { get; } - //[JsonIgnore] - //public bool IsStrict { get; set; } + ////protected abstract bool Conditionless { get; } + //[JsonIgnore] + //public bool IsStrict { get; set; } - //[JsonIgnore] - //public bool IsVerbatim { get; set; } + //[JsonIgnore] + //public bool IsVerbatim { get; set; } - //[JsonIgnore] - //public bool IsWritable => true; //IsVerbatim || !Conditionless; + //[JsonIgnore] + //public bool IsWritable => true; //IsVerbatim || !Conditionless; - //bool IQuery.Conditionless => Conditionless; + //bool IQuery.Conditionless => Conditionless; - //always evaluate to false so that each side of && equation is evaluated - public static bool operator false(Query a) => false; + //always evaluate to false so that each side of && equation is evaluated + public static bool operator false(Query a) => false; - //always evaluate to false so that each side of && equation is evaluated - public static bool operator true(Query a) => false; + //always evaluate to false so that each side of && equation is evaluated + public static bool operator true(Query a) => false; - //public static QueryBase operator &(QueryBase leftQuery, QueryBase rightQuery) => Combine(leftQuery, rightQuery, (l, r) => l && r); + //public static QueryBase operator &(QueryBase leftQuery, QueryBase rightQuery) => Combine(leftQuery, rightQuery, (l, r) => l && r); - //public static QueryBase operator |(QueryBase leftQuery, QueryBase rightQuery) => Combine(leftQuery, rightQuery, (l, r) => l || r); + //public static QueryBase operator |(QueryBase leftQuery, QueryBase rightQuery) => Combine(leftQuery, rightQuery, (l, r) => l || r); - //public static QueryBase operator !(QueryBase query) => query == null || !query.IsWritable - // ? null - // : new BoolQuery { MustNot = new QueryContainer[] { query } }; + //public static QueryBase operator !(QueryBase query) => query == null || !query.IsWritable + // ? null + // : new BoolQuery { MustNot = new QueryContainer[] { query } }; - //public static QueryBase operator +(QueryBase query) => query == null || !query.IsWritable - // ? null - // : new BoolQuery { Filter = new QueryContainer[] { query } }; + //public static QueryBase operator +(QueryBase query) => query == null || !query.IsWritable + // ? null + // : new BoolQuery { Filter = new QueryContainer[] { query } }; - //private static QueryBase Combine(QueryBase leftQuery, QueryBase rightQuery, Func combine) - //{ - // if (IfEitherIsEmptyReturnTheOtherOrEmpty(leftQuery, rightQuery, out var q)) - // return q; + //private static QueryBase Combine(QueryBase leftQuery, QueryBase rightQuery, Func combine) + //{ + // if (IfEitherIsEmptyReturnTheOtherOrEmpty(leftQuery, rightQuery, out var q)) + // return q; - // IQueryContainer container = combine(leftQuery, rightQuery); - // var query = container.Bool; - // return new BoolQuery - // { - // Must = query.Must, - // MustNot = query.MustNot, - // Should = query.Should, - // Filter = query.Filter, - // }; - //} + // IQueryContainer container = combine(leftQuery, rightQuery); + // var query = container.Bool; + // return new BoolQuery + // { + // Must = query.Must, + // MustNot = query.MustNot, + // Should = query.Should, + // Filter = query.Filter, + // }; + //} - //private static bool IfEitherIsEmptyReturnTheOtherOrEmpty(QueryBase leftQuery, QueryBase rightQuery, - // out QueryBase query) - //{ - // query = null; - // if (leftQuery == null && rightQuery == null) - // return true; + //private static bool IfEitherIsEmptyReturnTheOtherOrEmpty(QueryBase leftQuery, QueryBase rightQuery, + // out QueryBase query) + //{ + // query = null; + // if (leftQuery == null && rightQuery == null) + // return true; - // var leftWritable = leftQuery?.IsWritable ?? false; - // var rightWritable = rightQuery?.IsWritable ?? false; - // if (leftWritable && rightWritable) - // return false; - // if (!leftWritable && !rightWritable) - // return true; + // var leftWritable = leftQuery?.IsWritable ?? false; + // var rightWritable = rightQuery?.IsWritable ?? false; + // if (leftWritable && rightWritable) + // return false; + // if (!leftWritable && !rightWritable) + // return true; - // query = leftWritable ? leftQuery : rightQuery; - // return true; - //} + // query = leftWritable ? leftQuery : rightQuery; + // return true; + //} - //public static implicit operator QueryContainer(QueryBase query) => - // query == null ? null : new QueryContainer(query); + //public static implicit operator QueryContainer(QueryBase query) => + // query == null ? null : new QueryContainer(query); - //internal void WrapInContainer(IQueryContainer container) => InternalWrapInContainer(container); + //internal void WrapInContainer(IQueryContainer container) => InternalWrapInContainer(container); - ////container.IsVerbatim = IsVerbatim; - ////container.IsStrict = IsStrict; + ////container.IsVerbatim = IsVerbatim; + ////container.IsStrict = IsStrict; - //internal abstract void InternalWrapInContainer(IQueryContainer container); - } + //internal abstract void InternalWrapInContainer(IQueryContainer container); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/ReadOnlyIndexNameDictionary.cs b/src/Elastic.Clients.Elasticsearch/Common/ReadOnlyIndexNameDictionary.cs index 5bcdc9abd9b..731afb985d4 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/ReadOnlyIndexNameDictionary.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/ReadOnlyIndexNameDictionary.cs @@ -5,57 +5,56 @@ using System.Collections; using System.Collections.Generic; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +/// A specialised readonly dictionary for data, keyed by . +/// This supports inferrence enabled lookups by ensuring keys are sanitized when storing the values and when performing lookups. +/// +/// +public struct ReadOnlyIndexNameDictionary : IReadOnlyDictionary { - /// - /// A specialised readonly dictionary for data, keyed by . - /// This supports inferrence enabled lookups by ensuring keys are sanitized when storing the values and when performing lookups. - /// - /// - public struct ReadOnlyIndexNameDictionary : IReadOnlyDictionary - { - private readonly Dictionary _backingDictionary; - private readonly IElasticsearchClientSettings? _settings; + private readonly Dictionary _backingDictionary; + private readonly IElasticsearchClientSettings? _settings; - public ReadOnlyIndexNameDictionary() - { - _backingDictionary = new Dictionary(0); - _settings = null; - } + public ReadOnlyIndexNameDictionary() + { + _backingDictionary = new Dictionary(0); + _settings = null; + } - internal ReadOnlyIndexNameDictionary(Dictionary source, IElasticsearchClientSettings settings) - { - _settings = settings; + internal ReadOnlyIndexNameDictionary(Dictionary source, IElasticsearchClientSettings settings) + { + _settings = settings; - // This is an "optimised version" which doesn't cause a second dictionary to be allocated. - // Since we expect this to be used only for deserialisation, the keys received will already have been strings, - // so no further sanitisation is required. + // This is an "optimised version" which doesn't cause a second dictionary to be allocated. + // Since we expect this to be used only for deserialisation, the keys received will already have been strings, + // so no further sanitisation is required. - //var backingDictionary = new Dictionary(source.Count); + //var backingDictionary = new Dictionary(source.Count); - if (source == null) - { - _backingDictionary = new Dictionary(0); - return; - } + if (source == null) + { + _backingDictionary = new Dictionary(0); + return; + } - //foreach (var key in source.Keys) - // backingDictionary[Sanitize(key)] = source[key]; + //foreach (var key in source.Keys) + // backingDictionary[Sanitize(key)] = source[key]; - _backingDictionary = source; - } + _backingDictionary = source; + } - private string Sanitize(IndexName key) => _settings is not null ? key?.GetString(_settings) : string.Empty; + private string Sanitize(IndexName key) => _settings is not null ? key?.GetString(_settings) : string.Empty; - public TValue this[IndexName key] => _backingDictionary.TryGetValue(Sanitize(key), out var v) ? v : default; - public TValue this[string key] => _backingDictionary.TryGetValue(key, out var v) ? v : default; + public TValue this[IndexName key] => _backingDictionary.TryGetValue(Sanitize(key), out var v) ? v : default; + public TValue this[string key] => _backingDictionary.TryGetValue(key, out var v) ? v : default; - public IEnumerable Keys => _backingDictionary.Keys; - public IEnumerable Values => _backingDictionary.Values; - public int Count => _backingDictionary.Count; - public bool ContainsKey(IndexName key) => _backingDictionary.ContainsKey(Sanitize(key)); - public IEnumerator> GetEnumerator() => _backingDictionary.GetEnumerator(); - public bool TryGetValue(IndexName key, out TValue value) => _backingDictionary.TryGetValue(Sanitize(key), out value); - IEnumerator IEnumerable.GetEnumerator() => _backingDictionary.GetEnumerator(); - } + public IEnumerable Keys => _backingDictionary.Keys; + public IEnumerable Values => _backingDictionary.Values; + public int Count => _backingDictionary.Count; + public bool ContainsKey(IndexName key) => _backingDictionary.ContainsKey(Sanitize(key)); + public IEnumerator> GetEnumerator() => _backingDictionary.GetEnumerator(); + public bool TryGetValue(IndexName key, out TValue value) => _backingDictionary.TryGetValue(Sanitize(key), out value); + IEnumerator IEnumerable.GetEnumerator() => _backingDictionary.GetEnumerator(); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Static/Infer.cs b/src/Elastic.Clients.Elasticsearch/Common/Static/Infer.cs index 52718728c1e..15b320e96e7 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Static/Infer.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Static/Infer.cs @@ -8,69 +8,68 @@ using System.Linq.Expressions; using System.Reflection; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public static class Infer { - public static class Infer - { - //public static readonly Indices AllIndices = Elastic.Clients.Elasticsearch.Indices.All; + //public static readonly Indices AllIndices = Elastic.Clients.Elasticsearch.Indices.All; - public static IndexName Index(IndexName index) => index; + public static IndexName Index(IndexName index) => index; - public static IndexName Index() => typeof(T); + public static IndexName Index() => typeof(T); - public static IndexName Index(Type type) => type; + public static IndexName Index(Type type) => type; - public static IndexName Index(string clusterName) => IndexName.From(clusterName); + public static IndexName Index(string clusterName) => IndexName.From(clusterName); - public static Indices Indices() => typeof(T); + public static Indices Indices() => typeof(T); - public static Indices Indices(params IndexName[] indices) => indices; + public static Indices Indices(params IndexName[] indices) => indices; - public static Indices Indices(IEnumerable indices) => indices.ToArray(); + public static Indices Indices(IEnumerable indices) => indices.ToArray(); - public static RelationName Relation(string type) => type; + public static RelationName Relation(string type) => type; - public static RelationName Relation(Type type) => type; + public static RelationName Relation(Type type) => type; - public static RelationName Relation() => typeof(T); + public static RelationName Relation() => typeof(T); - public static Routing Route(T instance) where T : class => Routing.From(instance); + public static Routing Route(T instance) where T : class => Routing.From(instance); - public static Names Names(params string[] names) => string.Join(",", names); + public static Names Names(params string[] names) => string.Join(",", names); - public static Names Names(IEnumerable names) => string.Join(",", names); + public static Names Names(IEnumerable names) => string.Join(",", names); - public static Id Id(T document) where T : class => Elasticsearch.Id.From(document); + public static Id Id(T document) where T : class => Elasticsearch.Id.From(document); - public static Fields Fields(params Expression>[] fields) where T : class => - new(fields.Select(f => new Field(f))); + public static Fields Fields(params Expression>[] fields) where T : class => + new(fields.Select(f => new Field(f))); - public static Fields Fields(params string[] fields) => new(fields.Select(f => new Field(f))); + public static Fields Fields(params string[] fields) => new(fields.Select(f => new Field(f))); - public static Fields Fields(params PropertyInfo[] properties) => new(properties.Select(f => new Field(f))); + public static Fields Fields(params PropertyInfo[] properties) => new(properties.Select(f => new Field(f))); - /// - /// Create a strongly typed string field name representation of the path to a property - /// e.g. p => p.Array.First().SubProperty.Field will return 'array.subProperty.field' - /// - public static Field Field(Expression> path, double? boost = null, - string format = null) - => new(path, boost, format); + /// + /// Create a strongly typed string field name representation of the path to a property + /// e.g. p => p.Array.First().SubProperty.Field will return 'array.subProperty.field' + /// + public static Field Field(Expression> path, double? boost = null, + string format = null) + => new(path, boost, format); - /// - public static Field Field(Expression> path, double? boost = null, string format = null) - => new(path, boost, format); + /// + public static Field Field(Expression> path, double? boost = null, string format = null) + => new(path, boost, format); - public static Field Field(string field, double? boost = null, string format = null) => - new(field, boost, format); + public static Field Field(string field, double? boost = null, string format = null) => + new(field, boost, format); - public static Field Field(PropertyInfo property, double? boost = null, string format = null) => - new(property, boost, format); + public static Field Field(PropertyInfo property, double? boost = null, string format = null) => + new(property, boost, format); - public static PropertyName Property(string property) => property; + public static PropertyName Property(string property) => property; - public static PropertyName Property(Expression> path) where T : class => path; + public static PropertyName Property(Expression> path) where T : class => path; - public static PropertyName Property(Expression> path) where T : class => path; - } + public static PropertyName Property(Expression> path) where T : class => path; } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Union/Union.cs b/src/Elastic.Clients.Elasticsearch/Common/Union/Union.cs index 15975e1842d..95fcf32d3a8 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Union/Union.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Union/Union.cs @@ -4,80 +4,79 @@ using System; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +/// +/// Represents the union of two types, and . Used +/// in scenarios where an Elasticsearch API may accept more than one different input data structure. +/// +/// The first type +/// The second type +public class Union { + internal readonly int Tag; + internal readonly TFirst Item1; + internal readonly TSecond Item2; + /// - /// Represents the union of two types, and . Used - /// in scenarios where an Elasticsearch API may accept more than one different input data structure. + /// Creates an new instance of that encapsulates value /// - /// The first type - /// The second type - public class Union + /// The value to encapsulate + public Union(TFirst item) { - internal readonly int Tag; - internal readonly TFirst Item1; - internal readonly TSecond Item2; - - /// - /// Creates an new instance of that encapsulates value - /// - /// The value to encapsulate - public Union(TFirst item) - { - Item1 = item; - Tag = 0; - } + Item1 = item; + Tag = 0; + } - /// - /// Creates an new instance of that encapsulates value - /// - /// The value to encapsulate - public Union(TSecond item) - { - Item2 = item; - Tag = 1; - } + /// + /// Creates an new instance of that encapsulates value + /// + /// The value to encapsulate + public Union(TSecond item) + { + Item2 = item; + Tag = 1; + } - /// - /// Runs an delegate against the encapsulated value - /// - /// The delegate to run when this instance encapsulates an instance of - /// The delegate to run when this instance encapsulates an instance of - public void Match(Action first, Action second) + /// + /// Runs an delegate against the encapsulated value + /// + /// The delegate to run when this instance encapsulates an instance of + /// The delegate to run when this instance encapsulates an instance of + public void Match(Action first, Action second) + { + switch (Tag) { - switch (Tag) - { - case 0: - first(Item1); - break; - case 1: - second(Item2); - break; - default: - throw new Exception($"Unrecognized tag value: {Tag}"); - } + case 0: + first(Item1); + break; + case 1: + second(Item2); + break; + default: + throw new Exception($"Unrecognized tag value: {Tag}"); } + } - /// - /// Runs a delegate against the encapsulated value - /// - /// The delegate to run when this instance encapsulates an instance of - /// The delegate to run when this instance encapsulates an instance of - public T Match(Func first, Func second) + /// + /// Runs a delegate against the encapsulated value + /// + /// The delegate to run when this instance encapsulates an instance of + /// The delegate to run when this instance encapsulates an instance of + public T Match(Func first, Func second) + { + switch (Tag) { - switch (Tag) - { - case 0: - return first(Item1); - case 1: - return second(Item2); - default: - throw new Exception($"Unrecognized tag value: {Tag}"); - } + case 0: + return first(Item1); + case 1: + return second(Item2); + default: + throw new Exception($"Unrecognized tag value: {Tag}"); } + } - public static implicit operator Union(TFirst first) => new(first); + public static implicit operator Union(TFirst first) => new(first); - public static implicit operator Union(TSecond second) => new(second); - } + public static implicit operator Union(TSecond second) => new(second); } diff --git a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/DataStreamNames/DataStreamName.cs b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/DataStreamNames/DataStreamName.cs index 7ef2d45eeab..45de4980f85 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/DataStreamNames/DataStreamName.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/DataStreamNames/DataStreamName.cs @@ -8,72 +8,71 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +[JsonConverter(typeof(DataStreamNameConverter))] +[DebuggerDisplay("{DebugDisplay,nq}")] +public sealed class DataStreamName : IEquatable, IUrlParameter { - [JsonConverter(typeof(DataStreamNameConverter))] - [DebuggerDisplay("{DebugDisplay,nq}")] - public sealed class DataStreamName : IEquatable, IUrlParameter - { - internal DataStreamName(string dataStreamName) => Name = dataStreamName; + internal DataStreamName(string dataStreamName) => Name = dataStreamName; - public string Name { get; } + public string Name { get; } - internal string DebugDisplay => Name; + internal string DebugDisplay => Name; - public static implicit operator DataStreamName(string dataStreamName) => new(dataStreamName); + public static implicit operator DataStreamName(string dataStreamName) => new(dataStreamName); - public static bool operator ==(DataStreamName left, DataStreamName right) => Equals(left, right); + public static bool operator ==(DataStreamName left, DataStreamName right) => Equals(left, right); - public static bool operator !=(DataStreamName left, DataStreamName right) => !Equals(left, right); + public static bool operator !=(DataStreamName left, DataStreamName right) => !Equals(left, right); - bool IEquatable.Equals(DataStreamName other) => EqualsMarker(other); + bool IEquatable.Equals(DataStreamName other) => EqualsMarker(other); - private bool EqualsString(string other) => !other.IsNullOrEmpty() && other.Equals(Name, StringComparison.Ordinal); + private bool EqualsString(string other) => !other.IsNullOrEmpty() && other.Equals(Name, StringComparison.Ordinal); - public override bool Equals(object obj) => obj is string s ? EqualsString(s) : obj is DataStreamName i && EqualsMarker(i); + public override bool Equals(object obj) => obj is string s ? EqualsString(s) : obj is DataStreamName i && EqualsMarker(i); - string IUrlParameter.GetString(ITransportConfiguration? settings) => Name; + string IUrlParameter.GetString(ITransportConfiguration? settings) => Name; - public override string ToString() => Name ?? string.Empty; + public override string ToString() => Name ?? string.Empty; - private bool EqualsMarker(DataStreamName other) - { - if (other == null) - return false; + private bool EqualsMarker(DataStreamName other) + { + if (other == null) + return false; - return EqualsString(other.Name); - } + return EqualsString(other.Name); + } - private static int TypeHashCode { get; } = typeof(DataStreamName).GetHashCode(); + private static int TypeHashCode { get; } = typeof(DataStreamName).GetHashCode(); - public override int GetHashCode() + public override int GetHashCode() + { + unchecked { - unchecked - { - return (TypeHashCode * 23) ^ (Name.GetHashCode()); - } + return (TypeHashCode * 23) ^ (Name.GetHashCode()); } } +} - internal sealed class DataStreamNameConverter : JsonConverter +internal sealed class DataStreamNameConverter : JsonConverter +{ + public override DataStreamName? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - public override DataStreamName? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.String) - throw new JsonException($"Unexpected token '{reader.TokenType}' for DataStreamName"); + if (reader.TokenType != JsonTokenType.String) + throw new JsonException($"Unexpected token '{reader.TokenType}' for DataStreamName"); - return reader.GetString(); - } + return reader.GetString(); + } - public override void Write(Utf8JsonWriter writer, DataStreamName value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, DataStreamName value, JsonSerializerOptions options) + { + if (value is null || value.Name is null) { - if (value is null || value.Name is null) - { - writer.WriteNullValue(); - return; - } - - writer.WriteStringValue(value.Name); + writer.WriteNullValue(); + return; } + + writer.WriteStringValue(value.Name); } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/DataStreamNames/DataStreamNames.cs b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/DataStreamNames/DataStreamNames.cs index 44df2753879..3753699c9c4 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/DataStreamNames/DataStreamNames.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/DataStreamNames/DataStreamNames.cs @@ -11,112 +11,111 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +[JsonConverter(typeof(DataStreamNamesConverter))] +[DebuggerDisplay("{DebugDisplay,nq}")] +public sealed class DataStreamNames : IUrlParameter, IEnumerable, IEquatable { - [JsonConverter(typeof(DataStreamNamesConverter))] - [DebuggerDisplay("{DebugDisplay,nq}")] - public sealed class DataStreamNames : IUrlParameter, IEnumerable, IEquatable - { - internal readonly IList Names; + internal readonly IList Names; - internal DataStreamNames() => Names = new List(); + internal DataStreamNames() => Names = new List(); - internal DataStreamNames(IEnumerable dataStreamNames) => Names = dataStreamNames.ToList(); + internal DataStreamNames(IEnumerable dataStreamNames) => Names = dataStreamNames.ToList(); - internal DataStreamNames(IList dataStreamNames) => Names = dataStreamNames; + internal DataStreamNames(IList dataStreamNames) => Names = dataStreamNames; - private string DebugDisplay => - $"Count: {Names.Count} [" + string.Join(",", Names.Select((t, i) => $"({i + 1}: {t?.DebugDisplay ?? "NULL"})")) + "]"; + private string DebugDisplay => + $"Count: {Names.Count} [" + string.Join(",", Names.Select((t, i) => $"({i + 1}: {t?.DebugDisplay ?? "NULL"})")) + "]"; - public override string ToString() => string.Join(",", Names.Where(f => f is not null).Select(f => f.Name)); + public override string ToString() => string.Join(",", Names.Where(f => f is not null).Select(f => f.Name)); - public static implicit operator DataStreamNames(string[] dataStreamNames) => dataStreamNames.IsEmpty() ? null : new DataStreamNames(dataStreamNames.Select(f => new DataStreamName(f))); + public static implicit operator DataStreamNames(string[] dataStreamNames) => dataStreamNames.IsEmpty() ? null : new DataStreamNames(dataStreamNames.Select(f => new DataStreamName(f))); - public static implicit operator DataStreamNames(string dataStreamName) => dataStreamName.IsNullOrEmptyCommaSeparatedList(out var split) - ? null - : new DataStreamNames(split.Select(f => new DataStreamName(f))); + public static implicit operator DataStreamNames(string dataStreamName) => dataStreamName.IsNullOrEmptyCommaSeparatedList(out var split) + ? null + : new DataStreamNames(split.Select(f => new DataStreamName(f))); - public static implicit operator DataStreamNames(DataStreamName dataStreamName) => dataStreamName == null ? null : new DataStreamNames(new[] { dataStreamName }); + public static implicit operator DataStreamNames(DataStreamName dataStreamName) => dataStreamName == null ? null : new DataStreamNames(new[] { dataStreamName }); - public static implicit operator DataStreamNames(DataStreamName[] dataStreamNames) => dataStreamNames.IsEmpty() ? null : new DataStreamNames(dataStreamNames); + public static implicit operator DataStreamNames(DataStreamName[] dataStreamNames) => dataStreamNames.IsEmpty() ? null : new DataStreamNames(dataStreamNames); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() => Names.GetEnumerator(); + public IEnumerator GetEnumerator() => Names.GetEnumerator(); - public static bool operator ==(DataStreamNames left, DataStreamNames right) => Equals(left, right); + public static bool operator ==(DataStreamNames left, DataStreamNames right) => Equals(left, right); - public static bool operator !=(DataStreamNames left, DataStreamNames right) => !Equals(left, right); + public static bool operator !=(DataStreamNames left, DataStreamNames right) => !Equals(left, right); - public override bool Equals(object obj) => - obj switch - { - DataStreamNames f => Equals(f), - string s => Equals(s), - DataStreamName fn => Equals(fn), - DataStreamName[] fns => Equals(fns), - _ => false, - }; + public override bool Equals(object obj) => + obj switch + { + DataStreamNames f => Equals(f), + string s => Equals(s), + DataStreamName fn => Equals(fn), + DataStreamName[] fns => Equals(fns), + _ => false, + }; - public bool Equals(DataStreamNames other) => EqualsAllNames(Names, other.Names); + public bool Equals(DataStreamNames other) => EqualsAllNames(Names, other.Names); - private static bool EqualsAllNames(IList thisTypes, IList otherTypes) - { - if (thisTypes is null && otherTypes is null) - return true; + private static bool EqualsAllNames(IList thisTypes, IList otherTypes) + { + if (thisTypes is null && otherTypes is null) + return true; - if (thisTypes is null || otherTypes is null) - return false; + if (thisTypes is null || otherTypes is null) + return false; - if (thisTypes.Count != otherTypes.Count) - return false; + if (thisTypes.Count != otherTypes.Count) + return false; - return !thisTypes.Except(otherTypes).Any(); - } + return !thisTypes.Except(otherTypes).Any(); + } - public override int GetHashCode() + public override int GetHashCode() + { + var hashCodes = new List(Names.Count); + foreach (var item in Names) { - var hashCodes = new List(Names.Count); - foreach (var item in Names) - { - hashCodes.Add(item.GetHashCode()); - } + hashCodes.Add(item.GetHashCode()); + } - hashCodes.Sort(); + hashCodes.Sort(); - unchecked + unchecked + { + var hash = 17; + foreach (var hashCode in hashCodes) { - var hash = 17; - foreach (var hashCode in hashCodes) - { - hash = hash * 23 + hashCode; - } - return typeof(DataStreamName).GetHashCode() ^ hash; + hash = hash * 23 + hashCode; } + return typeof(DataStreamName).GetHashCode() ^ hash; } - - string IUrlParameter.GetString(ITransportConfiguration? settings) => ToString(); } - internal sealed class DataStreamNamesConverter : JsonConverter + string IUrlParameter.GetString(ITransportConfiguration? settings) => ToString(); +} + +internal sealed class DataStreamNamesConverter : JsonConverter +{ + public override DataStreamNames? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - public override DataStreamNames? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.StartArray) - throw new JsonException($"Expected {JsonTokenType.StartArray} token but read '{reader.TokenType}' token for DataStreamNames."); + if (reader.TokenType != JsonTokenType.StartArray) + throw new JsonException($"Expected {JsonTokenType.StartArray} token but read '{reader.TokenType}' token for DataStreamNames."); - return JsonSerializer.Deserialize(ref reader, options); - } + return JsonSerializer.Deserialize(ref reader, options); + } - public override void Write(Utf8JsonWriter writer, DataStreamNames value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, DataStreamNames value, JsonSerializerOptions options) + { + if (value is null) { - if (value is null) - { - writer.WriteNullValue(); - return; - } - - JsonSerializer.Serialize(writer, value.Names, options); + writer.WriteNullValue(); + return; } + + JsonSerializer.Serialize(writer, value.Names, options); } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/ScrollIds/ScrollId.cs b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/ScrollIds/ScrollId.cs index e006413bc36..a7f26e6469e 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/ScrollIds/ScrollId.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/ScrollIds/ScrollId.cs @@ -8,72 +8,71 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +[JsonConverter(typeof(ScrollIdConverter))] +[DebuggerDisplay("{DebugDisplay,nq}")] +public sealed class ScrollId : IEquatable, IUrlParameter { - [JsonConverter(typeof(ScrollIdConverter))] - [DebuggerDisplay("{DebugDisplay,nq}")] - public sealed class ScrollId : IEquatable, IUrlParameter - { - internal ScrollId(string scrollId) => Id = scrollId; + internal ScrollId(string scrollId) => Id = scrollId; - public string Id { get; } + public string Id { get; } - internal string DebugDisplay => Id; + internal string DebugDisplay => Id; - public static implicit operator ScrollId(string scrollId) => new(scrollId); + public static implicit operator ScrollId(string scrollId) => new(scrollId); - public static bool operator ==(ScrollId left, ScrollId right) => Equals(left, right); + public static bool operator ==(ScrollId left, ScrollId right) => Equals(left, right); - public static bool operator !=(ScrollId left, ScrollId right) => !Equals(left, right); + public static bool operator !=(ScrollId left, ScrollId right) => !Equals(left, right); - bool IEquatable.Equals(ScrollId other) => EqualsMarker(other); + bool IEquatable.Equals(ScrollId other) => EqualsMarker(other); - private bool EqualsString(string other) => !other.IsNullOrEmpty() && other.Equals(Id, StringComparison.Ordinal); + private bool EqualsString(string other) => !other.IsNullOrEmpty() && other.Equals(Id, StringComparison.Ordinal); - public override bool Equals(object obj) => obj is string s ? EqualsString(s) : obj is ScrollId i && EqualsMarker(i); + public override bool Equals(object obj) => obj is string s ? EqualsString(s) : obj is ScrollId i && EqualsMarker(i); - string IUrlParameter.GetString(ITransportConfiguration? settings) => Id; + string IUrlParameter.GetString(ITransportConfiguration? settings) => Id; - public override string ToString() => Id ?? string.Empty; + public override string ToString() => Id ?? string.Empty; - private bool EqualsMarker(ScrollId other) - { - if (other == null) - return false; + private bool EqualsMarker(ScrollId other) + { + if (other == null) + return false; - return EqualsString(other.Id); - } + return EqualsString(other.Id); + } - private static int TypeHashCode { get; } = typeof(ScrollId).GetHashCode(); + private static int TypeHashCode { get; } = typeof(ScrollId).GetHashCode(); - public override int GetHashCode() + public override int GetHashCode() + { + unchecked { - unchecked - { - return (TypeHashCode * 23) ^ (Id.GetHashCode()); - } + return (TypeHashCode * 23) ^ (Id.GetHashCode()); } } +} - internal sealed class ScrollIdConverter : JsonConverter +internal sealed class ScrollIdConverter : JsonConverter +{ + public override ScrollId? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - public override ScrollId? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.String) - throw new JsonException($"Unexpected token '{reader.TokenType}' for DataStreamName"); + if (reader.TokenType != JsonTokenType.String) + throw new JsonException($"Unexpected token '{reader.TokenType}' for DataStreamName"); - return reader.GetString(); - } + return reader.GetString(); + } - public override void Write(Utf8JsonWriter writer, ScrollId value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, ScrollId value, JsonSerializerOptions options) + { + if (value is null || value.Id is null) { - if (value is null || value.Id is null) - { - writer.WriteNullValue(); - return; - } - - writer.WriteStringValue(value.Id); + writer.WriteNullValue(); + return; } + + writer.WriteStringValue(value.Id); } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/ScrollIds/ScrollIds.cs b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/ScrollIds/ScrollIds.cs index 4021d7a8aa5..d0b2cfaa4a8 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/ScrollIds/ScrollIds.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/ScrollIds/ScrollIds.cs @@ -11,111 +11,110 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +[JsonConverter(typeof(ScrollIdsConverter))] +[DebuggerDisplay("{DebugDisplay,nq}")] +public sealed class ScrollIds : IUrlParameter, IEnumerable, IEquatable { - [JsonConverter(typeof(ScrollIdsConverter))] - [DebuggerDisplay("{DebugDisplay,nq}")] - public sealed class ScrollIds : IUrlParameter, IEnumerable, IEquatable - { - internal readonly IList Ids; + internal readonly IList Ids; - internal ScrollIds() => Ids = new List(); + internal ScrollIds() => Ids = new List(); - internal ScrollIds(IEnumerable dataStreamNames) => Ids = dataStreamNames.ToList(); + internal ScrollIds(IEnumerable dataStreamNames) => Ids = dataStreamNames.ToList(); - internal ScrollIds(IList dataStreamNames) => Ids = dataStreamNames; + internal ScrollIds(IList dataStreamNames) => Ids = dataStreamNames; - private string DebugDisplay => - $"Count: {Ids.Count} [" + string.Join(",", Ids.Select((t, i) => $"({i + 1}: {t?.DebugDisplay ?? "NULL"})")) + "]"; + private string DebugDisplay => + $"Count: {Ids.Count} [" + string.Join(",", Ids.Select((t, i) => $"({i + 1}: {t?.DebugDisplay ?? "NULL"})")) + "]"; - public override string ToString() => string.Join(",", Ids.Where(f => f is not null).Select(f => f.Id)); + public override string ToString() => string.Join(",", Ids.Where(f => f is not null).Select(f => f.Id)); - public static implicit operator ScrollIds(string[] scrollIds) => scrollIds.IsEmpty() ? null : new ScrollIds(scrollIds.Select(f => new ScrollId(f))); + public static implicit operator ScrollIds(string[] scrollIds) => scrollIds.IsEmpty() ? null : new ScrollIds(scrollIds.Select(f => new ScrollId(f))); - public static implicit operator ScrollIds(string scrollIds) => scrollIds.IsNullOrEmptyCommaSeparatedList(out var split) - ? null - : new ScrollIds(split.Select(f => new ScrollId(f))); + public static implicit operator ScrollIds(string scrollIds) => scrollIds.IsNullOrEmptyCommaSeparatedList(out var split) + ? null + : new ScrollIds(split.Select(f => new ScrollId(f))); - public static implicit operator ScrollIds(ScrollId scrollId) => scrollId == null ? null : new ScrollIds(new[] { scrollId }); + public static implicit operator ScrollIds(ScrollId scrollId) => scrollId == null ? null : new ScrollIds(new[] { scrollId }); - public static implicit operator ScrollIds(ScrollId[] scrollIds) => scrollIds.IsEmpty() ? null : new ScrollIds(scrollIds); + public static implicit operator ScrollIds(ScrollId[] scrollIds) => scrollIds.IsEmpty() ? null : new ScrollIds(scrollIds); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() => Ids.GetEnumerator(); + public IEnumerator GetEnumerator() => Ids.GetEnumerator(); - public static bool operator ==(ScrollIds left, ScrollIds right) => Equals(left, right); + public static bool operator ==(ScrollIds left, ScrollIds right) => Equals(left, right); - public static bool operator !=(ScrollIds left, ScrollIds right) => !Equals(left, right); + public static bool operator !=(ScrollIds left, ScrollIds right) => !Equals(left, right); - public override bool Equals(object obj) => - obj switch - { - ScrollIds f => Equals(f), - string s => Equals(s), - ScrollIds[] fns => Equals(fns), - _ => false, - }; + public override bool Equals(object obj) => + obj switch + { + ScrollIds f => Equals(f), + string s => Equals(s), + ScrollIds[] fns => Equals(fns), + _ => false, + }; - public bool Equals(ScrollIds other) => EqualsAllIds(Ids, other.Ids); + public bool Equals(ScrollIds other) => EqualsAllIds(Ids, other.Ids); - private static bool EqualsAllIds(IList thisTypes, IList otherTypes) - { - if (thisTypes is null && otherTypes is null) - return true; + private static bool EqualsAllIds(IList thisTypes, IList otherTypes) + { + if (thisTypes is null && otherTypes is null) + return true; - if (thisTypes is null || otherTypes is null) - return false; + if (thisTypes is null || otherTypes is null) + return false; - if (thisTypes.Count != otherTypes.Count) - return false; + if (thisTypes.Count != otherTypes.Count) + return false; - return !thisTypes.Except(otherTypes).Any(); - } + return !thisTypes.Except(otherTypes).Any(); + } - public override int GetHashCode() + public override int GetHashCode() + { + var hashCodes = new List(Ids.Count); + foreach (var item in Ids) { - var hashCodes = new List(Ids.Count); - foreach (var item in Ids) - { - hashCodes.Add(item.GetHashCode()); - } + hashCodes.Add(item.GetHashCode()); + } - hashCodes.Sort(); + hashCodes.Sort(); - unchecked + unchecked + { + var hash = 17; + foreach (var hashCode in hashCodes) { - var hash = 17; - foreach (var hashCode in hashCodes) - { - hash = hash * 23 + hashCode; - } - return typeof(ScrollId).GetHashCode() ^ hash; + hash = hash * 23 + hashCode; } + return typeof(ScrollId).GetHashCode() ^ hash; } - - string IUrlParameter.GetString(ITransportConfiguration? settings) => ToString(); } - internal sealed class ScrollIdsConverter : JsonConverter + string IUrlParameter.GetString(ITransportConfiguration? settings) => ToString(); +} + +internal sealed class ScrollIdsConverter : JsonConverter +{ + public override ScrollIds? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - public override ScrollIds? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.StartArray) - throw new JsonException($"Expected {JsonTokenType.StartArray} token but read '{reader.TokenType}' token for ScrollIds."); + if (reader.TokenType != JsonTokenType.StartArray) + throw new JsonException($"Expected {JsonTokenType.StartArray} token but read '{reader.TokenType}' token for ScrollIds."); - return JsonSerializer.Deserialize(ref reader, options); - } + return JsonSerializer.Deserialize(ref reader, options); + } - public override void Write(Utf8JsonWriter writer, ScrollIds value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, ScrollIds value, JsonSerializerOptions options) + { + if (value is null) { - if (value is null) - { - writer.WriteNullValue(); - return; - } - - JsonSerializer.Serialize(writer, value.Ids, options); + writer.WriteNullValue(); + return; } + + JsonSerializer.Serialize(writer, value.Ids, options); } } diff --git a/src/Elastic.Clients.Elasticsearch/CrossPlatform/NativeMethods.cs b/src/Elastic.Clients.Elasticsearch/CrossPlatform/NativeMethods.cs index ae2efc5268e..665237fc284 100644 --- a/src/Elastic.Clients.Elasticsearch/CrossPlatform/NativeMethods.cs +++ b/src/Elastic.Clients.Elasticsearch/CrossPlatform/NativeMethods.cs @@ -9,39 +9,38 @@ using System.Runtime.InteropServices; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal static class NativeMethods { - internal static class NativeMethods + public static class Windows { - public static class Windows + // This call avoids the shimming Windows does to report old versions + [DllImport("ntdll")] + private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation); + + internal static string RtlGetVersion() { - // This call avoids the shimming Windows does to report old versions - [DllImport("ntdll")] - private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation); - - internal static string RtlGetVersion() - { - var osvi = new RTL_OSVERSIONINFOEX(); - osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi); - if (RtlGetVersion(out osvi) == 0) - return $"Microsoft Windows {osvi.dwMajorVersion}.{osvi.dwMinorVersion}.{osvi.dwBuildNumber}"; - - return null; - } - - [StructLayout(LayoutKind.Sequential)] - // ReSharper disable once InconsistentNaming - internal struct RTL_OSVERSIONINFOEX - { - internal uint dwOSVersionInfoSize; - internal uint dwMajorVersion; - internal uint dwMinorVersion; - internal uint dwBuildNumber; - internal uint dwPlatformId; - - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] - internal string szCSDVersion; - } + var osvi = new RTL_OSVERSIONINFOEX(); + osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi); + if (RtlGetVersion(out osvi) == 0) + return $"Microsoft Windows {osvi.dwMajorVersion}.{osvi.dwMinorVersion}.{osvi.dwBuildNumber}"; + + return null; + } + + [StructLayout(LayoutKind.Sequential)] + // ReSharper disable once InconsistentNaming + internal struct RTL_OSVERSIONINFOEX + { + internal uint dwOSVersionInfoSize; + internal uint dwMajorVersion; + internal uint dwMinorVersion; + internal uint dwBuildNumber; + internal uint dwPlatformId; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + internal string szCSDVersion; } } } diff --git a/src/Elastic.Clients.Elasticsearch/CrossPlatform/NullableAttributes.cs b/src/Elastic.Clients.Elasticsearch/CrossPlatform/NullableAttributes.cs index 99e09498c04..8389e11206f 100644 --- a/src/Elastic.Clients.Elasticsearch/CrossPlatform/NullableAttributes.cs +++ b/src/Elastic.Clients.Elasticsearch/CrossPlatform/NullableAttributes.cs @@ -11,133 +11,132 @@ #pragma warning disable SA1649 // File name should match first type name #if !NETCOREAPP3_1_OR_GREATER && !NETSTANDARD2_1_OR_GREATER || NET461 -namespace System.Diagnostics.CodeAnalysis -{ - /// Specifies that null is allowed as an input even if the corresponding type disallows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +namespace System.Diagnostics.CodeAnalysis; + +/// Specifies that null is allowed as an input even if the corresponding type disallows it. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] #if INTERNAL_NULLABLE_ATTRIBUTES - internal +internal #else public #endif - sealed class AllowNullAttribute : Attribute - { } + sealed class AllowNullAttribute : Attribute +{ } - /// Specifies that null is disallowed as an input even if the corresponding type allows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +/// Specifies that null is disallowed as an input even if the corresponding type allows it. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] #if INTERNAL_NULLABLE_ATTRIBUTES - internal +internal #else public #endif - sealed class DisallowNullAttribute : Attribute - { } + sealed class DisallowNullAttribute : Attribute +{ } - /// Specifies that an output may be null even if the corresponding type disallows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +/// Specifies that an output may be null even if the corresponding type disallows it. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] #if INTERNAL_NULLABLE_ATTRIBUTES - internal +internal #else public #endif - sealed class MaybeNullAttribute : Attribute - { } + sealed class MaybeNullAttribute : Attribute +{ } - /// Specifies that an output will not be null even if the corresponding type allows it. - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +/// Specifies that an output will not be null even if the corresponding type allows it. +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] #if INTERNAL_NULLABLE_ATTRIBUTES - internal +internal #else public #endif - sealed class NotNullAttribute : Attribute - { } + sealed class NotNullAttribute : Attribute +{ } - /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. - [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +/// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. +[AttributeUsage(AttributeTargets.Parameter, Inherited = false)] #if INTERNAL_NULLABLE_ATTRIBUTES - internal +internal #else public #endif - sealed class MaybeNullWhenAttribute : Attribute - { - /// Initializes the attribute with the specified return value condition. - /// - /// The return value condition. If the method returns this value, the associated parameter may be null. - /// - public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - - /// Gets the return value condition. - public bool ReturnValue { get; } - } - - /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. - [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] + sealed class MaybeNullWhenAttribute : Attribute +{ + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter may be null. + /// + public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } +} + +/// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. +[AttributeUsage(AttributeTargets.Parameter, Inherited = false)] #if INTERNAL_NULLABLE_ATTRIBUTES - internal +internal #else public #endif - sealed class NotNullWhenAttribute : Attribute - { - /// Initializes the attribute with the specified return value condition. - /// - /// The return value condition. If the method returns this value, the associated parameter will not be null. - /// - public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - - /// Gets the return value condition. - public bool ReturnValue { get; } - } - - /// Specifies that the output will be non-null if the named parameter is non-null. - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] + sealed class NotNullWhenAttribute : Attribute +{ + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } +} + +/// Specifies that the output will be non-null if the named parameter is non-null. +[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] #if INTERNAL_NULLABLE_ATTRIBUTES - internal +internal #else public #endif - sealed class NotNullIfNotNullAttribute : Attribute - { - /// Initializes the attribute with the associated parameter name. - /// - /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. - /// - public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName; - - /// Gets the associated parameter name. - public string ParameterName { get; } - } - - /// Applied to a method that will never return under any circumstance. - [AttributeUsage(AttributeTargets.Method, Inherited = false)] + sealed class NotNullIfNotNullAttribute : Attribute +{ + /// Initializes the attribute with the associated parameter name. + /// + /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. + /// + public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName; + + /// Gets the associated parameter name. + public string ParameterName { get; } +} + +/// Applied to a method that will never return under any circumstance. +[AttributeUsage(AttributeTargets.Method, Inherited = false)] #if INTERNAL_NULLABLE_ATTRIBUTES - internal +internal #else public #endif - sealed class DoesNotReturnAttribute : Attribute - { } + sealed class DoesNotReturnAttribute : Attribute +{ } - /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. - [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +/// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. +[AttributeUsage(AttributeTargets.Parameter, Inherited = false)] #if INTERNAL_NULLABLE_ATTRIBUTES - internal +internal #else public #endif - sealed class DoesNotReturnIfAttribute : Attribute - { - /// Initializes the attribute with the specified parameter value. - /// - /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to - /// the associated parameter matches this value. - /// - public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; - - /// Gets the condition parameter value. - public bool ParameterValue { get; } - } + sealed class DoesNotReturnIfAttribute : Attribute +{ + /// Initializes the attribute with the specified parameter value. + /// + /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to + /// the associated parameter matches this value. + /// + public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; + + /// Gets the condition parameter value. + public bool ParameterValue { get; } } #endif diff --git a/src/Elastic.Clients.Elasticsearch/CrossPlatform/TypeExtensions.cs b/src/Elastic.Clients.Elasticsearch/CrossPlatform/TypeExtensions.cs index 1fd39f51e65..61cdbf2d2bc 100644 --- a/src/Elastic.Clients.Elasticsearch/CrossPlatform/TypeExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/CrossPlatform/TypeExtensions.cs @@ -6,26 +6,25 @@ using System.Collections.Generic; using System.Linq; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +internal static class DotNetCoreTypeExtensions { - internal static class DotNetCoreTypeExtensions + internal static bool TryGetGenericDictionaryArguments(this Type type, out Type[] genericArguments) { - internal static bool TryGetGenericDictionaryArguments(this Type type, out Type[] genericArguments) - { - var genericDictionary = type.GetInterfaces() - .FirstOrDefault(t => - t.IsGenericType && ( - t.GetGenericTypeDefinition() == typeof(IDictionary<,>) || - t.GetGenericTypeDefinition() == typeof(IReadOnlyDictionary<,>))); - - if (genericDictionary == null) - { - genericArguments = new Type[0]; - return false; - } + var genericDictionary = type.GetInterfaces() + .FirstOrDefault(t => + t.IsGenericType && ( + t.GetGenericTypeDefinition() == typeof(IDictionary<,>) || + t.GetGenericTypeDefinition() == typeof(IReadOnlyDictionary<,>))); - genericArguments = genericDictionary.GetGenericArguments(); - return true; + if (genericDictionary == null) + { + genericArguments = new Type[0]; + return false; } + + genericArguments = genericDictionary.GetGenericArguments(); + return true; } } diff --git a/src/Elastic.Clients.Elasticsearch/Experimental/AggregateDictionaryExtensions.cs b/src/Elastic.Clients.Elasticsearch/Experimental/AggregateDictionaryExtensions.cs index 4f302e9d53f..675f22f2572 100644 --- a/src/Elastic.Clients.Elasticsearch/Experimental/AggregateDictionaryExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Experimental/AggregateDictionaryExtensions.cs @@ -6,80 +6,79 @@ using System; using System.Linq; -namespace Elastic.Clients.Elasticsearch.Experimental +namespace Elastic.Clients.Elasticsearch.Experimental; + +internal static class AggregateDictionaryExtensions { - internal static class AggregateDictionaryExtensions + /// + /// WARNING: EXPERIMENTAL API + /// This API provides simplified access to terms aggregations. + /// + /// Experimental APIs are subject to changes or removal and should be used with caution. + public static TermsAggregate GetTerms(this AggregateDictionary aggregationDictionary, string key) => aggregationDictionary.GetTerms(key); + + /// + /// WARNING: EXPERIMENTAL API + /// This API provides simplified access to terms aggregations. + /// + /// Experimental APIs are subject to changes or removal and should be used with caution. + public static TermsAggregate GetTerms(this AggregateDictionary aggregationDictionary, string key) { - /// - /// WARNING: EXPERIMENTAL API - /// This API provides simplified access to terms aggregations. - /// - /// Experimental APIs are subject to changes or removal and should be used with caution. - public static TermsAggregate GetTerms(this AggregateDictionary aggregationDictionary, string key) => aggregationDictionary.GetTerms(key); + if (!aggregationDictionary.TryGetValue(key, out var agg)) + { + return null; + } - /// - /// WARNING: EXPERIMENTAL API - /// This API provides simplified access to terms aggregations. - /// - /// Experimental APIs are subject to changes or removal and should be used with caution. - public static TermsAggregate GetTerms(this AggregateDictionary aggregationDictionary, string key) + switch (agg) { - if (!aggregationDictionary.TryGetValue(key, out var agg)) - { - return null; - } + case StringTermsAggregate stringTerms: + var buckets = stringTerms.Buckets.Select(b => new TermsBucket(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.Key.ToString() }).ToReadOnlyCollection(); // ToString is a temp hack here + return new TermsAggregate + { + Buckets = buckets, + Meta = stringTerms.Meta, + DocCountErrorUpperBound = stringTerms.DocCountErrorUpperBound, + SumOtherDocCount = stringTerms.SumOtherDocCount + }; - switch (agg) - { - case StringTermsAggregate stringTerms: - var buckets = stringTerms.Buckets.Select(b => new TermsBucket(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.Key.ToString() }).ToReadOnlyCollection(); // ToString is a temp hack here - return new TermsAggregate - { - Buckets = buckets, - Meta = stringTerms.Meta, - DocCountErrorUpperBound = stringTerms.DocCountErrorUpperBound, - SumOtherDocCount = stringTerms.SumOtherDocCount - }; + case DoubleTermsAggregate doubleTerms: + var doubleTermsBuckets = doubleTerms.Buckets.Select(b => new TermsBucket(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection(); + return new TermsAggregate + { + Buckets = doubleTermsBuckets, + Meta = doubleTerms.Meta, + DocCountErrorUpperBound = doubleTerms.DocCountErrorUpperBound, + SumOtherDocCount = doubleTerms.SumOtherDocCount + }; - case DoubleTermsAggregate doubleTerms: - var doubleTermsBuckets = doubleTerms.Buckets.Select(b => new TermsBucket(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection(); - return new TermsAggregate - { - Buckets = doubleTermsBuckets, - Meta = doubleTerms.Meta, - DocCountErrorUpperBound = doubleTerms.DocCountErrorUpperBound, - SumOtherDocCount = doubleTerms.SumOtherDocCount - }; + case LongTermsAggregate longTerms: + var longTermsBuckets = longTerms.Buckets.Select(b => new TermsBucket(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection(); + return new TermsAggregate + { + Buckets = longTermsBuckets, + Meta = longTerms.Meta, + DocCountErrorUpperBound = longTerms.DocCountErrorUpperBound, + SumOtherDocCount = longTerms.SumOtherDocCount + }; - case LongTermsAggregate longTerms: - var longTermsBuckets = longTerms.Buckets.Select(b => new TermsBucket(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection(); - return new TermsAggregate - { - Buckets = longTermsBuckets, - Meta = longTerms.Meta, - DocCountErrorUpperBound = longTerms.DocCountErrorUpperBound, - SumOtherDocCount = longTerms.SumOtherDocCount - }; + // TODO - Multi-terms + } - // TODO - Multi-terms - } + return null; + } - return null; + private static TKey GetKeyFromBucketKey(object key) + { + if (typeof(TKey).IsEnum) + { + return (TKey)Enum.Parse(typeof(TKey), key.ToString(), true); } - private static TKey GetKeyFromBucketKey(object key) + if (key is FieldValue fieldValue) { - if (typeof(TKey).IsEnum) - { - return (TKey)Enum.Parse(typeof(TKey), key.ToString(), true); - } - - if (key is FieldValue fieldValue) - { - return (TKey)Convert.ChangeType(fieldValue.Value, typeof(TKey)); - } - - return (TKey)Convert.ChangeType(key, typeof(TKey)); + return (TKey)Convert.ChangeType(fieldValue.Value, typeof(TKey)); } + + return (TKey)Convert.ChangeType(key, typeof(TKey)); } } diff --git a/src/Elastic.Clients.Elasticsearch/FutureGenerated/FutureGenerated.cs b/src/Elastic.Clients.Elasticsearch/FutureGenerated/FutureGenerated.cs index ecb16fb5b1b..37fe247827f 100644 --- a/src/Elastic.Clients.Elasticsearch/FutureGenerated/FutureGenerated.cs +++ b/src/Elastic.Clients.Elasticsearch/FutureGenerated/FutureGenerated.cs @@ -5,16 +5,15 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch.QueryDsl +namespace Elastic.Clients.Elasticsearch.QueryDsl; + +// TODO - Generate these +public partial class TermQuery { - // TODO - Generate these - public partial class TermQuery - { - public static implicit operator QueryContainer(TermQuery termQuery) => QueryContainer.Term(termQuery); - } + public static implicit operator QueryContainer(TermQuery termQuery) => QueryContainer.Term(termQuery); +} - public partial class MatchAllQuery - { - public static implicit operator QueryContainer(MatchAllQuery matchAllQuery) => QueryContainer.MatchAll(matchAllQuery); - } +public partial class MatchAllQuery +{ + public static implicit operator QueryContainer(MatchAllQuery matchAllQuery) => QueryContainer.MatchAll(matchAllQuery); } diff --git a/src/Elastic.Clients.Elasticsearch/Helpers/IBulkAllRequest.cs b/src/Elastic.Clients.Elasticsearch/Helpers/IBulkAllRequest.cs index 702915eafd6..ee368951c8c 100644 --- a/src/Elastic.Clients.Elasticsearch/Helpers/IBulkAllRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Helpers/IBulkAllRequest.cs @@ -6,27 +6,26 @@ using System.Collections.Generic; using Elastic.Clients.Elasticsearch.Core.Bulk; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public interface IBulkAllRequest { - public interface IBulkAllRequest - { - int? BackOffRetries { get; } - Duration? BackOffTime { get; } - ProducerConsumerBackPressure? BackPressure { get; } - Action>? BufferToBulk { get; } - Action? BulkResponseCallback { get; } - bool ContinueAfterDroppedDocuments { get; } - IEnumerable Documents { get; } - Action? DroppedDocumentCallback { get; } - IndexName Index { get; } - int? MaxDegreeOfParallelism { get; } - string? Pipeline { get; } - Indices? RefreshIndices { get; } - bool RefreshOnCompleted { get; } - Func? RetryDocumentPredicate { get; } - Routing? Routing { get; } - int? Size { get; } - Duration? Timeout { get; } - WaitForActiveShards? WaitForActiveShards { get; } - } + int? BackOffRetries { get; } + Duration? BackOffTime { get; } + ProducerConsumerBackPressure? BackPressure { get; } + Action>? BufferToBulk { get; } + Action? BulkResponseCallback { get; } + bool ContinueAfterDroppedDocuments { get; } + IEnumerable Documents { get; } + Action? DroppedDocumentCallback { get; } + IndexName Index { get; } + int? MaxDegreeOfParallelism { get; } + string? Pipeline { get; } + Indices? RefreshIndices { get; } + bool RefreshOnCompleted { get; } + Func? RetryDocumentPredicate { get; } + Routing? Routing { get; } + int? Size { get; } + Duration? Timeout { get; } + WaitForActiveShards? WaitForActiveShards { get; } } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionary.cs b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionary.cs index eeddd8cf2ff..196cea2878b 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionary.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionary.cs @@ -2,11 +2,10 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch.Aggregations +namespace Elastic.Clients.Elasticsearch.Aggregations; + +public partial class AggregateDictionary { - public partial class AggregateDictionary - { - /// - public AvgAggregate? GetAverage(string key) => TryGet(key); - } + /// + public AvgAggregate? GetAverage(string key) => TryGet(key); } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregationContainer.cs b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregationContainer.cs index ef213b194ac..42c26fa23ef 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregationContainer.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregationContainer.cs @@ -5,32 +5,31 @@ using System; using System.Text.Json; -namespace Elastic.Clients.Elasticsearch.Aggregations +namespace Elastic.Clients.Elasticsearch.Aggregations; + +public partial class AggregationContainer { - public partial class AggregationContainer - { - internal string ContainedVariantName { get; set; } + internal string ContainedVariantName { get; set; } - internal Action SerializeFluent { get; private set; } + internal Action SerializeFluent { get; private set; } - private AggregationContainer(string variant) => ContainedVariantName = variant; + private AggregationContainer(string variant) => ContainedVariantName = variant; - internal static AggregationContainer CreateWithAction(string variantName, Action configure) where T : new() - { - var container = new AggregationContainer(variantName); - container.SetAction(configure); - return container; - } + internal static AggregationContainer CreateWithAction(string variantName, Action configure) where T : new() + { + var container = new AggregationContainer(variantName); + container.SetAction(configure); + return container; + } - private void SetAction(Action configure) where T : new() - => SerializeFluent = (writer, options) => - { - var descriptor = new T(); - configure(descriptor); - JsonSerializer.Serialize(writer, descriptor, options); - }; + private void SetAction(Action configure) where T : new() + => SerializeFluent = (writer, options) => + { + var descriptor = new T(); + configure(descriptor); + JsonSerializer.Serialize(writer, descriptor, options); + }; - public static implicit operator AggregationContainer(Aggregation aggregator) => - aggregator == null ? null : new AggregationContainer(aggregator); - } + public static implicit operator AggregationContainer(Aggregation aggregator) => + aggregator == null ? null : new AggregationContainer(aggregator); } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/TermsAggregate.cs b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/TermsAggregate.cs index 72639e77612..9af30af4904 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/TermsAggregate.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/TermsAggregate.cs @@ -5,24 +5,23 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch.Aggregations +namespace Elastic.Clients.Elasticsearch.Aggregations; + +public sealed class TermsAggregate : IAggregate { - public sealed class TermsAggregate : IAggregate - { - [JsonInclude] - [JsonPropertyName("doc_count_error_upper_bound")] - public long? DocCountErrorUpperBound { get; init; } + [JsonInclude] + [JsonPropertyName("doc_count_error_upper_bound")] + public long? DocCountErrorUpperBound { get; init; } - [JsonInclude] - [JsonPropertyName("sum_other_doc_count")] - public long? SumOtherDocCount { get; init; } + [JsonInclude] + [JsonPropertyName("sum_other_doc_count")] + public long? SumOtherDocCount { get; init; } - [JsonInclude] - [JsonPropertyName("buckets")] - public IReadOnlyCollection> Buckets { get; init; } + [JsonInclude] + [JsonPropertyName("buckets")] + public IReadOnlyCollection> Buckets { get; init; } - [JsonInclude] - [JsonPropertyName("meta")] - public Dictionary? Meta { get; init; } - } + [JsonInclude] + [JsonPropertyName("meta")] + public Dictionary? Meta { get; init; } } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Documents/MultiSearch/SearchRequestItem.cs b/src/Elastic.Clients.Elasticsearch/Types/Documents/MultiSearch/SearchRequestItem.cs index e6d7d0dd032..deed0df974b 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Documents/MultiSearch/SearchRequestItem.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Documents/MultiSearch/SearchRequestItem.cs @@ -8,48 +8,47 @@ using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch.Core.MSearch +namespace Elastic.Clients.Elasticsearch.Core.MSearch; + +// POC - If we have more than one union doing this, can we autogenerate with correct ctors etc. +public class SearchRequestItem : IStreamSerializable { - // POC - If we have more than one union doing this, can we autogenerate with correct ctors etc. - public class SearchRequestItem : IStreamSerializable + public SearchRequestItem(MultisearchBody body) => Body = body; + + public SearchRequestItem(MultisearchHeader header, MultisearchBody body) { - public SearchRequestItem(MultisearchBody body) => Body = body; + Header = header; + Body = body; + } - public SearchRequestItem(MultisearchHeader header, MultisearchBody body) - { - Header = header; - Body = body; - } + public MultisearchHeader Header { get; init; } + public MultisearchBody Body { get; init; } - public MultisearchHeader Header { get; init; } - public MultisearchBody Body { get; init; } + void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting) + { + if (Body is null) + return; - void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting) + if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options)) { - if (Body is null) - return; - - if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options)) - { - JsonSerializer.Serialize(stream, Header, options); - stream.WriteByte((byte)'\n'); - JsonSerializer.Serialize(stream, Body, options); - stream.WriteByte((byte)'\n'); - } + JsonSerializer.Serialize(stream, Header, options); + stream.WriteByte((byte)'\n'); + JsonSerializer.Serialize(stream, Body, options); + stream.WriteByte((byte)'\n'); } + } + + async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting) + { + if (Body is null) + return; - async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting) + if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options)) { - if (Body is null) - return; - - if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options)) - { - await JsonSerializer.SerializeAsync(stream, Header, options).ConfigureAwait(false); - stream.WriteByte((byte)'\n'); - await JsonSerializer.SerializeAsync(stream, Body, options).ConfigureAwait(false); - stream.WriteByte((byte)'\n'); - } + await JsonSerializer.SerializeAsync(stream, Header, options).ConfigureAwait(false); + stream.WriteByte((byte)'\n'); + await JsonSerializer.SerializeAsync(stream, Body, options).ConfigureAwait(false); + stream.WriteByte((byte)'\n'); } } } diff --git a/src/Elastic.Clients.Elasticsearch/Types/OpType.cs b/src/Elastic.Clients.Elasticsearch/Types/OpType.cs index 1eca30f512f..84ca5084548 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/OpType.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/OpType.cs @@ -4,19 +4,18 @@ using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public partial struct OpType : IStringable { - public partial struct OpType : IStringable - { - public static OpType Index = new("index"); - public static OpType Create = new("create"); + public static OpType Index = new("index"); + public static OpType Create = new("create"); - public OpType(string value) => Value = value; + public OpType(string value) => Value = value; - public string Value { get; } + public string Value { get; } - public static implicit operator OpType(string v) => new(v); + public static implicit operator OpType(string v) => new(v); - public string GetString() => Value ?? string.Empty; - } + public string GetString() => Value ?? string.Empty; } diff --git a/src/Elastic.Clients.Elasticsearch/Types/PointInTimeReferenceDescriptor.cs b/src/Elastic.Clients.Elasticsearch/Types/PointInTimeReferenceDescriptor.cs index f711badc726..0370f78f5b8 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/PointInTimeReferenceDescriptor.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/PointInTimeReferenceDescriptor.cs @@ -2,10 +2,9 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -namespace Elastic.Clients.Elasticsearch.Core.Search +namespace Elastic.Clients.Elasticsearch.Core.Search; + +public sealed partial class PointInTimeReferenceDescriptor { - public sealed partial class PointInTimeReferenceDescriptor - { - public PointInTimeReferenceDescriptor(string id) => IdValue = id; - } + public PointInTimeReferenceDescriptor(string id) => IdValue = id; } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Ranges.cs b/src/Elastic.Clients.Elasticsearch/Types/Ranges.cs index 512370fcd68..a146f6ecde2 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Ranges.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Ranges.cs @@ -5,95 +5,94 @@ using System; using System.Runtime.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public class DateRange { - public class DateRange - { - [DataMember(Name = "gt")] - public DateTimeOffset? GreaterThan { get; set; } + [DataMember(Name = "gt")] + public DateTimeOffset? GreaterThan { get; set; } - [DataMember(Name = "gte")] - public DateTimeOffset? GreaterThanOrEqualTo { get; set; } + [DataMember(Name = "gte")] + public DateTimeOffset? GreaterThanOrEqualTo { get; set; } - [DataMember(Name = "lt")] - public DateTimeOffset? LessThan { get; set; } + [DataMember(Name = "lt")] + public DateTimeOffset? LessThan { get; set; } - [DataMember(Name = "lte")] - public DateTimeOffset? LessThanOrEqualTo { get; set; } - } + [DataMember(Name = "lte")] + public DateTimeOffset? LessThanOrEqualTo { get; set; } +} - public class DoubleRange - { - [DataMember(Name = "gt")] - public double? GreaterThan { get; set; } +public class DoubleRange +{ + [DataMember(Name = "gt")] + public double? GreaterThan { get; set; } - [DataMember(Name = "gte")] - public double? GreaterThanOrEqualTo { get; set; } + [DataMember(Name = "gte")] + public double? GreaterThanOrEqualTo { get; set; } - [DataMember(Name = "lt")] - public double? LessThan { get; set; } + [DataMember(Name = "lt")] + public double? LessThan { get; set; } - [DataMember(Name = "lte")] - public double? LessThanOrEqualTo { get; set; } - } + [DataMember(Name = "lte")] + public double? LessThanOrEqualTo { get; set; } +} - public class FloatRange - { - [DataMember(Name = "gt")] - public float? GreaterThan { get; set; } +public class FloatRange +{ + [DataMember(Name = "gt")] + public float? GreaterThan { get; set; } - [DataMember(Name = "gte")] - public float? GreaterThanOrEqualTo { get; set; } + [DataMember(Name = "gte")] + public float? GreaterThanOrEqualTo { get; set; } - [DataMember(Name = "lt")] - public float? LessThan { get; set; } + [DataMember(Name = "lt")] + public float? LessThan { get; set; } - [DataMember(Name = "lte")] - public float? LessThanOrEqualTo { get; set; } - } + [DataMember(Name = "lte")] + public float? LessThanOrEqualTo { get; set; } +} - public class IntegerRange - { - [DataMember(Name = "gt")] - public int? GreaterThan { get; set; } +public class IntegerRange +{ + [DataMember(Name = "gt")] + public int? GreaterThan { get; set; } - [DataMember(Name = "gte")] - public int? GreaterThanOrEqualTo { get; set; } + [DataMember(Name = "gte")] + public int? GreaterThanOrEqualTo { get; set; } - [DataMember(Name = "lt")] - public int? LessThan { get; set; } + [DataMember(Name = "lt")] + public int? LessThan { get; set; } - [DataMember(Name = "lte")] - public int? LessThanOrEqualTo { get; set; } - } + [DataMember(Name = "lte")] + public int? LessThanOrEqualTo { get; set; } +} - public class LongRange - { - [DataMember(Name = "gt")] - public long? GreaterThan { get; set; } +public class LongRange +{ + [DataMember(Name = "gt")] + public long? GreaterThan { get; set; } - [DataMember(Name = "gte")] - public long? GreaterThanOrEqualTo { get; set; } + [DataMember(Name = "gte")] + public long? GreaterThanOrEqualTo { get; set; } - [DataMember(Name = "lt")] - public long? LessThan { get; set; } + [DataMember(Name = "lt")] + public long? LessThan { get; set; } - [DataMember(Name = "lte")] - public long? LessThanOrEqualTo { get; set; } - } + [DataMember(Name = "lte")] + public long? LessThanOrEqualTo { get; set; } +} - public class IpAddressRange - { - [DataMember(Name = "gt")] - public string GreaterThan { get; set; } +public class IpAddressRange +{ + [DataMember(Name = "gt")] + public string GreaterThan { get; set; } - [DataMember(Name = "gte")] - public string GreaterThanOrEqualTo { get; set; } + [DataMember(Name = "gte")] + public string GreaterThanOrEqualTo { get; set; } - [DataMember(Name = "lt")] - public string LessThan { get; set; } + [DataMember(Name = "lt")] + public string LessThan { get; set; } - [DataMember(Name = "lte")] - public string LessThanOrEqualTo { get; set; } - } + [DataMember(Name = "lte")] + public string LessThanOrEqualTo { get; set; } } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Refresh.cs b/src/Elastic.Clients.Elasticsearch/Types/Refresh.cs index d810b75ff70..c4f41a86102 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Refresh.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Refresh.cs @@ -4,18 +4,17 @@ using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public partial struct Refresh : IStringable { - public partial struct Refresh : IStringable - { - public static Refresh WaitFor = new("wait_for"); - public static Refresh True = new("true"); - public static Refresh False = new("false"); + public static Refresh WaitFor = new("wait_for"); + public static Refresh True = new("true"); + public static Refresh False = new("false"); - public Refresh(string value) => Value = value; + public Refresh(string value) => Value = value; - public string Value { get; } + public string Value { get; } - public string GetString() => Value ?? string.Empty; - } + public string GetString() => Value ?? string.Empty; } diff --git a/src/Elastic.Clients.Elasticsearch/Types/SourceConfig.cs b/src/Elastic.Clients.Elasticsearch/Types/SourceConfig.cs index d041d9ef321..99112976e9e 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/SourceConfig.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/SourceConfig.cs @@ -7,59 +7,58 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch.Core.Search +namespace Elastic.Clients.Elasticsearch.Core.Search; + +[JsonConverter(typeof(SourceConfigConverter))] +public partial class SourceConfig { - [JsonConverter(typeof(SourceConfigConverter))] - public partial class SourceConfig - { - public bool HasBoolValue => Tag == 0; + public bool HasBoolValue => Tag == 0; - public bool HasSourceFilterValue => Tag == 1; + public bool HasSourceFilterValue => Tag == 1; - public bool TryGetBool([NotNullWhen(returnValue: true)] out bool? value) + public bool TryGetBool([NotNullWhen(returnValue: true)] out bool? value) + { + if (Tag == 0) { - if (Tag == 0) - { - value = Item1; - return true; - } - - value = null; - return false; + value = Item1; + return true; } - public bool TryGetSourceFilter([NotNullWhen(returnValue: true)] out SourceFilter? value) - { - if (Tag == 1) - { - value = Item2; - return true; - } + value = null; + return false; + } - value = null; - return false; + public bool TryGetSourceFilter([NotNullWhen(returnValue: true)] out SourceFilter? value) + { + if (Tag == 1) + { + value = Item2; + return true; } + + value = null; + return false; } +} - internal class SourceConfigConverter : JsonConverter +internal class SourceConfigConverter : JsonConverter +{ + public override SourceConfig? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - public override SourceConfig? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + switch (reader.TokenType) { - switch (reader.TokenType) - { - case JsonTokenType.True: - case JsonTokenType.False: - var value = reader.GetBoolean(); - return new SourceConfig(value); - - case JsonTokenType.StartObject: - var sourceFilter = JsonSerializer.Deserialize(ref reader, options); - return new SourceConfig(sourceFilter); - } + case JsonTokenType.True: + case JsonTokenType.False: + var value = reader.GetBoolean(); + return new SourceConfig(value); - return null; + case JsonTokenType.StartObject: + var sourceFilter = JsonSerializer.Deserialize(ref reader, options); + return new SourceConfig(sourceFilter); } - public override void Write(Utf8JsonWriter writer, SourceConfig value, JsonSerializerOptions options) => throw new NotImplementedException(); + return null; } + + public override void Write(Utf8JsonWriter writer, SourceConfig value, JsonSerializerOptions options) => throw new NotImplementedException(); } diff --git a/src/Elastic.Clients.Elasticsearch/Types/StoredScriptId.cs b/src/Elastic.Clients.Elasticsearch/Types/StoredScriptId.cs index 1ac4fb13e03..22bf2195455 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/StoredScriptId.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/StoredScriptId.cs @@ -7,79 +7,78 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +[JsonConverter(typeof(StoredScriptIdConveter))] +public partial class StoredScriptId { - [JsonConverter(typeof(StoredScriptIdConveter))] - public partial class StoredScriptId - { - public StoredScriptId(string id) => Id = id; - public StoredScriptId(Id id) => Id = id; - } + public StoredScriptId(string id) => Id = id; + public StoredScriptId(Id id) => Id = id; +} - internal sealed class StoredScriptIdConveter : JsonConverter +internal sealed class StoredScriptIdConveter : JsonConverter +{ + public override StoredScriptId? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - public override StoredScriptId? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - StoredScriptId? storedScriptId = null; + StoredScriptId? storedScriptId = null; - Dictionary? parameters = null; - while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) + Dictionary? parameters = null; + while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) + { + if (reader.TokenType == JsonTokenType.PropertyName) { - if (reader.TokenType == JsonTokenType.PropertyName) + if (reader.ValueTextEquals("id")) { - if (reader.ValueTextEquals("id")) + reader.Read(); + var value = JsonSerializer.Deserialize(ref reader, options); + if (value is not null) { - reader.Read(); - var value = JsonSerializer.Deserialize(ref reader, options); - if (value is not null) - { - storedScriptId = new StoredScriptId(value); - } - - continue; + storedScriptId = new StoredScriptId(value); } - if (reader.ValueTextEquals("params")) - { - reader.Read(); - var value = JsonSerializer.Deserialize>(ref reader, options); - if (value is not null) - { - parameters = value; - } + continue; + } - continue; + if (reader.ValueTextEquals("params")) + { + reader.Read(); + var value = JsonSerializer.Deserialize>(ref reader, options); + if (value is not null) + { + parameters = value; } - } - } - if (storedScriptId is not null) - { - storedScriptId.Params = null; + continue; + } } - - return storedScriptId; } - public override void Write(Utf8JsonWriter writer, StoredScriptId value, JsonSerializerOptions options) + if (storedScriptId is not null) { - if (value is null) - { - writer.WriteNullValue(); - return; - } + storedScriptId.Params = null; + } - writer.WriteStartObject(); - writer.WritePropertyName("id"); - JsonSerializer.Serialize(writer, value.Id, options); + return storedScriptId; + } - if (value.Params is not null) - { - writer.WritePropertyName("params"); - JsonSerializer.Serialize(writer, value.Params, options); - } + public override void Write(Utf8JsonWriter writer, StoredScriptId value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } - writer.WriteEndObject(); + writer.WriteStartObject(); + writer.WritePropertyName("id"); + JsonSerializer.Serialize(writer, value.Id, options); + + if (value.Params is not null) + { + writer.WritePropertyName("params"); + JsonSerializer.Serialize(writer, value.Params, options); } + + writer.WriteEndObject(); } } diff --git a/src/Elastic.Clients.Elasticsearch/Types/WaitForActiveShards.cs b/src/Elastic.Clients.Elasticsearch/Types/WaitForActiveShards.cs index fe1ba1246a3..e033e7af327 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/WaitForActiveShards.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/WaitForActiveShards.cs @@ -4,19 +4,18 @@ using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public partial struct WaitForActiveShards : IStringable { - public partial struct WaitForActiveShards : IStringable - { - public static WaitForActiveShards All = new("all"); + public static WaitForActiveShards All = new("all"); - public WaitForActiveShards(string value) => Value = value; + public WaitForActiveShards(string value) => Value = value; - public string Value { get; } + public string Value { get; } - public static implicit operator WaitForActiveShards(int v) => new(v.ToString()); - public static implicit operator WaitForActiveShards(string v) => new(v); + public static implicit operator WaitForActiveShards(int v) => new(v.ToString()); + public static implicit operator WaitForActiveShards(string v) => new(v); - public string GetString() => Value ?? string.Empty; - } + public string GetString() => Value ?? string.Empty; }