diff --git a/GRDB/Core/Database.swift b/GRDB/Core/Database.swift index b8644a5a9f..0fb33ab005 100644 --- a/GRDB/Core/Database.swift +++ b/GRDB/Core/Database.swift @@ -315,6 +315,15 @@ public final class Database { } do { + // Use extended result codes + do { + let code = sqlite3_extended_result_codes(sqliteConnection!, 1) + guard code == SQLITE_OK else { + throw DatabaseError(code: ResultCode(rawValue: code), message: String(cString: sqlite3_errmsg(sqliteConnection))) + } + } + + // Eventual passphrase #if SQLITE_HAS_CODEC if let passphrase = configuration.passphrase { try Database.set(passphrase: passphrase, forConnection: sqliteConnection!) diff --git a/Tests/Public/Core/Database/DatabaseTests.swift b/Tests/Public/Core/Database/DatabaseTests.swift index 0e5265e9d9..ffe296c399 100644 --- a/Tests/Public/Core/Database/DatabaseTests.swift +++ b/Tests/Public/Core/Database/DatabaseTests.swift @@ -316,10 +316,10 @@ class DatabaseTests : GRDBTestCase { } XCTFail() } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) XCTAssertEqual(error.message!, "FOREIGN KEY constraint failed") XCTAssertEqual(error.sql!, "COMMIT TRANSACTION") - XCTAssertEqual(error.description, "SQLite error 19 with statement `COMMIT TRANSACTION`: FOREIGN KEY constraint failed") + XCTAssertEqual(error.description, "SQLite error 787 with statement `COMMIT TRANSACTION`: FOREIGN KEY constraint failed") } // Make sure we can open another transaction diff --git a/Tests/Public/Core/DatabaseError/DatabaseErrorTests.swift b/Tests/Public/Core/DatabaseError/DatabaseErrorTests.swift index 042452b27e..c535058c3a 100644 --- a/Tests/Public/Core/DatabaseError/DatabaseErrorTests.swift +++ b/Tests/Public/Core/DatabaseError/DatabaseErrorTests.swift @@ -22,10 +22,10 @@ class DatabaseErrorTests: GRDBTestCase { return .commit } } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) XCTAssertEqual(error.message!.lowercased(), "foreign key constraint failed") // lowercased: accept multiple SQLite version XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)") - XCTAssertEqual(error.description.lowercased(), "sqlite error 19 with statement `insert into pets (masterid, name) values (?, ?)` arguments [1, \"bobby\"]: foreign key constraint failed") + XCTAssertEqual(error.description.lowercased(), "sqlite error 787 with statement `insert into pets (masterid, name) values (?, ?)` arguments [1, \"bobby\"]: foreign key constraint failed") XCTAssertEqual(sqlQueries.count, 2) XCTAssertEqual(sqlQueries[0], "INSERT INTO pets (masterId, name) VALUES (1, 'Bobby')") @@ -56,10 +56,10 @@ class DatabaseErrorTests: GRDBTestCase { } } } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) XCTAssertEqual(error.message!.lowercased(), "foreign key constraint failed") // lowercased: accept multiple SQLite version XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)") - XCTAssertEqual(error.description.lowercased(), "sqlite error 19 with statement `insert into pets (masterid, name) values (?, ?)` arguments [1, \"bobby\"]: foreign key constraint failed") + XCTAssertEqual(error.description.lowercased(), "sqlite error 787 with statement `insert into pets (masterid, name) values (?, ?)` arguments [1, \"bobby\"]: foreign key constraint failed") } } } @@ -78,10 +78,10 @@ class DatabaseErrorTests: GRDBTestCase { try db.execute("INSERT INTO pets (masterId, name) VALUES (?, ?)", arguments: [1, "Bobby"]) XCTFail() } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) XCTAssertEqual(error.message!.lowercased(), "foreign key constraint failed") // lowercased: accept multiple SQLite version XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)") - XCTAssertEqual(error.description.lowercased(), "sqlite error 19 with statement `insert into pets (masterid, name) values (?, ?)` arguments [1, \"bobby\"]: foreign key constraint failed") + XCTAssertEqual(error.description.lowercased(), "sqlite error 787 with statement `insert into pets (masterid, name) values (?, ?)` arguments [1, \"bobby\"]: foreign key constraint failed") } } @@ -92,10 +92,10 @@ class DatabaseErrorTests: GRDBTestCase { try statement.execute(arguments: [1, "Bobby"]) XCTFail() } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) XCTAssertEqual(error.message!.lowercased(), "foreign key constraint failed") // lowercased: accept multiple SQLite version XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)") - XCTAssertEqual(error.description.lowercased(), "sqlite error 19 with statement `insert into pets (masterid, name) values (?, ?)` arguments [1, \"bobby\"]: foreign key constraint failed") + XCTAssertEqual(error.description.lowercased(), "sqlite error 787 with statement `insert into pets (masterid, name) values (?, ?)` arguments [1, \"bobby\"]: foreign key constraint failed") } } @@ -107,10 +107,10 @@ class DatabaseErrorTests: GRDBTestCase { try statement.execute() XCTFail() } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) XCTAssertEqual(error.message!.lowercased(), "foreign key constraint failed") // lowercased: accept multiple SQLite version XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)") - XCTAssertEqual(error.description.lowercased(), "sqlite error 19 with statement `insert into pets (masterid, name) values (?, ?)` arguments [1, \"bobby\"]: foreign key constraint failed") + XCTAssertEqual(error.description.lowercased(), "sqlite error 787 with statement `insert into pets (masterid, name) values (?, ?)` arguments [1, \"bobby\"]: foreign key constraint failed") } } } @@ -127,10 +127,10 @@ class DatabaseErrorTests: GRDBTestCase { "INSERT INTO pets (masterId, name) VALUES (1, 'Bobby')") XCTFail() } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) XCTAssertEqual(error.message!.lowercased(), "foreign key constraint failed") // lowercased: accept multiple SQLite version XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (1, 'Bobby')") - XCTAssertEqual(error.description.lowercased(), "sqlite error 19 with statement `insert into pets (masterid, name) values (1, 'bobby')`: foreign key constraint failed") + XCTAssertEqual(error.description.lowercased(), "sqlite error 787 with statement `insert into pets (masterid, name) values (1, 'bobby')`: foreign key constraint failed") } } } diff --git a/Tests/Public/Core/Persistable/PersistableTests.swift b/Tests/Public/Core/Persistable/PersistableTests.swift index b12ccedb18..ec1e877d96 100644 --- a/Tests/Public/Core/Persistable/PersistableTests.swift +++ b/Tests/Public/Core/Persistable/PersistableTests.swift @@ -793,7 +793,7 @@ class PersistableTests: GRDBTestCase { do { try Citizenship(personID: person.id!, countryIsoCode: "US").insert(db) } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) } try Citizenship(personID: person.id!, countryIsoCode: "FR").insert(db) } diff --git a/Tests/Public/Core/TransactionObserver/TransactionObserverTests.swift b/Tests/Public/Core/TransactionObserver/TransactionObserverTests.swift index a31116e8e2..c5f6eda26e 100644 --- a/Tests/Public/Core/TransactionObserver/TransactionObserverTests.swift +++ b/Tests/Public/Core/TransactionObserver/TransactionObserverTests.swift @@ -796,7 +796,7 @@ class TransactionObserverTests: GRDBTestCase { try Artwork(title: "meh").save(db) XCTFail("Expected Error") } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) #if SQLITE_ENABLE_PREUPDATE_HOOK XCTAssertEqual(observer.willChangeCount, 0) #endif @@ -809,7 +809,7 @@ class TransactionObserverTests: GRDBTestCase { } XCTFail("Expected Error") } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) #if SQLITE_ENABLE_PREUPDATE_HOOK XCTAssertEqual(observer.willChangeCount, 0) #endif @@ -834,7 +834,7 @@ class TransactionObserverTests: GRDBTestCase { XCTFail("Expected Error") } catch let error as DatabaseError { // Immediate constraint check has failed. - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) #if SQLITE_ENABLE_PREUPDATE_HOOK XCTAssertEqual(observer.willChangeCount, 0) #endif @@ -848,7 +848,7 @@ class TransactionObserverTests: GRDBTestCase { } XCTFail("Expected Error") } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) #if SQLITE_ENABLE_PREUPDATE_HOOK XCTAssertEqual(observer.willChangeCount, 0) #endif @@ -930,7 +930,7 @@ class TransactionObserverTests: GRDBTestCase { try Artwork(title: "meh").save(db) XCTFail("Expected Error") } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) #if SQLITE_ENABLE_PREUPDATE_HOOK XCTAssertEqual(observer.willChangeCount, 0) #endif @@ -943,7 +943,7 @@ class TransactionObserverTests: GRDBTestCase { } XCTFail("Expected Error") } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) #if SQLITE_ENABLE_PREUPDATE_HOOK XCTAssertEqual(observer.willChangeCount, 0) #endif @@ -969,7 +969,7 @@ class TransactionObserverTests: GRDBTestCase { XCTFail("Expected Error") } catch let error as DatabaseError { // Immediate constraint check has failed. - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) #if SQLITE_ENABLE_PREUPDATE_HOOK XCTAssertEqual(observer.willChangeCount, 0) #endif @@ -983,7 +983,7 @@ class TransactionObserverTests: GRDBTestCase { } XCTFail("Expected Error") } catch let error as DatabaseError { - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) #if SQLITE_ENABLE_PREUPDATE_HOOK XCTAssertEqual(observer.willChangeCount, 0) #endif diff --git a/Tests/Public/Migrations/DatabaseMigratorTests.swift b/Tests/Public/Migrations/DatabaseMigratorTests.swift index c9a8d34659..ece4e8eed8 100644 --- a/Tests/Public/Migrations/DatabaseMigratorTests.swift +++ b/Tests/Public/Migrations/DatabaseMigratorTests.swift @@ -118,10 +118,10 @@ class DatabaseMigratorTests : GRDBTestCase { // The first migration should be committed. // The second migration should be rollbacked. - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) XCTAssertEqual(error.message!.lowercased(), "foreign key constraint failed") // lowercased: accept multiple SQLite version XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)") - XCTAssertEqual(error.description.lowercased(), "sqlite error 19 with statement `insert into pets (masterid, name) values (?, ?)` arguments [123, \"bobby\"]: foreign key constraint failed") + XCTAssertEqual(error.description.lowercased(), "sqlite error 787 with statement `insert into pets (masterid, name) values (?, ?)` arguments [123, \"bobby\"]: foreign key constraint failed") let names = try dbQueue.inDatabase { db in try String.fetchAll(db, "SELECT name FROM persons") @@ -172,7 +172,7 @@ class DatabaseMigratorTests : GRDBTestCase { // Migration 1 and 2 should be committed. // Migration 3 should not be committed. - XCTAssertEqual(error.code, .SQLITE_CONSTRAINT) + XCTAssertEqual(error.primaryResultCode, .SQLITE_CONSTRAINT) XCTAssertEqual(error.message!, "FOREIGN KEY constraint failed") XCTAssertTrue(error.sql == nil) XCTAssertEqual(error.description, "SQLite error 19: FOREIGN KEY constraint failed")