Skip to content

Commit 47a3cff

Browse files
committed
[DEVEX-222] Added delete method with options
1 parent 6af77db commit 47a3cff

File tree

4 files changed

+105
-28
lines changed

4 files changed

+105
-28
lines changed

Diff for: src/KurrentDB.Client/Core/OperationOptions.cs

+10
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,14 @@ public class OperationOptions {
1515
/// </summary>
1616
public UserCredentials? UserCredentials { get; set; }
1717

18+
/// <summary>
19+
/// Clones a copy of the current <see cref="KurrentDBClientOperationOptions"/>.
20+
/// </summary>
21+
/// <returns></returns>
22+
public OperationOptions With(KurrentDBClientSettings clientSettings) {
23+
Deadline ??= clientSettings.DefaultDeadline;
24+
UserCredentials ??= clientSettings.DefaultCredentials;
25+
26+
return this;
27+
}
1828
}

Diff for: src/KurrentDB.Client/Streams/KurrentDBClient.Append.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -508,8 +508,9 @@ public class AppendToStreamOptions : OperationOptions {
508508
/// <returns></returns>
509509
public void With(KurrentDBClientOperationOptions clientOperationOptions) {
510510
ThrowOnAppendFailure ??= clientOperationOptions.ThrowOnAppendFailure;
511-
512511
BatchAppendSize ??= clientOperationOptions.BatchAppendSize;
512+
513+
return this;
513514
}
514515

515516
/// <summary>

Diff for: src/KurrentDB.Client/Streams/KurrentDBClient.Delete.cs

+61-16
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,78 @@ public partial class KurrentDBClient {
88
/// </summary>
99
/// <param name="streamName">The name of the stream to delete.</param>
1010
/// <param name="expectedState">The expected <see cref="StreamState"/> of the stream being deleted.</param>
11-
/// <param name="deadline">The maximum time to wait before terminating the call.</param>
12-
/// <param name="userCredentials">The optional <see cref="UserCredentials"/> to perform operation with.</param>
11+
/// <param name="options">Optional settings for the delete operation, e.g. deadline, user credentials etc.</param>
1312
/// <param name="cancellationToken">The optional <see cref="System.Threading.CancellationToken"/>.</param>
1413
/// <returns></returns>
1514
public Task<DeleteResult> DeleteAsync(
1615
string streamName,
1716
StreamState expectedState,
18-
TimeSpan? deadline = null,
19-
UserCredentials? userCredentials = null,
20-
CancellationToken cancellationToken = default) => DeleteInternal(new DeleteReq {
21-
Options = new DeleteReq.Types.Options {
22-
StreamIdentifier = streamName
23-
}
24-
}.WithAnyStreamRevision(expectedState), deadline, userCredentials, cancellationToken);
17+
DeleteOptions? options = null,
18+
CancellationToken cancellationToken = default
19+
) =>
20+
DeleteInternal(
21+
new DeleteReq {
22+
Options = new DeleteReq.Types.Options {
23+
StreamIdentifier = streamName
24+
}
25+
}.WithAnyStreamRevision(expectedState),
26+
options,
27+
cancellationToken
28+
);
2529

26-
private async Task<DeleteResult> DeleteInternal(DeleteReq request,
27-
TimeSpan? deadline,
28-
UserCredentials? userCredentials,
29-
CancellationToken cancellationToken) {
30+
async Task<DeleteResult> DeleteInternal(
31+
DeleteReq request,
32+
DeleteOptions? options,
33+
CancellationToken cancellationToken
34+
) {
3035
_log.LogDebug("Deleting stream {streamName}.", request.Options.StreamIdentifier);
3136
var channelInfo = await GetChannelInfo(cancellationToken).ConfigureAwait(false);
32-
using var call = new EventStore.Client.Streams.Streams.StreamsClient(
33-
channelInfo.CallInvoker).DeleteAsync(request,
34-
KurrentDBCallOptions.CreateNonStreaming(Settings, deadline, userCredentials, cancellationToken));
37+
using var call = new Streams.StreamsClient(channelInfo.CallInvoker).DeleteAsync(
38+
request,
39+
KurrentDBCallOptions.CreateNonStreaming(
40+
Settings,
41+
options?.Deadline,
42+
options?.UserCredentials,
43+
cancellationToken
44+
)
45+
);
46+
3547
var result = await call.ResponseAsync.ConfigureAwait(false);
3648

3749
return new DeleteResult(new Position(result.Position.CommitPosition, result.Position.PreparePosition));
3850
}
3951
}
52+
53+
public class DeleteOptions : OperationOptions;
54+
55+
public static class KurrentDBClientObsoleteDeleteExtensions {
56+
/// <summary>
57+
/// Deletes a stream asynchronously.
58+
/// </summary>
59+
/// <param name="dbClient"></param>
60+
/// <param name="streamName">The name of the stream to delete.</param>
61+
/// <param name="expectedState">The expected <see cref="StreamState"/> of the stream being deleted.</param>
62+
/// <param name="deadline">The maximum time to wait before terminating the call.</param>
63+
/// <param name="userCredentials">The optional <see cref="UserCredentials"/> to perform operation with.</param>
64+
/// <param name="cancellationToken">The optional <see cref="System.Threading.CancellationToken"/>.</param>
65+
/// <returns></returns>
66+
[Obsolete(
67+
"This method may be removed in future releases. Use the overload with DeleteOptions parameter",
68+
false
69+
)]
70+
public static Task<DeleteResult> DeleteAsync(
71+
this KurrentDBClient dbClient,
72+
string streamName,
73+
StreamState expectedState,
74+
TimeSpan? deadline = null,
75+
UserCredentials? userCredentials = null,
76+
CancellationToken cancellationToken = default
77+
) =>
78+
dbClient.DeleteAsync(
79+
streamName,
80+
expectedState,
81+
new DeleteOptions{ Deadline = deadline, UserCredentials = userCredentials },
82+
cancellationToken
83+
);
84+
}
4085
}

