<commit_before>import XCTest
#if SQLITE_HAS_CODEC
    import GRDBCipher
#else
    import GRDB
#endif

class DatabaseErrorTests: GRDBTestCase {
    
    func testDatabaseErrorInTransaction() {
        assertNoError {
            let dbQueue = try makeDatabaseQueue()
            do {
                try dbQueue.inTransaction { db in
                    try db.execute("CREATE TABLE persons (id INTEGER PRIMARY KEY)")
                    try db.execute("CREATE TABLE pets (masterId INTEGER NOT NULL REFERENCES persons(id), name TEXT)")
                    self.sqlQueries.removeAll()
                    try db.execute("INSERT INTO pets (masterId, name) VALUES (?, ?)", arguments: [1, "Bobby"])
                    return .Commit
                }
            } catch let error as DatabaseError {
                XCTAssertEqual(error.code, 19) // SQLITE_CONSTRAINT
                XCTAssertEqual(error.message!, "FOREIGN KEY constraint failed")
                XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)")
                XCTAssertEqual(error.description, "SQLite error 19 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')")
                XCTAssertEqual(sqlQueries[1], "ROLLBACK TRANSACTION")
            }
        }
    }
    
    func testDatabaseErrorThrownByUpdateStatementContainSQLAndArguments() {
        assertNoError {
            let dbQueue = try makeDatabaseQueue()
            try dbQueue.inDatabase { db in
                try db.execute("CREATE TABLE persons (id INTEGER PRIMARY KEY)")
                try db.execute("CREATE TABLE pets (masterId INTEGER NOT NULL REFERENCES persons(id), name TEXT)")
            }
            
            // db.execute(sql, arguments)
            try dbQueue.inDatabase { db in
                do {
                    try db.execute("INSERT INTO pets (masterId, name) VALUES (?, ?)", arguments: [1, "Bobby"])
                    XCTFail()
                } catch let error as DatabaseError {
                    XCTAssertEqual(error.code, 19) // SQLITE_CONSTRAINT
                    XCTAssertEqual(error.message!, "FOREIGN KEY constraint failed")
                    XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)")
                    XCTAssertEqual(error.description, "SQLite error 19 with statement `INSERT INTO pets (masterId, name) VALUES (?, ?)` arguments [1, \"Bobby\"]: FOREIGN KEY constraint failed")
                }
            }
            
            // statement.execute(arguments)
            try dbQueue.inDatabase { db in
                do {
                    let statement = try db.updateStatement("INSERT INTO pets (masterId, name) VALUES (?, ?)")
                    try statement.execute(arguments: [1, "Bobby"])
                    XCTFail()
                } catch let error as DatabaseError {
                    XCTAssertEqual(error.code, 19) // SQLITE_CONSTRAINT
                    XCTAssertEqual(error.message!, "FOREIGN KEY constraint failed")
                    XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)")
                    XCTAssertEqual(error.description, "SQLite error 19 with statement `INSERT INTO pets (masterId, name) VALUES (?, ?)` arguments [1, \"Bobby\"]: FOREIGN KEY constraint failed")
                }
            }
            
            // statement.execute()
            try dbQueue.inDatabase { db in
                do {
                    let statement = try db.updateStatement("INSERT INTO pets (masterId, name) VALUES (?, ?)")
                    statement.arguments = [1, "Bobby"]
                    try statement.execute()
                    XCTFail()
                } catch let error as DatabaseError {
                    XCTAssertEqual(error.code, 19) // SQLITE_CONSTRAINT
                    XCTAssertEqual(error.message!, "FOREIGN KEY constraint failed")
                    XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)")
                    XCTAssertEqual(error.description, "SQLite error 19 with statement `INSERT INTO pets (masterId, name) VALUES (?, ?)` arguments [1, \"Bobby\"]: FOREIGN KEY constraint failed")
                }
            }
        }
    }
    
    func testDatabaseErrorThrownByExecuteMultiStatementContainSQL() {
        assertNoError {
            let dbQueue = try makeDatabaseQueue()
            try dbQueue.inDatabase { db in
                do {
                    try db.execute(
                        "CREATE TABLE persons (id INTEGER PRIMARY KEY, name TEXT, age INT);" +
                            "CREATE TABLE pets (masterId INTEGER NOT NULL REFERENCES persons(id), name TEXT);" +
                        "INSERT INTO pets (masterId, name) VALUES (1, 'Bobby')")
                    XCTFail()
                } catch let error as DatabaseError {
                    XCTAssertEqual(error.code, 19) // SQLITE_CONSTRAINT
                    XCTAssertEqual(error.message!, "FOREIGN KEY constraint failed")
                    XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (1, 'Bobby')")
                    XCTAssertEqual(error.description, "SQLite error 19 with statement `INSERT INTO pets (masterId, name) VALUES (1, 'Bobby')`: FOREIGN KEY constraint failed")
                }
            }
        }
    }

}<commit_msg>DatabaseErrorTests: accept various error messages from various SQLite versions<commit_after>import XCTest
#if SQLITE_HAS_CODEC
    import GRDBCipher
#else
    import GRDB
#endif

class DatabaseErrorTests: GRDBTestCase {
    
