-
Notifications
You must be signed in to change notification settings - Fork 249
CSHARP-994 Add AsyncEnumerable support to RowSet #617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 4 commits
6408af6
372167b
675c1f5
066009d
6a7ac17
c54d0fe
c1d1e46
bb77743
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -606,12 +606,12 @@ public void Bound_Manual_Paging() | |
| Assert.False(rs.AutoPage); | ||
| Assert.NotNull(rs.PagingState); | ||
| //Dequeue all via Linq | ||
| var ids = rs.Select(r => r.GetValue<Guid>("id")).ToList(); | ||
| var ids = Enumerable.Select(rs, r => r.GetValue<Guid>("id")).ToList(); | ||
| Assert.AreEqual(pageSize, ids.Count); | ||
| //Retrieve the next page | ||
| var rs2 = Session.Execute(ps.Bind().SetAutoPage(false).SetPagingState(rs.PagingState)); | ||
| Assert.Null(rs2.PagingState); | ||
| var ids2 = rs2.Select(r => r.GetValue<Guid>("id")).ToList(); | ||
| var ids2 = Enumerable.Select(rs2, r => r.GetValue<Guid>("id")).ToList(); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RowSet now implements both IEnumerable and IAsyncEnumerable which both have a select method. I double checked if it was an issue with my AsyncEnumerable implementation but if you create a new .NET 10 project (that has AsyncEnumerable built-in) and have a class that implements both interface, you'll have this error too.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But the driver project only targets netstandard 2.1 so it will never have the built in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Correct, but I provided my own implementation of AsyncEnumerable. It's internal but internals are visible to the test assemblies.
Yes this could be an issue.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The custom AsyncEnumerable implementation is internal, how would it affect applications installing it?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
But the test assemblies don't target net10 currently so it shouldn't be an issue now right?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It will indeed not impact projects referencing Cassandra because it's internal. It will impact Cassandra + test projects because they all have access to the this internal class. |
||
| Assert.AreEqual(totalRowLength - pageSize, ids2.Count); | ||
| Assert.AreEqual(totalRowLength, ids.Union(ids2).Count()); | ||
| } | ||
|
|
@@ -1047,10 +1047,11 @@ public void Batch_PreparedStatement_With_Unprepared_Flow() | |
| session.Execute(new BatchStatement() | ||
| .Add(ps1.Bind(3, "label3_u")) | ||
| .Add(ps2.Bind("label4_u", 4))); | ||
| var result = session.Execute("SELECT id, label FROM tbl_unprepared_flow") | ||
| .Select(r => new object[] { r.GetValue<int>(0), r.GetValue<string>(1) }) | ||
| .OrderBy(arr => (int)arr[0]) | ||
| .ToArray(); | ||
| var result = Enumerable.Select( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| session.Execute("SELECT id, label FROM tbl_unprepared_flow"), | ||
| r => new object[] { r.GetValue<int>(0), r.GetValue<string>(1) }) | ||
| .OrderBy(arr => (int)arr[0]) | ||
| .ToArray(); | ||
| Assert.AreEqual(Enumerable.Range(1, 4).Select(i => new object[] { i, $"label{i}_u" }), result); | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -128,7 +128,7 @@ public void RandomValuesTest() | |
|
|
||
| var selectQuery = $"SELECT id, timeuuid_sample, {GetToDateFunction()}(timeuuid_sample) FROM {AllTypesTableName} LIMIT 10000"; | ||
| Assert.DoesNotThrow(() => | ||
| Session.Execute(selectQuery).Select(r => r.GetValue<TimeUuid>("timeuuid_sample")).ToArray()); | ||
| Enumerable.Select(Session.Execute(selectQuery), r => r.GetValue<TimeUuid>("timeuuid_sample")).ToArray()); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
|
||
| [Test] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,7 +54,7 @@ internal override IEnumerable<TResult> AdaptResult(string cql, RowSet rs) | |
| if (!_canCompile) | ||
| { | ||
| var mapper = MapperFactory.GetMapperWithProjection<TResult>(cql, rs, _projectionExpression); | ||
| result = rs.Select(mapper); | ||
| result = Enumerable.Select(rs, mapper); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I won't comment more on this to avoid spamming the same comment
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
| else | ||
| { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| // Copyright (C) DataStax Inc. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| #if NETSTANDARD2_1_OR_GREATER && !NET10_OR_GREATER // These methods are implemented in .NET 10. | ||
verdie-g marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| using System.Collections.Generic; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
|
|
||
| // ReSharper disable once CheckNamespace | ||
| namespace System.Linq | ||
| { | ||
| internal static class AsyncEnumerable | ||
| { | ||
| public static async ValueTask<TSource> FirstAsync<TSource>( | ||
| this IAsyncEnumerable<TSource> source, | ||
| CancellationToken cancellationToken = default) | ||
| { | ||
| await using var e = source.GetAsyncEnumerator(cancellationToken); | ||
|
|
||
| if (!await e.MoveNextAsync()) | ||
| { | ||
| throw new InvalidOperationException("Sequence contains no elements"); | ||
| } | ||
|
|
||
| return e.Current; | ||
| } | ||
|
|
||
| public static async ValueTask<TSource> FirstOrDefaultAsync<TSource>( | ||
| this IAsyncEnumerable<TSource> source, | ||
| CancellationToken cancellationToken = default) | ||
| { | ||
| await using var e = source.GetAsyncEnumerator(cancellationToken); | ||
| return await e.MoveNextAsync() ? e.Current : default; | ||
| } | ||
|
|
||
| public static async ValueTask<TSource> SingleAsync<TSource>( | ||
| this IAsyncEnumerable<TSource> source, | ||
| CancellationToken cancellationToken = default) | ||
| { | ||
| await using var e = source.GetAsyncEnumerator(cancellationToken); | ||
|
|
||
| if (!await e.MoveNextAsync()) | ||
| { | ||
| throw new InvalidOperationException("Sequence contains no elements"); | ||
| } | ||
|
|
||
| TSource result = e.Current; | ||
| if (await e.MoveNextAsync()) | ||
| { | ||
| throw new InvalidOperationException("Sequence contains more than one element"); | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| public static async ValueTask<TSource> SingleOrDefaultAsync<TSource>( | ||
| this IAsyncEnumerable<TSource> source, | ||
| CancellationToken cancellationToken = default) | ||
| { | ||
| await using var e = source.GetAsyncEnumerator(cancellationToken); | ||
|
|
||
| if (!await e.MoveNextAsync()) | ||
| { | ||
| return default; | ||
| } | ||
|
|
||
| TSource result = e.Current; | ||
| if (await e.MoveNextAsync()) | ||
| { | ||
| throw new InvalidOperationException("Sequence contains more than one element"); | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| public static async IAsyncEnumerable<TResult> Select<TSource, TResult>( | ||
| this IAsyncEnumerable<TSource> source, | ||
| Func<TSource, TResult> selector) | ||
| { | ||
| await foreach (TSource element in source) | ||
| { | ||
| yield return selector(element); | ||
| } | ||
| } | ||
|
|
||
| public static async ValueTask<List<TSource>> ToListAsync<TSource>( | ||
| this IAsyncEnumerable<TSource> source, | ||
| CancellationToken cancellationToken = default) | ||
| { | ||
| var list = new List<TSource>(); | ||
| await foreach (TSource element in source.WithCancellation(cancellationToken)) | ||
| { | ||
| list.Add(element); | ||
| } | ||
|
|
||
| return list; | ||
| } | ||
| } | ||
| } | ||
| #endif | ||
Uh oh!
There was an error while loading. Please reload this page.