Skip to content

Commit 5a4d9b5

Browse files
committed
Let PRAGMA QUERY_ONLY statements run from a cancelled database access
Fix #1715
1 parent a64b09d commit 5a4d9b5

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

GRDB/Core/Database.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,12 @@ public final class Database: CustomStringConvertible, CustomDebugStringConvertib
12881288
return
12891289
}
12901290

1291+
// Suspension should not prevent adjusting the read-only mode.
1292+
// See <https://github.com/groue/GRDB.swift/issues/1715>.
1293+
if statement.isQueryOnlyPragma {
1294+
return
1295+
}
1296+
12911297
// How should we interrupt the statement?
12921298
enum Interrupt {
12931299
case abort // Rollback and throw SQLITE_ABORT

GRDB/Core/Statement.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ public final class Statement {
9292
/// The effects on the database (reported by `sqlite3_set_authorizer`).
9393
private(set) var authorizerEventKinds: [DatabaseEventKind] = []
9494

95+
/// If true, the statement executes is a `PRAGMA QUERY_ONLY` statement.
96+
private(set) var isQueryOnlyPragma = false
97+
9598
/// A boolean value indicating if the prepared statement makes no direct
9699
/// changes to the content of the database file.
97100
///
@@ -160,6 +163,7 @@ public final class Statement {
160163
self.invalidatesDatabaseSchemaCache = authorizer.invalidatesDatabaseSchemaCache
161164
self.transactionEffect = authorizer.transactionEffect
162165
self.authorizerEventKinds = authorizer.databaseEventKinds
166+
self.isQueryOnlyPragma = authorizer.isQueryOnlyPragma
163167
}
164168

165169
deinit {

GRDB/Core/StatementAuthorizer.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ final class StatementAuthorizer {
4141
/// savepoint statement.
4242
var transactionEffect: Statement.TransactionEffect?
4343

44+
/// If true, the statement executes is a `PRAGMA QUERY_ONLY` statement.
45+
var isQueryOnlyPragma = false
46+
4447
private var isDropStatement = false
4548

4649
init(_ database: Database) {
@@ -67,6 +70,7 @@ final class StatementAuthorizer {
6770
databaseEventKinds = []
6871
invalidatesDatabaseSchemaCache = false
6972
transactionEffect = nil
73+
isQueryOnlyPragma = false
7074
isDropStatement = false
7175
}
7276

@@ -192,6 +196,11 @@ final class StatementAuthorizer {
192196
}
193197
return SQLITE_OK
194198

199+
case SQLITE_PRAGMA:
200+
if let cString1 {
201+
isQueryOnlyPragma = sqlite3_stricmp(cString1, "query_only") == 0
202+
}
203+
return SQLITE_OK
195204
default:
196205
return SQLITE_OK
197206
}

0 commit comments

Comments
 (0)