    func testDatabaseErrorInTransaction() {
        assertNoError {
            let dbQueue = try makeDatabaseQueue()
            do {
                try dbQueue.inTransaction { db in
                    try db.execute("CREATE TABLE persons (id INTEGER PRIMARY KEY)")
                    try db.execute("CREATE TABLE pets (masterId INTEGER NOT NULL REFERENCES persons(id), name TEXT)")
                    self.sqlQueries.removeAll()
                    try db.execute("INSERT INTO pets (masterId, name) VALUES (?, ?)", arguments: [1, "Bobby"])
                    return .Commit
                }
            } catch let error as DatabaseError {
                XCTAssertEqual(error.code, 19) // SQLITE_CONSTRAINT
                XCTAssertEqual(error.message!.lowercaseString, "foreign key constraint failed") // lowercaseString: accept multiple SQLite version
                XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)")
                XCTAssertEqual(error.description.lowercaseString, "sqlite error 19 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')")
                XCTAssertEqual(sqlQueries[1], "ROLLBACK TRANSACTION")
            }
        }
    }
    
    func testDatabaseErrorThrownByUpdateStatementContainSQLAndArguments() {
        assertNoError {
            let dbQueue = try makeDatabaseQueue()
            try dbQueue.inDatabase { db in
                try db.execute("CREATE TABLE persons (id INTEGER PRIMARY KEY)")
                try db.execute("CREATE TABLE pets (masterId INTEGER NOT NULL REFERENCES persons(id), name TEXT)")
            }
            
            // db.execute(sql, arguments)
            try dbQueue.inDatabase { db in
                do {
                    try db.execute("INSERT INTO pets (masterId, name) VALUES (?, ?)", arguments: [1, "Bobby"])
                    XCTFail()
                } catch let error as DatabaseError {
                    XCTAssertEqual(error.code, 19) // SQLITE_CONSTRAINT
                    XCTAssertEqual(error.message!, "FOREIGN KEY constraint failed")
                    XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)")
                    XCTAssertEqual(error.description, "SQLite error 19 with statement `INSERT INTO pets (masterId, name) VALUES (?, ?)` arguments [1, \"Bobby\"]: FOREIGN KEY constraint failed")
                }
            }
            
            // statement.execute(arguments)
            try dbQueue.inDatabase { db in
                do {
                    let statement = try db.updateStatement("INSERT INTO pets (masterId, name) VALUES (?, ?)")
                    try statement.execute(arguments: [1, "Bobby"])
                    XCTFail()
                } catch let error as DatabaseError {
                    XCTAssertEqual(error.code, 19) // SQLITE_CONSTRAINT
                    XCTAssertEqual(error.message!, "FOREIGN KEY constraint failed")
                    XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)")
                    XCTAssertEqual(error.description, "SQLite error 19 with statement `INSERT INTO pets (masterId, name) VALUES (?, ?)` arguments [1, \"Bobby\"]: FOREIGN KEY constraint failed")
                }
            }
            
            // statement.execute()
            try dbQueue.inDatabase { db in
                do {
                    let statement = try db.updateStatement("INSERT INTO pets (masterId, name) VALUES (?, ?)")
                    statement.arguments = [1, "Bobby"]
                    try statement.execute()
                    XCTFail()
                } catch let error as DatabaseError {
                    XCTAssertEqual(error.code, 19) // SQLITE_CONSTRAINT
                    XCTAssertEqual(error.message!.lowercaseString, "foreign key constraint failed") // lowercaseString: accept multiple SQLite version
                    XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (?, ?)")
                    XCTAssertEqual(error.description.lowercaseString, "sqlite error 19 with statement `insert into pets (masterid, name) values (?, ?)` arguments [1, \"bobby\"]: foreign key constraint failed")
                }
            }
        }
    }
    
    func testDatabaseErrorThrownByExecuteMultiStatementContainSQL() {
        assertNoError {
            let dbQueue = try makeDatabaseQueue()
            try dbQueue.inDatabase { db in
                do {
                    try db.execute(
                        "CREATE TABLE persons (id INTEGER PRIMARY KEY, name TEXT, age INT);" +
                            "CREATE TABLE pets (masterId INTEGER NOT NULL REFERENCES persons(id), name TEXT);" +
                        "INSERT INTO pets (masterId, name) VALUES (1, 'Bobby')")
                    XCTFail()
                } catch let error as DatabaseError {
                    XCTAssertEqual(error.code, 19) // SQLITE_CONSTRAINT
                    XCTAssertEqual(error.message!.lowercaseString, "foreign key constraint failed") // lowercaseString: accept multiple SQLite version
                    XCTAssertEqual(error.sql!, "INSERT INTO pets (masterId, name) VALUES (1, 'Bobby')")
                    XCTAssertEqual(error.description.lowercaseString, "sqlite error 19 with statement `insert into pets (masterid, name) values (1, 'bobby')`: foreign key constraint failed")
                }
            }
        }
    }

}
{'fraction_non_alphanumeric': 0.0943330427201395, 'fraction_numerical': 0.006102877070619006, 'mean_word_length': 1.8094538329659564, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6812663', 'n_tokens_mistral': 3093, 'n_tokens_neox': 2804, 'n_words': 829}