// Single conditionPlayer.filter { $0.score > 1000 }// SELECT * FROM player WHERE score > 1000// Multiple conditions with ANDPlayer.filter { $0.score > 1000 && $0.name != nil }// SELECT * FROM player WHERE (score > 1000) AND (name IS NOT NULL)// Multiple conditions with ORPlayer.filter { $0.score > 1000 || $0.score < 0 }// SELECT * FROM player WHERE (score > 1000) OR (score < 0)
// Single IDPlayer.filter(id: 42)// SELECT * FROM player WHERE id = 42// Multiple IDsPlayer.filter(ids: [1, 2, 3])// SELECT * FROM player WHERE id IN (1, 2, 3)// Compound primary keyCountryInfo.filter(key: ["code": "FR"])
// Using Column directlyPlayer.filter(Column("name") == "Arthur")// Using KeyPathPlayer.filter(\.$name == "Arthur")// Using coding keysPlayer.filter(Player.Columns.name == "Arthur")
// LIKE operatorPlayer.filter(Column("name").like("Art%"))// SELECT * FROM player WHERE name LIKE 'Art%'// Case-insensitive searchPlayer.filter(Column("email").collating(.nocase) == "[email protected]")// Pattern matchingPlayer.filter(Column("name").glob("Art*"))
// IN with arraylet names = ["Arthur", "Barbara"]Player.filter(names.contains($0.name))// SELECT * FROM player WHERE name IN ('Arthur', 'Barbara')// NOT INPlayer.filter(!names.contains($0.name))// SELECT * FROM player WHERE name NOT IN ('Arthur', 'Barbara')// IN with subquerylet subquery = Team.select(Column("name"))Player.filter(subquery.contains($0.teamName))
// Single column, ascendingPlayer.order(\.$score)// SELECT * FROM player ORDER BY score// Single column, descendingPlayer.order(\.$score.desc)// SELECT * FROM player ORDER BY score DESC// Multiple columnsPlayer.order(\.$score.desc, \.$name)// SELECT * FROM player ORDER BY score DESC, name
// First 10 recordsPlayer.limit(10)// SELECT * FROM player LIMIT 10// Pagination with offsetPlayer.limit(10, offset: 20)// SELECT * FROM player LIMIT 10 OFFSET 20// Remove limitlet unlimited = Player.limit(10).unordered()
// Group by single columnPlayer.group(\.$teamId)// SELECT * FROM player GROUP BY teamId// Group by multiple columnsPlayer.group(\.$teamId, \.$country)// SELECT * FROM player GROUP BY teamId, country// With aggregatePlayer .select(\.$teamId, count(Column("*")).forKey("count")) .group(\.$teamId)// SELECT teamId, COUNT(*) AS count FROM player GROUP BY teamId
Player .select(\.$teamId, count(Column("*")).forKey("count")) .group(\.$teamId) .having(count(Column("*")) > 5)// SELECT teamId, COUNT(*) AS count // FROM player // GROUP BY teamId // HAVING COUNT(*) > 5
Memory-efficient iteration over large result sets:
try dbQueue.read { db in let cursor = try Player .order(\.$score.desc) .fetchCursor(db) while let player = try cursor.next() { print("\(player.name): \(player.score)") }}
Cursors must be consumed within the database access block. They become invalid once the block exits.