Skip to content

Commit e267d4f

Browse files
author
Tim De Jong
committed
Restored original indentation.
1 parent 586f373 commit e267d4f

File tree

1 file changed

+108
-108
lines changed

1 file changed

+108
-108
lines changed
Lines changed: 108 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,133 @@
11
#if (SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER)) && !os(Linux)
2-
/// A long-live read-only WAL transaction.
3-
///
4-
/// `WALSnapshotTransaction` **takes ownership** of its reader
5-
/// `SerializedDatabase` (TODO: make it a move-only type eventually).
6-
final class WALSnapshotTransaction: @unchecked Sendable {
7-
// @unchecked because `databaseAccess` is protected by a mutex.
2+
/// A long-live read-only WAL transaction.
3+
///
4+
/// `WALSnapshotTransaction` **takes ownership** of its reader
5+
/// `SerializedDatabase` (TODO: make it a move-only type eventually).
6+
final class WALSnapshotTransaction: @unchecked Sendable {
7+
// @unchecked because `databaseAccess` is protected by a mutex.
88

9-
private struct DatabaseAccess {
10-
let reader: SerializedDatabase
11-
let release: @Sendable (_ isInsideTransaction: Bool) -> Void
9+
private struct DatabaseAccess {
10+
let reader: SerializedDatabase
11+
let release: @Sendable (_ isInsideTransaction: Bool) -> Void
1212

13-
// MUST be called only once
14-
func commitAndRelease() {
15-
// WALSnapshotTransaction may be deinitialized in the dispatch
16-
// queue of its reader: allow reentrancy.
17-
let isInsideTransaction = reader.reentrantSync(allowingLongLivedTransaction: false)
18-
{ db in
19-
// Commit or rollback, but try hard to leave the read-only transaction
20-
// (commit may fail with a CancellationError).
21-
do {
22-
try db.commit()
23-
} catch {
24-
try? db.rollback()
25-
}
26-
return db.isInsideTransaction
13+
// MUST be called only once
14+
func commitAndRelease() {
15+
// WALSnapshotTransaction may be deinitialized in the dispatch
16+
// queue of its reader: allow reentrancy.
17+
let isInsideTransaction = reader.reentrantSync(allowingLongLivedTransaction: false)
18+
{ db in
19+
// Commit or rollback, but try hard to leave the read-only transaction
20+
// (commit may fail with a CancellationError).
21+
do {
22+
try db.commit()
23+
} catch {
24+
try? db.rollback()
2725
}
28-
release(isInsideTransaction)
26+
return db.isInsideTransaction
2927
}
28+
release(isInsideTransaction)
3029
}
30+
}
3131

32-
// TODO: consider using the serialized DispatchQueue of reader instead of a lock.
33-
/// nil when closed
34-
private let databaseAccessMutex: Mutex<DatabaseAccess?>
32+
// TODO: consider using the serialized DispatchQueue of reader instead of a lock.
33+
/// nil when closed
34+
private let databaseAccessMutex: Mutex<DatabaseAccess?>
3535

36-
/// The state of the database at the beginning of the transaction.
37-
let walSnapshot: WALSnapshot
36+
/// The state of the database at the beginning of the transaction.
37+
let walSnapshot: WALSnapshot
3838

39-
/// Creates a long-live WAL transaction on a read-only connection.
40-
///
41-
/// The `release` closure is always called. It is called when the
42-
/// `WALSnapshotTransaction` is deallocated, or if the initializer
43-
/// throws.
44-
///
45-
/// In normal operations, the argument to `release` is always false,
46-
/// meaning that the connection is no longer in a transaction. If true,
47-
/// the connection has been left inside a transaction, due to
48-
/// some error.
49-
///
50-
/// Usage:
51-
///
52-
/// ```swift
53-
/// let transaction = WALSnapshotTransaction(
54-
/// reader: reader,
55-
/// release: { isInsideTransaction in
56-
/// ...
57-
/// })
58-
/// ```
59-
///
60-
/// - parameter reader: A read-only database connection.
61-
/// - parameter release: A closure to call when the read-only connection
62-
/// is no longer used.
63-
init(
64-
onReader reader: SerializedDatabase,
65-
release: @escaping @Sendable (_ isInsideTransaction: Bool) -> Void
66-
)
67-
throws
68-
{
69-
assert(reader.configuration.readonly)
70-
let databaseAccess = DatabaseAccess(reader: reader, release: release)
39+
/// Creates a long-live WAL transaction on a read-only connection.
40+
///
41+
/// The `release` closure is always called. It is called when the
42+
/// `WALSnapshotTransaction` is deallocated, or if the initializer
43+
/// throws.
44+
///
45+
/// In normal operations, the argument to `release` is always false,
46+
/// meaning that the connection is no longer in a transaction. If true,
47+
/// the connection has been left inside a transaction, due to
48+
/// some error.
49+
///
50+
/// Usage:
51+
///
52+
/// ```swift
53+
/// let transaction = WALSnapshotTransaction(
54+
/// reader: reader,
55+
/// release: { isInsideTransaction in
56+
/// ...
57+
/// })
58+
/// ```
59+
///
60+
/// - parameter reader: A read-only database connection.
61+
/// - parameter release: A closure to call when the read-only connection
62+
/// is no longer used.
63+
init(
64+
onReader reader: SerializedDatabase,
65+
release: @escaping @Sendable (_ isInsideTransaction: Bool) -> Void
66+
)
67+
throws
68+
{
69+
assert(reader.configuration.readonly)
70+
let databaseAccess = DatabaseAccess(reader: reader, release: release)
7171

72-
do {
73-
// Open a long-lived transaction, and enter snapshot isolation
74-
self.walSnapshot = try reader.sync(allowingLongLivedTransaction: true) { db in
75-
try db.beginTransaction(.deferred)
76-
// This also acquires snapshot isolation because checking
77-
// database schema performs a read access.
78-
try db.clearSchemaCacheIfNeeded()
79-
return try WALSnapshot(db)
80-
}
81-
self.databaseAccessMutex = Mutex(databaseAccess)
82-
} catch {
83-
// self is not initialized, so deinit will not run.
84-
databaseAccess.commitAndRelease()
85-
throw error
72+
do {
73+
// Open a long-lived transaction, and enter snapshot isolation
74+
self.walSnapshot = try reader.sync(allowingLongLivedTransaction: true) { db in
75+
try db.beginTransaction(.deferred)
76+
// This also acquires snapshot isolation because checking
77+
// database schema performs a read access.
78+
try db.clearSchemaCacheIfNeeded()
79+
return try WALSnapshot(db)
8680
}
81+
self.databaseAccessMutex = Mutex(databaseAccess)
82+
} catch {
83+
// self is not initialized, so deinit will not run.
84+
databaseAccess.commitAndRelease()
85+
throw error
8786
}
87+
}
8888

89-
deinit {
90-
close()
91-
}
92-
93-
/// Executes database operations in the snapshot transaction, and
94-
/// returns their result after they have finished executing.
95-
func read<T>(_ value: (Database) throws -> T) throws -> T {
96-
try databaseAccessMutex.withLock { databaseAccess in
97-
guard let databaseAccess else {
98-
throw DatabaseError.snapshotIsLost()
99-
}
89+
deinit {
90+
close()
91+
}
10092

101-
// We should check the validity of the snapshot, as DatabaseSnapshotPool does.
102-
return try databaseAccess.reader.sync(value)
93+
/// Executes database operations in the snapshot transaction, and
94+
/// returns their result after they have finished executing.
95+
func read<T>(_ value: (Database) throws -> T) throws -> T {
96+
try databaseAccessMutex.withLock { databaseAccess in
97+
guard let databaseAccess else {
98+
throw DatabaseError.snapshotIsLost()
10399
}
100+
101+
// We should check the validity of the snapshot, as DatabaseSnapshotPool does.
102+
return try databaseAccess.reader.sync(value)
104103
}
104+
}
105105

106-
/// Schedules database operations for execution, and
107-
/// returns immediately.
108-
func asyncRead(_ value: @escaping @Sendable (Result<Database, Error>) -> Void) {
109-
databaseAccessMutex.withLock { databaseAccess in
110-
guard let databaseAccess else {
111-
value(.failure(DatabaseError.snapshotIsLost()))
112-
return
113-
}
106+
/// Schedules database operations for execution, and
107+
/// returns immediately.
108+
func asyncRead(_ value: @escaping @Sendable (Result<Database, Error>) -> Void) {
109+
databaseAccessMutex.withLock { databaseAccess in
110+
guard let databaseAccess else {
111+
value(.failure(DatabaseError.snapshotIsLost()))
112+
return
113+
}
114114

115-
databaseAccess.reader.async { db in
116-
// We should check the validity of the snapshot, as DatabaseSnapshotPool does.
117-
// At least check if self was closed:
118-
if self.databaseAccessMutex.load() == nil {
119-
value(.failure(DatabaseError.snapshotIsLost()))
120-
}
121-
value(.success(db))
115+
databaseAccess.reader.async { db in
116+
// We should check the validity of the snapshot, as DatabaseSnapshotPool does.
117+
// At least check if self was closed:
118+
if self.databaseAccessMutex.load() == nil {
119+
value(.failure(DatabaseError.snapshotIsLost()))
122120
}
121+
value(.success(db))
123122
}
124123
}
124+
}
125125

126-
func close() {
127-
databaseAccessMutex.withLock { databaseAccess in
128-
databaseAccess?.commitAndRelease()
129-
databaseAccess = nil
130-
}
126+
func close() {
127+
databaseAccessMutex.withLock { databaseAccess in
128+
databaseAccess?.commitAndRelease()
129+
databaseAccess = nil
131130
}
132131
}
132+
}
133133
#endif

0 commit comments

Comments
 (0)