Diff for: test/KurrentDB.Client.Tests/Streams/DeleteTests.cs

+32-11
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ namespace KurrentDB.Client.Tests.Streams;
55

66
[Trait("Category", "Target:Streams")]
77
[Trait("Category", "Operation:Delete")]
8-
public class DeleteTests(ITestOutputHelper output, KurrentDBPermanentFixture fixture) : KurrentPermanentTests<KurrentDBPermanentFixture>(output, fixture) {
8+
public class DeleteTests(ITestOutputHelper output, KurrentDBPermanentFixture fixture)
9+
: KurrentPermanentTests<KurrentDBPermanentFixture>(output, fixture) {
910
[Theory, ExpectedStreamStateCases]
10-
public async Task hard_deleting_a_stream_that_does_not_exist_with_expected_version_does_not_throw(StreamState expectedVersion, string name) {
11+
public async Task hard_deleting_a_stream_that_does_not_exist_with_expected_version_does_not_throw(
12+
StreamState expectedVersion, string name
13+
) {
1114
var stream = $"{Fixture.GetStreamName()}_{name}";
1215

1316
await Fixture.Streams.TombstoneAsync(stream, expectedVersion);
@@ -26,14 +29,18 @@ public async Task soft_deleting_a_stream_that_exists() {
2629
public async Task hard_deleting_a_stream_that_does_not_exist_with_wrong_expected_version_throws() {
2730
var stream = Fixture.GetStreamName();
2831

29-
await Assert.ThrowsAsync<WrongExpectedVersionException>(() => Fixture.Streams.TombstoneAsync(stream, StreamState.StreamRevision(0)));
32+
await Assert.ThrowsAsync<WrongExpectedVersionException>(
33+
() => Fixture.Streams.TombstoneAsync(stream, StreamState.StreamRevision(0))
34+
);
3035
}
3136

3237
[Fact]
3338
public async Task soft_deleting_a_stream_that_does_not_exist_with_wrong_expected_version_throws() {
3439
var stream = Fixture.GetStreamName();
3540

36-
await Assert.ThrowsAsync<WrongExpectedVersionException>(() => Fixture.Streams.DeleteAsync(stream, StreamState.StreamRevision(0)));
41+
await Assert.ThrowsAsync<WrongExpectedVersionException>(
42+
() => Fixture.Streams.DeleteAsync(stream, StreamState.StreamRevision(0))
43+
);
3744
}
3845

3946
[Fact]
@@ -72,13 +79,17 @@ public async Task hard_deleting_a_deleted_stream_should_throw() {
7279

7380
await Fixture.Streams.TombstoneAsync(stream, StreamState.NoStream);
7481

75-
await Assert.ThrowsAsync<StreamDeletedException>(() => Fixture.Streams.TombstoneAsync(stream, StreamState.NoStream));
82+
await Assert.ThrowsAsync<StreamDeletedException>(
83+
() => Fixture.Streams.TombstoneAsync(stream, StreamState.NoStream)
84+
);
7685
}
7786

7887
[Fact]
7988
public async Task with_timeout_any_stream_revision_delete_fails_when_operation_expired() {
80-
var stream = Fixture.GetStreamName();
81-
var rpcException = await Assert.ThrowsAsync<RpcException>(() => Fixture.Streams.DeleteAsync(stream, StreamState.Any, TimeSpan.Zero));
89+
var stream = Fixture.GetStreamName();
90+
var rpcException = await Assert.ThrowsAsync<RpcException>(
91+
() => Fixture.Streams.DeleteAsync(stream, StreamState.Any, new DeleteOptions { Deadline = TimeSpan.Zero })
92+
);
8293

8394
Assert.Equal(StatusCode.DeadlineExceeded, rpcException.StatusCode);
8495
}
@@ -87,15 +98,23 @@ public async Task with_timeout_any_stream_revision_delete_fails_when_operation_e
8798
public async Task with_timeout_stream_revision_delete_fails_when_operation_expired() {
8899
var stream = Fixture.GetStreamName();
89100

90-
var rpcException = await Assert.ThrowsAsync<RpcException>(() => Fixture.Streams.DeleteAsync(stream, StreamState.StreamRevision(0), TimeSpan.Zero));
101+
var rpcException = await Assert.ThrowsAsync<RpcException>(
102+
() => Fixture.Streams.DeleteAsync(
103+
stream,
104+
StreamState.StreamRevision(0),
105+
new DeleteOptions { Deadline = TimeSpan.Zero }
106+
)
107+
);
91108

92109
Assert.Equal(StatusCode.DeadlineExceeded, rpcException.StatusCode);
93110
}
94111

95112
[Fact]
96113
public async Task with_timeout_any_stream_revision_tombstoning_fails_when_operation_expired() {
97-
var stream = Fixture.GetStreamName();
98-
var rpcException = await Assert.ThrowsAsync<RpcException>(() => Fixture.Streams.TombstoneAsync(stream, StreamState.Any, TimeSpan.Zero));
114+
var stream = Fixture.GetStreamName();
115+
var rpcException = await Assert.ThrowsAsync<RpcException>(
116+
() => Fixture.Streams.TombstoneAsync(stream, StreamState.Any, TimeSpan.Zero)
117+
);
99118

100119
Assert.Equal(StatusCode.DeadlineExceeded, rpcException.StatusCode);
101120
}
@@ -104,7 +123,9 @@ public async Task with_timeout_any_stream_revision_tombstoning_fails_when_operat
104123
public async Task with_timeout_stream_revision_tombstoning_fails_when_operation_expired() {
105124
var stream = Fixture.GetStreamName();
106125

107-
var rpcException = await Assert.ThrowsAsync<RpcException>(() => Fixture.Streams.TombstoneAsync(stream, StreamState.StreamRevision(0), TimeSpan.Zero));
126+
var rpcException = await Assert.ThrowsAsync<RpcException>(
127+
() => Fixture.Streams.TombstoneAsync(stream, StreamState.StreamRevision(0), TimeSpan.Zero)
128+
);
108129

109130
Assert.Equal(StatusCode.DeadlineExceeded, rpcException.StatusCode);
110131
}

0 commit comments

Comments
 (0)