Files
UUVPN/iOS-SwiftUI-Code/GRDB.swift-6.29.3/Tests/GRDBTests/ColumnExpressionTests.swift
T

278 lines
12 KiB
Swift

import XCTest
import GRDB
class ColumnExpressionTests: GRDBTestCase {
func testRawColumnExpression() throws {
struct Player: TableRecord, FetchableRecord, PersistableRecord {
var id: Int64
var name: String
var score: Int
struct Column: ColumnExpression {
var name: String
}
enum Columns {
static let id = Player.Column(name: "id")
static let name = Player.Column(name: "name")
static let score = Player.Column(name: "score")
}
// Test databaseSelection
static let databaseSelection: [any SQLSelectable] = [Columns.id, Columns.name, Columns.score]
init(row: Row) {
// Test row subscript
id = row[Columns.id]
name = row[Columns.name]
score = row[Columns.score]
}
func encode(to container: inout PersistenceContainer) {
// Test container subscript
container[Columns.id] = id
container[Columns.name] = name
container[Columns.score] = score
}
static var testRequest: QueryInterfaceRequest<Player> {
// Test expression derivation
return filter(Columns.name != nil).order(Columns.score.desc)
}
}
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.create(table: "player") { t in
t.autoIncrementedPrimaryKey("id")
t.column("name")
t.column("score")
}
// Test rowId column identification
try XCTAssertEqual(Player.filter(key: 1).databaseRegion(db).description, "player(id,name,score)[1]")
try XCTAssertEqual(Player.filter(Player.Columns.id == 1).databaseRegion(db).description, "player(id,name,score)[1]")
try XCTAssertEqual(Player.filter(1 == Player.Columns.id).databaseRegion(db).description, "player(id,name,score)[1]")
try XCTAssertEqual(Player.filter(Player.Columns.id == 1 || Player.Columns.id == 2).databaseRegion(db).description, "player(id,name,score)[1,2]")
try XCTAssertEqual(Player.filter([1, 2, 3].contains(Player.Columns.id)).databaseRegion(db).description, "player(id,name,score)[1,2,3]")
// Test specific column updates
let player = Player(row: ["id": 1, "name": "Arthur", "score": 1000])
try? player.update(db, columns: [Player.Columns.name, Player.Columns.score])
XCTAssertEqual(lastSQLQuery, "UPDATE \"player\" SET \"name\"=\'Arthur\', \"score\"=1000 WHERE \"id\"=1")
// Test compound expression
let expression = Player.Columns.name == "foo"
let request = Player.select(expression)
try assertEqualSQL(db, request, "SELECT \"name\" = 'foo' FROM \"player\"")
}
}
func testRawRepresentableColumnExpression() throws {
struct Player: TableRecord, FetchableRecord, PersistableRecord {
var id: Int64
var name: String
var score: Int
enum Columns: String, ColumnExpression {
case id, name, score
}
// Test databaseSelection
static let databaseSelection: [any SQLSelectable] = [Columns.id, Columns.name, Columns.score]
init(row: Row) {
// Test row subscript
id = row[Columns.id]
name = row[Columns.name]
score = row[Columns.score]
}
func encode(to container: inout PersistenceContainer) {
// Test container subscript
container[Columns.id] = id
container[Columns.name] = name
container[Columns.score] = score
}
static var testRequest: QueryInterfaceRequest<Player> {
// Test expression derivation
return filter(Columns.name != nil).order(Columns.score.desc)
}
}
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.create(table: "player") { t in
t.autoIncrementedPrimaryKey("id")
t.column("name")
t.column("score")
}
// Test rowId column identification
try XCTAssertEqual(Player.filter(key: 1).databaseRegion(db).description, "player(id,name,score)[1]")
try XCTAssertEqual(Player.filter(Player.Columns.id == 1).databaseRegion(db).description, "player(id,name,score)[1]")
try XCTAssertEqual(Player.filter(1 == Player.Columns.id).databaseRegion(db).description, "player(id,name,score)[1]")
try XCTAssertEqual(Player.filter(Player.Columns.id == 1 || Player.Columns.id == 2).databaseRegion(db).description, "player(id,name,score)[1,2]")
try XCTAssertEqual(Player.filter([1, 2, 3].contains(Player.Columns.id)).databaseRegion(db).description, "player(id,name,score)[1,2,3]")
// Test specific column updates
let player = Player(row: ["id": 1, "name": "Arthur", "score": 1000])
try? player.update(db, columns: [Player.Columns.name, Player.Columns.score])
XCTAssertEqual(lastSQLQuery, "UPDATE \"player\" SET \"name\"=\'Arthur\', \"score\"=1000 WHERE \"id\"=1")
// Test compound expression
let expression = Player.Columns.name == "foo"
let request = Player.select(expression)
try assertEqualSQL(db, request, "SELECT \"name\" = 'foo' FROM \"player\"")
}
}
func testColumnsDerivedFromCodingKeys() throws {
struct Player: Codable, TableRecord, FetchableRecord, PersistableRecord {
var id: Int64
var name: String
var score: Int
enum CodingKeys: String, CodingKey {
case id
case name = "full_name"
case score
}
enum Columns {
static let id = Column(CodingKeys.id)
static let name = Column(CodingKeys.name)
static let score = Column(CodingKeys.score)
}
// Test databaseSelection
static let databaseSelection: [any SQLSelectable] = [Columns.id, Columns.name, Columns.score]
static var testRequest: QueryInterfaceRequest<Player> {
// Test expression derivation
return filter(Columns.name != nil).order(Columns.score.desc)
}
}
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.create(table: "player") { t in
t.autoIncrementedPrimaryKey("id")
t.column("full_name")
t.column("score")
}
// Test rowId column identification
try XCTAssertEqual(Player.filter(key: 1).databaseRegion(db).description, "player(full_name,id,score)[1]")
try XCTAssertEqual(Player.filter(Player.Columns.id == 1).databaseRegion(db).description, "player(full_name,id,score)[1]")
try XCTAssertEqual(Player.filter(1 == Player.Columns.id).databaseRegion(db).description, "player(full_name,id,score)[1]")
try XCTAssertEqual(Player.filter(Player.Columns.id == 1 || Player.Columns.id == 2).databaseRegion(db).description, "player(full_name,id,score)[1,2]")
try XCTAssertEqual(Player.filter([1, 2, 3].contains(Player.Columns.id)).databaseRegion(db).description, "player(full_name,id,score)[1,2,3]")
// Test specific column updates
let player = try Player(row: ["id": 1, "full_name": "Arthur", "score": 1000])
try? player.update(db, columns: [Player.Columns.name, Player.Columns.score])
XCTAssertEqual(lastSQLQuery, "UPDATE \"player\" SET \"full_name\"=\'Arthur\', \"score\"=1000 WHERE \"id\"=1")
// Test compound expression
let expression = Player.Columns.name == "foo"
let request = Player.select(expression)
try assertEqualSQL(db, request, "SELECT \"full_name\" = 'foo' FROM \"player\"")
}
}
func testCodingKeysAsColumnExpression() throws {
struct Player: Codable, TableRecord, FetchableRecord, PersistableRecord {
var id: Int64
var name: String
var score: Int
enum CodingKeys: String, CodingKey, ColumnExpression {
case id
case name = "full_name"
case score
}
// Test databaseSelection
static let databaseSelection: [any SQLSelectable] = [CodingKeys.id, CodingKeys.name, CodingKeys.score]
static var testRequest: QueryInterfaceRequest<Player> {
// Test expression derivation
return filter(CodingKeys.name != nil).order(CodingKeys.score.desc)
}
}
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.create(table: "player") { t in
t.autoIncrementedPrimaryKey("id")
t.column("full_name")
t.column("score")
}
// Test rowId column identification
try XCTAssertEqual(Player.filter(key: 1).databaseRegion(db).description, "player(full_name,id,score)[1]")
try XCTAssertEqual(Player.filter(Player.CodingKeys.id == 1).databaseRegion(db).description, "player(full_name,id,score)[1]")
try XCTAssertEqual(Player.filter(1 == Player.CodingKeys.id).databaseRegion(db).description, "player(full_name,id,score)[1]")
try XCTAssertEqual(Player.filter(Player.CodingKeys.id == 1 || Player.CodingKeys.id == 2).databaseRegion(db).description, "player(full_name,id,score)[1,2]")
try XCTAssertEqual(Player.filter([1, 2, 3].contains(Player.CodingKeys.id)).databaseRegion(db).description, "player(full_name,id,score)[1,2,3]")
// Test specific column updates
let player = try Player(row: ["id": 1, "full_name": "Arthur", "score": 1000])
try? player.update(db, columns: [Player.CodingKeys.name, Player.CodingKeys.score])
XCTAssertEqual(lastSQLQuery, "UPDATE \"player\" SET \"full_name\"=\'Arthur\', \"score\"=1000 WHERE \"id\"=1")
// Test compound expression
let expression = Player.CodingKeys.name == "foo"
let request = Player.select(expression)
try assertEqualSQL(db, request, "SELECT \"full_name\" = 'foo' FROM \"player\"")
}
}
func testDetachedColumn() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.write { db in
try db.create(table: "t") { t in t.column("a") }
// Regular columns are qualified
do {
let alias = TableAlias(name: "custom")
let request = Table("t")
.aliased(alias)
.order(Column("a"))
let sql = try request.makePreparedRequest(db).statement.sql
XCTAssertEqual(sql, """
SELECT "custom".* FROM "t" "custom" ORDER BY "custom"."a"
""")
}
// Detached columns are NOT qualified
do {
let alias = TableAlias(name: "custom")
let request = Table("t")
.aliased(alias)
.order(Column("a").detached)
let sql = try request.makePreparedRequest(db).statement.sql
XCTAssertEqual(sql, """
SELECT "custom".* FROM "t" "custom" ORDER BY "a"
""")
}
// Detached columns are quoted
do {
let alias = TableAlias(name: "custom")
let request = Table("t")
.aliased(alias)
.select(Column("a").forKey("order"))
.order(Column("order").detached)
let sql = try request.makePreparedRequest(db).statement.sql
XCTAssertEqual(sql, """
SELECT "custom"."a" AS "order" FROM "t" "custom" ORDER BY "order"
""")
}
}
}
}