Files
UUVPN/iOS-SwiftUI-Code/GRDB.swift-6.29.3/Tests/GRDBTests/DatabaseTests.swift
T
2025-01-22 14:09:10 +08:00

625 lines
27 KiB
Swift

import XCTest
import GRDB
class DatabaseTests : GRDBTestCase {
func testCreateTable() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
XCTAssertFalse(try db.tableExists("persons"))
try db.execute(sql: """
CREATE TABLE persons (
id INTEGER PRIMARY KEY,
name TEXT,
age INT)
""")
XCTAssertTrue(try db.tableExists("persons"))
}
}
func testCreateTemporaryTable() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
XCTAssertFalse(try db.tableExists("persons"))
try db.execute(sql: """
CREATE TEMPORARY TABLE persons (
id INTEGER PRIMARY KEY,
name TEXT,
age INT)
""")
XCTAssertTrue(try db.tableExists("persons"))
}
}
func testMultipleStatementsWithoutArguments() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
XCTAssertFalse(try db.tableExists("persons"))
XCTAssertFalse(try db.tableExists("pets"))
try db.execute(sql: """
CREATE TABLE persons (id INTEGER PRIMARY KEY, name TEXT, age INT);
CREATE TABLE pets (id INTEGER PRIMARY KEY, name TEXT, age INT);
""")
XCTAssertTrue(try db.tableExists("persons"))
XCTAssertTrue(try db.tableExists("pets"))
}
}
func testUpdateStatement() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
// The tested function:
let statement = try db.makeStatement(sql: "INSERT INTO persons (name, age) VALUES ('Arthur', 41)")
try statement.execute()
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testUpdateStatementWithArrayBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
let statement = try db.makeStatement(sql: "INSERT INTO persons (name, age) VALUES (?, ?)")
try statement.execute(arguments: ["Arthur", 41])
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testUpdateStatementWithDictionaryBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
let statement = try db.makeStatement(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)")
try statement.execute(arguments: ["name": "Arthur", "age": 41])
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testUpdateStatementLiteral() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
// The tested function:
let statement = try db.makeStatement(literal: "INSERT INTO persons (name, age) VALUES ('Arthur', 41)")
try statement.execute()
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testUpdateStatementLiteralWithArguments() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
// The tested function:
let statement = try db.makeStatement(literal: "INSERT INTO persons (name, age) VALUES (\("Arthur"), \(41))")
try statement.execute()
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testUpdateStatementLiteralWithArrayBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
let statement = try db.makeStatement(literal: "INSERT INTO persons (name, age) VALUES (?, ?)")
try statement.execute(arguments: ["Arthur", 41])
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testUpdateStatementLiteralWithDictionaryBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
let statement = try db.makeStatement(literal: "INSERT INTO persons (name, age) VALUES (:name, :age)")
try statement.execute(arguments: ["name": "Arthur", "age": 41])
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testCachedUpdateStatementLiteral() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
// The tested function:
let statement = try db.cachedStatement(literal: "INSERT INTO persons (name, age) VALUES ('Arthur', 41)")
try statement.execute()
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testCachedUpdateStatementLiteralWithArguments() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
// The tested function:
let statement = try db.cachedStatement(literal: "INSERT INTO persons (name, age) VALUES (\("Arthur"), \(41))")
try statement.execute()
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testCachedUpdateStatementLiteralWithArrayBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
let statement = try db.cachedStatement(literal: "INSERT INTO persons (name, age) VALUES (?, ?)")
try statement.execute(arguments: ["Arthur", 41])
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testCachedUpdateStatementLiteralWithDictionaryBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
let statement = try db.cachedStatement(literal: "INSERT INTO persons (name, age) VALUES (:name, :age)")
try statement.execute(arguments: ["name": "Arthur", "age": 41])
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testDatabaseExecute() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
// The tested function:
try db.execute(sql: "INSERT INTO persons (name, age) VALUES ('Arthur', 41)")
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testDatabaseExecuteChanges() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
XCTAssertEqual(db.changesCount, 0)
XCTAssertEqual(db.totalChangesCount, 0)
XCTAssertEqual(db.lastInsertedRowID, 0)
try db.execute(sql: "CREATE TABLE persons (id INTEGER PRIMARY KEY, name TEXT)")
try db.execute(sql: "INSERT INTO persons (name) VALUES ('Arthur')")
XCTAssertEqual(db.changesCount, 1)
XCTAssertEqual(db.totalChangesCount, 1)
XCTAssertEqual(db.lastInsertedRowID, 1)
try db.execute(sql: "INSERT INTO persons (name) VALUES (?)", arguments: ["Barbara"])
XCTAssertEqual(db.changesCount, 1)
XCTAssertEqual(db.totalChangesCount, 2)
XCTAssertEqual(db.lastInsertedRowID, 2)
try db.execute(sql: "DELETE FROM persons")
XCTAssertEqual(db.changesCount, 2)
XCTAssertEqual(db.totalChangesCount, 4)
XCTAssertEqual(db.lastInsertedRowID, 2)
}
}
func testDatabaseExecuteWithArrayBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
// The tested function:
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (?, ?)", arguments: ["Arthur", 41])
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testDatabaseExecuteWithDictionaryBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
// The tested function:
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
XCTAssertEqual(row[0] as String, "Arthur")
XCTAssertEqual(row[1] as Int, 41)
}
}
func testSelectStatement() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
let statement = try db.makeStatement(sql: "SELECT * FROM persons")
let rows = try Row.fetchAll(statement)
XCTAssertEqual(rows.count, 2)
}
}
func testSelectStatementWithArrayBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
let statement = try db.makeStatement(sql: "SELECT * FROM persons WHERE name = ?")
let rows = try Row.fetchAll(statement, arguments: ["Arthur"])
XCTAssertEqual(rows.count, 1)
}
}
func testSelectStatementWithDictionaryBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
let statement = try db.makeStatement(sql: "SELECT * FROM persons WHERE name = :name")
let rows = try Row.fetchAll(statement, arguments: ["name": "Arthur"])
XCTAssertEqual(rows.count, 1)
}
}
func testSelectStatementLiteral() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
let statement = try db.makeStatement(literal: "SELECT * FROM persons")
let rows = try Row.fetchAll(statement)
XCTAssertEqual(rows.count, 2)
}
}
func testSelectStatementLiteralWithArguments() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
let statement = try db.makeStatement(literal: "SELECT * FROM persons WHERE name = \("Arthur")")
let rows = try Row.fetchAll(statement)
XCTAssertEqual(rows.count, 1)
}
}
func testSelectStatementLiteralWithArrayBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
let statement = try db.makeStatement(literal: "SELECT * FROM persons WHERE name = ?")
let rows = try Row.fetchAll(statement, arguments: ["Arthur"])
XCTAssertEqual(rows.count, 1)
}
}
func testSelectStatementLiteralWithDictionaryBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
let statement = try db.makeStatement(literal: "SELECT * FROM persons WHERE name = :name")
let rows = try Row.fetchAll(statement, arguments: ["name": "Arthur"])
XCTAssertEqual(rows.count, 1)
}
}
func testCachedSelectStatementLiteral() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
let statement = try db.cachedStatement(literal: "SELECT * FROM persons")
let rows = try Row.fetchAll(statement)
XCTAssertEqual(rows.count, 2)
}
}
func testCachedSelectStatementLiteralWithArguments() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
let statement = try db.cachedStatement(literal: "SELECT * FROM persons WHERE name = \("Arthur")")
let rows = try Row.fetchAll(statement)
XCTAssertEqual(rows.count, 1)
}
}
func testCachedSelectStatementLiteralWithArrayBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
let statement = try db.cachedStatement(literal: "SELECT * FROM persons WHERE name = ?")
let rows = try Row.fetchAll(statement, arguments: ["Arthur"])
XCTAssertEqual(rows.count, 1)
}
}
func testCachedSelectStatementLiteralWithDictionaryBinding() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
let statement = try db.cachedStatement(literal: "SELECT * FROM persons WHERE name = :name")
let rows = try Row.fetchAll(statement, arguments: ["name": "Arthur"])
XCTAssertEqual(rows.count, 1)
}
}
func testRowValueAtIndex() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
var names: [String?] = []
var ages: [Int?] = []
let rows = try Row.fetchCursor(db, sql: "SELECT * FROM persons ORDER BY name")
while let row = try rows.next() {
// The tested function:
let name: String? = row[0]
let age: Int? = row[1]
names.append(name)
ages.append(age)
}
XCTAssertEqual(names[0]!, "Arthur")
XCTAssertEqual(names[1]!, "Barbara")
XCTAssertEqual(ages[0]!, 41)
XCTAssertNil(ages[1])
}
}
func testRowValueNamed() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE persons (name TEXT, age INT)")
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Arthur", "age": 41])
try db.execute(sql: "INSERT INTO persons (name, age) VALUES (:name, :age)", arguments: ["name": "Barbara", "age": nil])
var names: [String?] = []
var ages: [Int?] = []
let rows = try Row.fetchCursor(db, sql: "SELECT * FROM persons ORDER BY name")
while let row = try rows.next() {
// The tested function:
let name: String? = row["name"]
let age: Int? = row["age"]
names.append(name)
ages.append(age)
}
XCTAssertEqual(names[0]!, "Arthur")
XCTAssertEqual(names[1]!, "Barbara")
XCTAssertEqual(ages[0]!, 41)
XCTAssertNil(ages[1])
}
}
func testDatabaseCanBeUsedOutsideOfDatabaseQueueBlockAsLongAsTheQueueIsCorrect() throws {
let dbQueue = try makeDatabaseQueue()
var database: Database? = nil
dbQueue.inDatabase { db in
database = db
}
try dbQueue.inDatabase { _ in
try database!.execute(sql: "CREATE TABLE persons (name TEXT)")
}
}
func testFailedCommitIsRollbacked() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE parent (id INTEGER PRIMARY KEY)")
try db.execute(sql: "CREATE TABLE child (parentID INTEGER NOT NULL REFERENCES parent(id))")
}
do {
try dbQueue.inTransaction { db in
do {
try db.execute(sql: "PRAGMA defer_foreign_keys = ON")
try db.execute(sql: "INSERT INTO child (parentID) VALUES (1)")
} catch {
XCTFail()
}
return .commit
}
XCTFail()
} catch let error as DatabaseError {
XCTAssertEqual(error.resultCode, .SQLITE_CONSTRAINT)
XCTAssertEqual(error.message!, "FOREIGN KEY constraint failed")
XCTAssertEqual(error.sql!, "COMMIT TRANSACTION")
XCTAssertEqual(error.description, "SQLite error 19: FOREIGN KEY constraint failed - while executing `COMMIT TRANSACTION`")
}
// Make sure we can open another transaction
try dbQueue.inTransaction { db in .commit }
}
func testExplicitTransactionManagement() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.writeWithoutTransaction { db in
try db.beginTransaction()
XCTAssertEqual(lastSQLQuery, "BEGIN DEFERRED TRANSACTION")
try db.rollback()
XCTAssertEqual(lastSQLQuery, "ROLLBACK TRANSACTION")
try db.beginTransaction(.immediate)
XCTAssertEqual(lastSQLQuery, "BEGIN IMMEDIATE TRANSACTION")
try db.commit()
XCTAssertEqual(lastSQLQuery, "COMMIT TRANSACTION")
}
}
func testReadOnly() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.execute(sql: "CREATE TABLE t (id INTEGER PRIMARY KEY)")
// Write access OK
try db.execute(sql: "INSERT INTO t DEFAULT VALUES")
try db.readOnly {
do {
try db.execute(sql: "INSERT INTO t DEFAULT VALUES")
XCTFail()
} catch let error as DatabaseError {
XCTAssertEqual(error.resultCode, .SQLITE_READONLY)
}
// Reentrancy
try db.readOnly {
do {
try db.execute(sql: "INSERT INTO t DEFAULT VALUES")
XCTFail()
} catch let error as DatabaseError {
XCTAssertEqual(error.resultCode, .SQLITE_READONLY)
}
}
// Still read-only
do {
try db.execute(sql: "INSERT INTO t DEFAULT VALUES")
XCTFail()
} catch let error as DatabaseError {
XCTAssertEqual(error.resultCode, .SQLITE_READONLY)
}
}
// Write access OK
try db.execute(sql: "INSERT INTO t DEFAULT VALUES")
}
}
func testReadOnlyTransaction() throws {
dbConfiguration.defaultTransactionKind = .immediate
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
do {
sqlQueries.removeAll()
try db.inSavepoint { .commit }
try db.inTransaction { .commit }
try db.inTransaction(.immediate) { .commit }
XCTAssertEqual(Set(sqlQueries), ["BEGIN IMMEDIATE TRANSACTION", "COMMIT TRANSACTION"])
}
try db.readOnly {
sqlQueries.removeAll()
try db.inSavepoint { .commit }
try db.inTransaction { .commit }
XCTAssertEqual(Set(sqlQueries), ["BEGIN DEFERRED TRANSACTION", "COMMIT TRANSACTION"])
do {
try db.inTransaction(.immediate) { .commit }
XCTFail("Expected error")
} catch DatabaseError.SQLITE_READONLY { }
}
}
}
func testCheckpoint() throws {
do {
// Not a WAL database
let dbQueue = try makeDatabaseQueue()
let result = try dbQueue.inDatabase {
try $0.checkpoint()
}
XCTAssertEqual(result.walFrameCount, -1)
XCTAssertEqual(result.checkpointedFrameCount, -1)
}
do {
// WAL database
let dbPool = try makeDatabasePool()
let result = try dbPool.writeWithoutTransaction {
try $0.checkpoint()
}
XCTAssertGreaterThanOrEqual(result.walFrameCount, 0)
XCTAssertGreaterThanOrEqual(result.checkpointedFrameCount, 0)
}
do {
// WAL database + TRUNCATE
let dbPool = try makeDatabasePool()
let result = try dbPool.writeWithoutTransaction {
try $0.checkpoint(.truncate)
}
XCTAssertEqual(result.walFrameCount, 0)
XCTAssertEqual(result.checkpointedFrameCount, 0)
}
}
func testMaximumStatementArgumentCount() throws {
let dbQueue = try makeDatabaseQueue()
let count = try dbQueue.read { $0.maximumStatementArgumentCount }
// 999 should be safe: https://www.sqlite.org/limits.html
XCTAssertGreaterThanOrEqual(count, 999)
}
}