Add CI/CD configuration and API documentation
This commit is contained in:
@@ -0,0 +1,583 @@
|
||||
import XCTest
|
||||
import GRDB
|
||||
|
||||
class StatementArgumentsTests: GRDBTestCase {
|
||||
|
||||
override func setup(_ dbWriter: some DatabaseWriter) throws {
|
||||
var migrator = DatabaseMigrator()
|
||||
migrator.registerMigration("createPersons") { db in
|
||||
try db.execute(sql: """
|
||||
CREATE TABLE persons (
|
||||
id INTEGER PRIMARY KEY,
|
||||
firstName TEXT,
|
||||
lastName TEXT,
|
||||
age INT)
|
||||
""")
|
||||
}
|
||||
try migrator.migrate(dbWriter)
|
||||
}
|
||||
|
||||
func testPositionalStatementArgumentsValidation() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let statement = try db.makeStatement(sql: "INSERT INTO persons (firstName, age) VALUES (?, ?)")
|
||||
|
||||
do {
|
||||
// Correct number of arguments
|
||||
try statement.validateArguments(["foo", 1])
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Missing arguments
|
||||
try statement.validateArguments([])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Two few arguments
|
||||
try statement.validateArguments(["foo"])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Two many arguments
|
||||
try statement.validateArguments(["foo", 1, "bar"])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Missing arguments
|
||||
try statement.validateArguments([:])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Unmappable arguments
|
||||
try statement.validateArguments(["firstName": "foo", "age": 1])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testPositionalStatementArguments() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let name = "Arthur"
|
||||
let age = 42
|
||||
let arguments = StatementArguments([name, age] as [(any DatabaseValueConvertible)?])
|
||||
|
||||
let updateStatement = try db.makeStatement(sql: "INSERT INTO persons (firstName, age) VALUES (?, ?)")
|
||||
updateStatement.arguments = arguments
|
||||
try updateStatement.execute()
|
||||
|
||||
let selectStatement = try db.makeStatement(sql: "SELECT * FROM persons WHERE firstName = ? AND age = ?")
|
||||
selectStatement.arguments = arguments
|
||||
let row = try Row.fetchOne(selectStatement)!
|
||||
|
||||
XCTAssertEqual(row["firstName"] as String, name)
|
||||
XCTAssertEqual(row["age"] as Int, age)
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckedPositionalStatementArguments() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let name = "Arthur"
|
||||
let age = 42
|
||||
let arguments = StatementArguments([name, age] as [(any DatabaseValueConvertible)?])
|
||||
|
||||
let updateStatement = try db.makeStatement(sql: "INSERT INTO persons (firstName, age) VALUES (?, ?)")
|
||||
try updateStatement.setArguments(arguments)
|
||||
try updateStatement.execute()
|
||||
|
||||
let selectStatement = try db.makeStatement(sql: "SELECT * FROM persons WHERE firstName = ? AND age = ?")
|
||||
try selectStatement.setArguments(arguments)
|
||||
let row = try Row.fetchOne(selectStatement)!
|
||||
|
||||
XCTAssertEqual(row["firstName"] as String, name)
|
||||
XCTAssertEqual(row["age"] as Int, age)
|
||||
|
||||
do {
|
||||
try updateStatement.setArguments([1])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
XCTAssertEqual(updateStatement.arguments, arguments)
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
try selectStatement.setArguments([1])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
XCTAssertEqual(selectStatement.arguments, arguments)
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testUncheckedPositionalStatementArguments() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let name = "Arthur"
|
||||
let age = 42
|
||||
let arguments = StatementArguments([name, age] as [(any DatabaseValueConvertible)?])
|
||||
|
||||
let updateStatement = try db.makeStatement(sql: "INSERT INTO persons (firstName, age) VALUES (?, ?)")
|
||||
updateStatement.setUncheckedArguments(arguments)
|
||||
try updateStatement.execute()
|
||||
|
||||
let selectStatement = try db.makeStatement(sql: "SELECT * FROM persons WHERE firstName = ? AND age = ?")
|
||||
selectStatement.setUncheckedArguments(arguments)
|
||||
let row = try Row.fetchOne(selectStatement)!
|
||||
|
||||
XCTAssertEqual(row["firstName"] as String, name)
|
||||
XCTAssertEqual(row["age"] as Int, age)
|
||||
}
|
||||
}
|
||||
|
||||
func testNamedStatementArgumentsValidation() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let statement = try db.makeStatement(sql: "INSERT INTO persons (firstName, age) VALUES (:firstName, :age)")
|
||||
|
||||
do {
|
||||
// Correct number of arguments
|
||||
try statement.validateArguments(["foo", 1])
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// All arguments are mapped
|
||||
try statement.validateArguments(["firstName": "foo", "age": 1])
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// All arguments are mapped
|
||||
try statement.validateArguments(["firstName": "foo", "age": 1, "bar": "baz"])
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Missing arguments
|
||||
try statement.validateArguments([])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Missing arguments
|
||||
try statement.validateArguments(["foo"])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Too many arguments
|
||||
try statement.validateArguments(["foo", 1, "baz"])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Missing arguments
|
||||
try statement.validateArguments([:])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Missing arguments
|
||||
try statement.validateArguments(["firstName": "foo"])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testNamedStatementArguments() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let name = "Arthur"
|
||||
let age = 42
|
||||
let arguments = StatementArguments(["name": name, "age": age] as [String: (any DatabaseValueConvertible)?])
|
||||
|
||||
let updateStatement = try db.makeStatement(sql: "INSERT INTO persons (firstName, age) VALUES (:name, :age)")
|
||||
updateStatement.arguments = arguments
|
||||
try updateStatement.execute()
|
||||
|
||||
let selectStatement = try db.makeStatement(sql: "SELECT * FROM persons WHERE firstName = :name AND age = :age")
|
||||
selectStatement.arguments = arguments
|
||||
let row = try Row.fetchOne(selectStatement)!
|
||||
|
||||
XCTAssertEqual(row["firstName"] as String, name)
|
||||
XCTAssertEqual(row["age"] as Int, age)
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckedNamedStatementArguments() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let name = "Arthur"
|
||||
let age = 42
|
||||
let arguments = StatementArguments(["name": name, "age": age] as [String: (any DatabaseValueConvertible)?])
|
||||
|
||||
let updateStatement = try db.makeStatement(sql: "INSERT INTO persons (firstName, age) VALUES (:name, :age)")
|
||||
try updateStatement.setArguments(arguments)
|
||||
try updateStatement.execute()
|
||||
|
||||
let selectStatement = try db.makeStatement(sql: "SELECT * FROM persons WHERE firstName = :name AND age = :age")
|
||||
try selectStatement.setArguments(arguments)
|
||||
let row = try Row.fetchOne(selectStatement)!
|
||||
|
||||
XCTAssertEqual(row["firstName"] as String, name)
|
||||
XCTAssertEqual(row["age"] as Int, age)
|
||||
|
||||
do {
|
||||
try updateStatement.setArguments(["name": name])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
XCTAssertEqual(updateStatement.arguments, arguments)
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
try selectStatement.setArguments(["name": name])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
XCTAssertEqual(selectStatement.arguments, arguments)
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testUncheckedNamedStatementArguments() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let name = "Arthur"
|
||||
let age = 42
|
||||
let arguments = StatementArguments(["name": name, "age": age] as [String: (any DatabaseValueConvertible)?])
|
||||
|
||||
let updateStatement = try db.makeStatement(sql: "INSERT INTO persons (firstName, age) VALUES (:name, :age)")
|
||||
updateStatement.setUncheckedArguments(arguments)
|
||||
try updateStatement.execute()
|
||||
|
||||
let selectStatement = try db.makeStatement(sql: "SELECT * FROM persons WHERE firstName = :name AND age = :age")
|
||||
selectStatement.setUncheckedArguments(arguments)
|
||||
let row = try Row.fetchOne(selectStatement)!
|
||||
|
||||
XCTAssertEqual(row["firstName"] as String, name)
|
||||
XCTAssertEqual(row["age"] as Int, age)
|
||||
}
|
||||
}
|
||||
|
||||
func testReusedNamedStatementArgumentsValidation() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let statement = try db.makeStatement(sql: "INSERT INTO persons (firstName, lastName, age) VALUES (:name, :name, :age)")
|
||||
|
||||
do {
|
||||
try statement.execute(arguments: ["name": "foo", "age": 1])
|
||||
let row = try Row.fetchOne(db, sql: "SELECT * FROM persons")!
|
||||
XCTAssertEqual(row["firstName"] as String, "foo")
|
||||
XCTAssertEqual(row["lastName"] as String, "foo")
|
||||
XCTAssertEqual(row["age"] as Int, 1)
|
||||
}
|
||||
|
||||
do {
|
||||
// Correct number of arguments
|
||||
try statement.validateArguments(["foo", 1])
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// All arguments are mapped
|
||||
try statement.validateArguments(["name": "foo", "age": 1])
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// All arguments are mapped
|
||||
try statement.validateArguments(["name": "foo", "age": 1, "bar": "baz"])
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Missing arguments
|
||||
try statement.validateArguments([])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Missing arguments
|
||||
try statement.validateArguments(["foo"])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Too many arguments
|
||||
try statement.validateArguments(["foo", 1, "baz"])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Missing arguments
|
||||
try statement.validateArguments([:])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
// Missing arguments
|
||||
try statement.validateArguments(["name": "foo"])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testReusedNamedStatementArguments() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let name = "Arthur"
|
||||
let age = 42
|
||||
let arguments = StatementArguments(["name": name, "age": age] as [String: (any DatabaseValueConvertible)?])
|
||||
|
||||
let updateStatement = try db.makeStatement(sql: "INSERT INTO persons (firstName, lastName, age) VALUES (:name, :name, :age)")
|
||||
updateStatement.arguments = arguments
|
||||
try updateStatement.execute()
|
||||
|
||||
let selectStatement = try db.makeStatement(sql: "SELECT * FROM persons WHERE firstName = :name AND lastName = :name AND age = :age")
|
||||
selectStatement.arguments = arguments
|
||||
let row = try Row.fetchOne(selectStatement)!
|
||||
|
||||
XCTAssertEqual(row["firstName"] as String, name)
|
||||
XCTAssertEqual(row["age"] as Int, age)
|
||||
}
|
||||
}
|
||||
|
||||
func testCheckedReusedNamedStatementArguments() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let name = "Arthur"
|
||||
let age = 42
|
||||
let arguments = StatementArguments(["name": name, "age": age] as [String: (any DatabaseValueConvertible)?])
|
||||
|
||||
let updateStatement = try db.makeStatement(sql: "INSERT INTO persons (firstName, lastName, age) VALUES (:name, :name, :age)")
|
||||
try updateStatement.setArguments(arguments)
|
||||
try updateStatement.execute()
|
||||
|
||||
let selectStatement = try db.makeStatement(sql: "SELECT * FROM persons WHERE firstName = :name AND lastName = :name AND age = :age")
|
||||
try selectStatement.setArguments(arguments)
|
||||
let row = try Row.fetchOne(selectStatement)!
|
||||
|
||||
XCTAssertEqual(row["firstName"] as String, name)
|
||||
XCTAssertEqual(row["age"] as Int, age)
|
||||
|
||||
do {
|
||||
try updateStatement.setArguments(["name": name])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
XCTAssertEqual(updateStatement.arguments, arguments)
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
|
||||
do {
|
||||
try selectStatement.setArguments(["name": name])
|
||||
XCTFail("Expected error")
|
||||
} catch DatabaseError.SQLITE_MISUSE {
|
||||
XCTAssertEqual(selectStatement.arguments, arguments)
|
||||
} catch {
|
||||
XCTFail("Unexpected error: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testUncheckedReusedNamedStatementArguments() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let name = "Arthur"
|
||||
let age = 42
|
||||
let arguments = StatementArguments(["name": name, "age": age] as [String: (any DatabaseValueConvertible)?])
|
||||
|
||||
let updateStatement = try db.makeStatement(sql: "INSERT INTO persons (firstName, lastName, age) VALUES (:name, :name, :age)")
|
||||
updateStatement.setUncheckedArguments(arguments)
|
||||
try updateStatement.execute()
|
||||
|
||||
let selectStatement = try db.makeStatement(sql: "SELECT * FROM persons WHERE firstName = :name AND lastName = :name AND age = :age")
|
||||
selectStatement.setUncheckedArguments(arguments)
|
||||
let row = try Row.fetchOne(selectStatement)!
|
||||
|
||||
XCTAssertEqual(row["firstName"] as String, name)
|
||||
XCTAssertEqual(row["age"] as Int, age)
|
||||
}
|
||||
}
|
||||
|
||||
func testMixedArguments() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
let sql = "SELECT ?2 AS two, :foo AS foo, ?1 AS one, :foo AS foo2, :bar AS bar"
|
||||
let row = try Row.fetchOne(db, sql: sql, arguments: [1, 2, "bar"] + ["foo": "foo"])!
|
||||
XCTAssertEqual(row, ["two": 2, "foo": "foo", "one": 1, "foo2": "foo", "bar": "bar"])
|
||||
}
|
||||
}
|
||||
|
||||
func testAppendContentsOf() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
do {
|
||||
var arguments: StatementArguments = [1, 2]
|
||||
let replacedValues = arguments.append(contentsOf: [3, 4])
|
||||
XCTAssert(replacedValues.isEmpty)
|
||||
|
||||
let row = try Row.fetchOne(db, sql: "SELECT ?, ?, ?, ?", arguments: arguments)!
|
||||
XCTAssertEqual(row, ["?": 1, "?": 2, "?": 3, "?": 4])
|
||||
}
|
||||
|
||||
do {
|
||||
var arguments: StatementArguments = ["foo": "foo", "bar": "bar", "toto": "titi"]
|
||||
let replacedValues = arguments.append(contentsOf: ["foo": "qux", "bar": "baz", "tata": "tutu"])
|
||||
XCTAssertEqual(replacedValues, ["foo": "foo".databaseValue, "bar": "bar".databaseValue])
|
||||
|
||||
let row = try Row.fetchOne(db, sql: "SELECT :foo, :bar, :toto, :tata", arguments: arguments)!
|
||||
XCTAssertEqual(row, [":foo": "qux", ":bar": "baz", ":toto": "titi", ":tata": "tutu"])
|
||||
}
|
||||
|
||||
do {
|
||||
var arguments: StatementArguments = [1, 2]
|
||||
let replacedValues = arguments.append(contentsOf: ["foo": "qux", "bar": "baz", "tata": "tutu"])
|
||||
XCTAssert(replacedValues.isEmpty)
|
||||
|
||||
let row = try Row.fetchOne(db, sql: "SELECT ?, :foo, :bar, ?, :tata", arguments: arguments)!
|
||||
XCTAssertEqual(row, ["?": 1, ":foo": "qux", ":bar": "baz", "?": 2, ":tata": "tutu"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testPlusOperator() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
do {
|
||||
let arguments: StatementArguments = [1, 2] + [3, 4]
|
||||
let row = try Row.fetchOne(db, sql: "SELECT ?, ?, ?, ?", arguments: arguments)!
|
||||
XCTAssertEqual(row, ["?": 1, "?": 2, "?": 3, "?": 4])
|
||||
}
|
||||
|
||||
do {
|
||||
// + does not allow overrides
|
||||
let arguments: StatementArguments = ["foo": "foo", "bar": "bar", "toto": "titi"] + ["tata": "tutu"]
|
||||
let row = try Row.fetchOne(db, sql: "SELECT :foo, :bar, :toto, :tata", arguments: arguments)!
|
||||
XCTAssertEqual(row, [":foo": "foo", ":bar": "bar", ":toto": "titi", ":tata": "tutu"])
|
||||
}
|
||||
|
||||
do {
|
||||
let arguments: StatementArguments = [1, 2] + ["foo": "qux", "bar": "baz", "tata": "tutu"]
|
||||
let row = try Row.fetchOne(db, sql: "SELECT ?, :foo, :bar, ?, :tata", arguments: arguments)!
|
||||
XCTAssertEqual(row, ["?": 1, ":foo": "qux", ":bar": "baz", "?": 2, ":tata": "tutu"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testOverflowPlusOperator() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
do {
|
||||
let arguments: StatementArguments = [1, 2] &+ [3, 4]
|
||||
let row = try Row.fetchOne(db, sql: "SELECT ?, ?, ?, ?", arguments: arguments)!
|
||||
XCTAssertEqual(row, ["?": 1, "?": 2, "?": 3, "?": 4])
|
||||
}
|
||||
|
||||
do {
|
||||
// &+ does not allow overrides
|
||||
let arguments: StatementArguments = ["foo": "foo", "bar": "bar", "toto": "titi"] &+ ["foo": "qux", "bar": "baz", "tata": "tutu"]
|
||||
let row = try Row.fetchOne(db, sql: "SELECT :foo, :bar, :toto, :tata", arguments: arguments)!
|
||||
XCTAssertEqual(row, [":foo": "qux", ":bar": "baz", ":toto": "titi", ":tata": "tutu"])
|
||||
}
|
||||
|
||||
do {
|
||||
let arguments: StatementArguments = [1, 2] &+ ["foo": "qux", "bar": "baz", "tata": "tutu"]
|
||||
let row = try Row.fetchOne(db, sql: "SELECT ?, :foo, :bar, ?, :tata", arguments: arguments)!
|
||||
XCTAssertEqual(row, ["?": 1, ":foo": "qux", ":bar": "baz", "?": 2, ":tata": "tutu"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testPlusEqualOperator() throws {
|
||||
let dbQueue = try makeDatabaseQueue()
|
||||
try dbQueue.inDatabase { db in
|
||||
do {
|
||||
var arguments: StatementArguments = [1, 2]
|
||||
arguments += [3, 4]
|
||||
let row = try Row.fetchOne(db, sql: "SELECT ?, ?, ?, ?", arguments: arguments)!
|
||||
XCTAssertEqual(row, ["?": 1, "?": 2, "?": 3, "?": 4])
|
||||
}
|
||||
|
||||
do {
|
||||
// += does not allow overrides
|
||||
var arguments: StatementArguments = ["foo": "foo", "bar": "bar", "toto": "titi"]
|
||||
arguments += ["tata": "tutu"]
|
||||
let row = try Row.fetchOne(db, sql: "SELECT :foo, :bar, :toto, :tata", arguments: arguments)!
|
||||
XCTAssertEqual(row, [":foo": "foo", ":bar": "bar", ":toto": "titi", ":tata": "tutu"])
|
||||
}
|
||||
|
||||
do {
|
||||
var arguments: StatementArguments = [1, 2]
|
||||
arguments += ["foo": "qux", "bar": "baz", "tata": "tutu"]
|
||||
let row = try Row.fetchOne(db, sql: "SELECT ?, :foo, :bar, ?, :tata", arguments: arguments)!
|
||||
XCTAssertEqual(row, ["?": 1, ":foo": "qux", ":bar": "baz", "?": 2, ":tata": "tutu"])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user