Add changes & totalChanges properties for connection

This commit is contained in:
2025-11-11 16:28:51 +02:00
parent b41d772f7f
commit e48c37aca4
3 changed files with 75 additions and 0 deletions

View File

@@ -131,6 +131,14 @@ extension Connection: ConnectionProtocol {
sqlite3_db_readonly(connection, "main") == 1 sqlite3_db_readonly(connection, "main") == 1
} }
public var changes: Int64 {
sqlite3_changes64(connection)
}
public var totalChanges: Int64 {
sqlite3_total_changes64(connection)
}
public static func initialize() throws(SQLiteError) { public static func initialize() throws(SQLiteError) {
let status = sqlite3_initialize() let status = sqlite3_initialize()
guard status == SQLITE_OK else { guard status == SQLITE_OK else {

View File

@@ -12,6 +12,8 @@ import Foundation
/// ///
/// - ``isAutocommit`` /// - ``isAutocommit``
/// - ``isReadonly`` /// - ``isReadonly``
/// - ``changes``
/// - ``totalChanges``
/// ///
/// ### Accessing PRAGMA Values /// ### Accessing PRAGMA Values
/// ///
@@ -84,6 +86,14 @@ public protocol ConnectionProtocol: AnyObject {
/// - SeeAlso: [Determine if a database is read-only](https://sqlite.org/c3ref/db_readonly.html) /// - SeeAlso: [Determine if a database is read-only](https://sqlite.org/c3ref/db_readonly.html)
var isReadonly: Bool { get } var isReadonly: Bool { get }
/// The number of rows modified by the most recent write operation.
/// - SeeAlso: [Count The Number Of Rows Modified](https://sqlite.org/c3ref/changes.html)
var changes: Int64 { get }
/// The total number of rows modified since this connection was opened.
/// - SeeAlso: [Total Number Of Rows Modified](https://sqlite.org/c3ref/total_changes.html)
var totalChanges: Int64 { get }
// MARK: - PRAGMA Accessors // MARK: - PRAGMA Accessors
/// The busy timeout of the connection, in milliseconds. /// The busy timeout of the connection, in milliseconds.

View File

@@ -63,6 +63,63 @@ struct ConnectionTests {
#expect(connection.isReadonly == expected) #expect(connection.isReadonly == expected)
} }
@Test func changes() throws {
let connection = try Connection(
location: .inMemory, options: [.create, .readwrite]
)
try connection.execute(sql: "CREATE TABLE t (id INT PRIMARY KEY)")
#expect(connection.changes == 0)
try connection.execute(sql: "INSERT INTO t (id) VALUES (1),(2)")
#expect(connection.changes == 2)
try connection.execute(sql: "UPDATE t SET id = 3 WHERE id = 1")
#expect(connection.changes == 1)
try connection.execute(sql: "DELETE FROM t WHERE id = 2")
#expect(connection.changes == 1)
try connection.execute(sql: "UPDATE t SET id = 3 WHERE id = -1")
#expect(connection.changes == 0)
try connection.execute(sql: "INSERT INTO t (id) VALUES (4),(5)")
try connection.execute(sql: "SELECT * FROM t")
#expect(connection.changes == 2)
}
@Test func totalChanges() throws {
let connection = try Connection(
location: .inMemory, options: [.create, .readwrite]
)
try connection.execute(sql: "CREATE TABLE t (id INT PRIMARY KEY)")
#expect(connection.totalChanges == 0)
try connection.execute(sql: "INSERT INTO t (id) VALUES (1),(2)")
#expect(connection.totalChanges == 2)
try connection.execute(sql: "UPDATE t SET id = 3 WHERE id = 1")
#expect(connection.totalChanges == 3)
try connection.execute(sql: "DELETE FROM t WHERE id = 2")
#expect(connection.totalChanges == 4)
// No-op update does not increase totalChanges
try connection.execute(sql: "UPDATE t SET id = 3 WHERE id = -1")
#expect(connection.totalChanges == 4)
// Read-only statements do not affect totals
try connection.execute(sql: "SELECT * FROM t")
#expect(connection.totalChanges == 4)
try connection.execute(sql: "INSERT INTO t (id) VALUES (4),(5)")
#expect(connection.totalChanges == 6)
try connection.execute(sql: "DELETE FROM t")
#expect(connection.totalChanges == 9)
}
@Test func testBusyTimeout() throws { @Test func testBusyTimeout() throws {
let connection = try Connection( let connection = try Connection(
location: .inMemory, options: [.create, .readwrite] location: .inMemory, options: [.create, .readwrite]