Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ on: push
jobs:
test:
runs-on: macos-13

steps:
- uses: actions/checkout@v3
- name: Select Xcode 15
run: sudo xcode-select -s /Applications/Xcode_15.0.app
- name: Test
run: swift test

27 changes: 19 additions & 8 deletions Sources/SQLite/SQLiteDatabase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,20 @@ public final class SQLiteDatabase: DatabaseProtocol, @unchecked Sendable {
)
}

public func truncate() throws {
switch database {
case let .pool(pool):
try pool.writeWithoutTransaction { db in
_ = try db.execute(raw: "PRAGMA wal_checkpoint(TRUNCATE);")
}

case let .queue(queue):
try queue.writeWithoutTransaction { db in
_ = try db.execute(raw: "PRAGMA wal_checkpoint(TRUNCATE);")
}
}
}

// NOTE: This function is only really meant to be called in tests.
public func close() throws {
changeNotifier.stop()
Expand Down Expand Up @@ -275,7 +289,7 @@ public extension SQLiteDatabase {
@discardableResult
func execute(raw sql: SQL) async throws -> [SQLiteRow] {
do {
return try await database.writer.write { db in
return try await database.writer.writeWithoutTransaction { db in
try db.execute(raw: sql)
}
} catch {
Expand Down Expand Up @@ -339,7 +353,7 @@ public extension SQLiteDatabase {
@discardableResult
func execute(raw sql: SQL) throws -> [SQLiteRow] {
do {
return try database.writer.write { db in
return try database.writer.writeWithoutTransaction { db in
try db.execute(raw: sql)
}
} catch {
Expand Down Expand Up @@ -644,13 +658,10 @@ private extension SQLiteDatabase {
config.journalMode = isInMemory ? .default : .wal
// NOTE: GRDB recommends `defaultTransactionKind` be set
// to `.immediate` in order to prevent `SQLITE_BUSY`
// errors. Using `.immediate` appears to disable
// automatic vacuuming.
// errors.
//
// https://swiftpackageindex.com/groue/grdb.swift/v6.24.2/documentation/grdb/databasesharing#How-to-limit-the-SQLITEBUSY-error
config.defaultTransactionKind = isInMemory
? .deferred
: .immediate
config.defaultTransactionKind = .immediate
config.busyMode = .timeout(busyTimeout)
config.observesSuspensionNotifications = true
config.maximumReaderCount = max(
Expand Down Expand Up @@ -770,7 +781,7 @@ private enum Database {
arguments: SQLiteArguments = [:]
) throws {
do {
try writer.write { db in
try writer.writeWithoutTransaction { db in
try db.write(sql, arguments: arguments)
}
} catch {
Expand Down
21 changes: 21 additions & 0 deletions Tests/SQLiteTests/SQLiteDatabaseTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,27 @@ final class SQLiteDatabaseTests: XCTestCase {
}
}

func testCheckpointUsingTruncate() throws {
try Sandbox.execute { directory in
let path = directory.appendingPathComponent("test.db").path
let db = try SQLiteDatabase(path: path)
defer { try? db.close() }

try db.execute(raw: _createTableWithBlob)

try db.inTransaction { db in
for index in 0 ..< 100 {
let args: SQLiteArguments = [
"id": .integer(Int64(index)), "data": .data(_textData),
]
try db.write(_insertIDAndData, arguments: args)
}
}

try db.truncate()
}
}

func testCreateTable() throws {
XCTAssertNoThrow(try database.execute(raw: _createTableWithBlob))
let tableNames = try database.tables()
Expand Down