-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSQLite.AsyncSession.cs
More file actions
133 lines (125 loc) · 5.23 KB
/
Copy pathSQLite.AsyncSession.cs
File metadata and controls
133 lines (125 loc) · 5.23 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
129
130
131
132
133
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Data.Sqlite;
namespace DBAClientX;
public partial class SQLite {
/// <summary>Opens a managed asynchronous SQLite session using one provider connection.</summary>
public virtual async Task<SQLiteAsyncSession> OpenSessionAsync(
string database,
CancellationToken cancellationToken = default) {
var connectionString = BuildOperationalConnectionString(database);
SqliteConnection? connection = null;
try {
(connection, _, _) = await ResolveConnectionAsync(
connectionString,
useTransaction: false,
cancellationToken).ConfigureAwait(false);
return new SQLiteAsyncSession(this, connection);
} catch {
if (connection is not null) {
await DisposeSQLiteConnectionAsync(connection).ConfigureAwait(false);
}
throw;
}
}
internal async Task<int> ExecuteSessionNonQueryAsync(
SqliteConnection connection,
SqliteTransaction? transaction,
string query,
IDictionary<string, object?>? parameters,
CancellationToken cancellationToken) {
ValidateCommandText(query);
try {
return await base.ExecuteNonQueryAsync(
connection,
transaction,
query,
parameters,
cancellationToken).ConfigureAwait(false);
} catch (Exception ex) when (!IsCallerCancellation(ex, cancellationToken) && ex is (SqliteException or InvalidOperationException)) {
throw CreateQueryExecutionOrCancellationException("Failed to execute non-query.", query, ex, cancellationToken);
}
}
internal async Task<object?> ExecuteSessionScalarAsync(
SqliteConnection connection,
SqliteTransaction? transaction,
string query,
IDictionary<string, object?>? parameters,
CancellationToken cancellationToken) {
ValidateCommandText(query);
try {
return await base.ExecuteScalarAsync(
connection,
transaction,
query,
parameters,
cancellationToken).ConfigureAwait(false);
} catch (Exception ex) when (!IsCallerCancellation(ex, cancellationToken) && ex is (SqliteException or InvalidOperationException)) {
throw CreateQueryExecutionOrCancellationException("Failed to execute scalar query.", query, ex, cancellationToken);
}
}
internal async Task<IReadOnlyList<T>> ExecuteSessionQueryAsListAsync<T>(
SqliteConnection connection,
SqliteTransaction? transaction,
string query,
Func<IDataRecord, T> map,
IDictionary<string, object?>? parameters,
Action<IDataRecord>? initialize,
CancellationToken cancellationToken) {
ValidateCommandText(query);
if (map is null) {
throw new ArgumentNullException(nameof(map));
}
try {
return await ExecuteMappedQueryAsync(
connection,
transaction,
query,
map,
initialize,
parameters,
cancellationToken).ConfigureAwait(false);
} catch (Exception ex) when (!IsCallerCancellation(ex, cancellationToken) && ex is (SqliteException or InvalidOperationException)) {
throw CreateQueryExecutionOrCancellationException("Failed to execute mapped query.", query, ex, cancellationToken);
}
}
internal async Task<TResult> ExecuteSessionTransactionAsync<TResult>(
SqliteConnection connection,
Func<SQLiteAsyncSession, CancellationToken, Task<TResult>> operation,
CancellationToken cancellationToken) {
if (operation is null) {
throw new ArgumentNullException(nameof(operation));
}
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER || NET5_0_OR_GREATER
await using var transaction = (SqliteTransaction)await connection
.BeginTransactionAsync(cancellationToken)
.ConfigureAwait(false);
#else
using var transaction = connection.BeginTransaction();
#endif
var transactionSession = new SQLiteAsyncSession(this, connection, transaction);
try {
var result = await operation(transactionSession, cancellationToken).ConfigureAwait(false);
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER || NET5_0_OR_GREATER
await transaction.CommitAsync(cancellationToken).ConfigureAwait(false);
#else
transaction.Commit();
#endif
return result;
} catch (Exception ex) {
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER || NET5_0_OR_GREATER
await HandleTransactionFailureAsync(
ex,
token => transaction.RollbackAsync(token),
static () => true,
cancellationToken).ConfigureAwait(false);
#else
HandleTransactionFailure(ex, transaction.Rollback, static () => true);
#endif
throw new InvalidOperationException("Transaction failure handling returned unexpectedly.", ex);
}
}
}