-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSQLiteAsyncSession.cs
More file actions
128 lines (112 loc) · 4.65 KB
/
Copy pathSQLiteAsyncSession.cs
File metadata and controls
128 lines (112 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Data.Sqlite;
namespace DBAClientX;
/// <summary>
/// Represents an asynchronous SQLite connection session owned and managed by <see cref="SQLite"/>.
/// </summary>
/// <remarks>
/// Provider-specific connection and transaction objects remain internal to DBAClientX. Consumers
/// provide domain SQL, parameter values, and provider-neutral <see cref="IDataRecord"/> projections.
/// </remarks>
public sealed class SQLiteAsyncSession : IAsyncDisposable {
private readonly SQLite _client;
private readonly SqliteConnection _connection;
private readonly SqliteTransaction? _transaction;
private readonly bool _ownsConnection;
private bool _disposed;
internal SQLiteAsyncSession(SQLite client, SqliteConnection connection)
: this(client, connection, transaction: null, ownsConnection: true) {
}
internal SQLiteAsyncSession(SQLite client, SqliteConnection connection, SqliteTransaction transaction)
: this(client, connection, transaction, ownsConnection: false) {
}
private SQLiteAsyncSession(
SQLite client,
SqliteConnection connection,
SqliteTransaction? transaction,
bool ownsConnection) {
_client = client ?? throw new ArgumentNullException(nameof(client));
_connection = connection ?? throw new ArgumentNullException(nameof(connection));
_transaction = transaction;
_ownsConnection = ownsConnection;
}
/// <summary>Executes a statement that does not return rows.</summary>
public Task<int> ExecuteNonQueryAsync(
string query,
IDictionary<string, object?>? parameters = null,
CancellationToken cancellationToken = default) {
ThrowIfDisposed();
return _client.ExecuteSessionNonQueryAsync(_connection, _transaction, query, parameters, cancellationToken);
}
/// <summary>Executes a statement and returns the first column of the first row.</summary>
public Task<object?> ExecuteScalarAsync(
string query,
IDictionary<string, object?>? parameters = null,
CancellationToken cancellationToken = default) {
ThrowIfDisposed();
return _client.ExecuteSessionScalarAsync(_connection, _transaction, query, parameters, cancellationToken);
}
/// <summary>Executes a query and maps every row through a provider-neutral record.</summary>
public Task<IReadOnlyList<T>> QueryAsListAsync<T>(
string query,
Func<IDataRecord, T> map,
IDictionary<string, object?>? parameters = null,
Action<IDataRecord>? initialize = null,
CancellationToken cancellationToken = default) {
ThrowIfDisposed();
return _client.ExecuteSessionQueryAsListAsync(
_connection,
_transaction,
query,
map,
parameters,
initialize,
cancellationToken);
}
/// <summary>Runs related operations inside one SQLite transaction.</summary>
public Task<TResult> RunInTransactionAsync<TResult>(
Func<SQLiteAsyncSession, CancellationToken, Task<TResult>> operation,
CancellationToken cancellationToken = default) {
ThrowIfDisposed();
if (_transaction is not null) {
throw new DbaTransactionException("A session transaction is already active.");
}
return _client.ExecuteSessionTransactionAsync(_connection, operation, cancellationToken);
}
/// <summary>Runs related operations inside one SQLite transaction.</summary>
public async Task RunInTransactionAsync(
Func<SQLiteAsyncSession, CancellationToken, Task> operation,
CancellationToken cancellationToken = default) {
if (operation is null) {
throw new ArgumentNullException(nameof(operation));
}
await RunInTransactionAsync(async (session, token) => {
await operation(session, token).ConfigureAwait(false);
return true;
}, cancellationToken).ConfigureAwait(false);
}
/// <inheritdoc />
public async ValueTask DisposeAsync() {
if (_disposed) {
return;
}
if (_ownsConnection) {
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER || NET5_0_OR_GREATER
await _connection.DisposeAsync().ConfigureAwait(false);
#else
_connection.Dispose();
await Task.CompletedTask.ConfigureAwait(false);
#endif
}
_disposed = true;
}
private void ThrowIfDisposed() {
if (_disposed) {
throw new ObjectDisposedException(nameof(SQLiteAsyncSession));
}
}
}