public protocol PredicateExpression<Output> {
associatedtype Output
func evaluate(_ bindings: PredicateBindings) throws -> Output
}
<aside> π‘ predicateμ ꡬμ±νλ ννμμ΄ μ€μν΄μΌ νλ μꡬμ¬νμ λͺ μΈ.
</aside>
ν΄λΉ νλ‘ν μ½μ κΈ°λ³Έ predicate νμ
μ΄ λ§€ν¬λ‘μμ expression treeλ₯Ό νμ±νκΈ° μν΄ κ΅¬νν΄μΌ νλ νμ λ©μλλ₯Ό λͺ
μΈνλ€. ν΄λΉ λ©μλλ₯Ό μ μ§μ μΌλ‘ νΈμΆν΄μ νμ ννμμ μννλ©° predicate μλ£κ΅¬μ‘°λ‘ λ³ννλ κ³Όμ μ tree walkingμ΄λΌκ³ μΉνλλ°, μ νλ‘ν μ½κ³Ό μ μ¬νκ² tree walkingμ μννλ νλ‘ν μ½μ μμ±νκ³ , κ° ννμμ μ΅μ€ν
μ
μ μΆκ°ν΄ ν΄λΉ νλ‘ν μ½μ μ±ννλ©΄ predicate 맀ν¬λ‘λ‘λΆν° Predicate
νμ
μ΄μΈμ μνλ ν¬λ§·μ κ²°κ³Όκ°μ μ»μ΄λΌ μ μλ€. SQL 쿼리 string, κΈ°ν DB 쿼리 κ°μ²΄ ννλ₯Ό μ»μ΄λ΄κ³ μ νλ κ²½μ° μ μ©ν μ μλ€.
<aside>
π‘ tree walkingν ννμμμ λ³μκ°(μ
λ ₯κ° ν¬ν¨)μ μ λ¬λ°κ³ μ¬μ©ν΄μΌ ν κ²½μ°, μ evaluate(_:)
λ©μλμ²λΌ PredicateBindings
νμ
μ μ ννλ€. μμΈν μ€λͺ
μ ν΄λΉ νμ΄μ§μμ.
</aside>
μλ₯Ό λ€μ΄, λ€μκ³Ό κ°μ νλ‘ν μ½μ΄ μλ€κ³ νμ:
protocol ProsePredicateExpression {
func proseQuery() -> String
}
ν΄λΉ νλ‘ν μ½μ μ±ννλ ννμμ extension μ½λλ₯Ό λ€μκ³Ό κ°μ΄ μμ±ν μ μλ€:
extension PredicateExpressions.Equal: ProsePredicateExpression
where LHS: ProsePredicateExpression, RHS: ProsePredicateExpression {
func proseQuery() -> String {
return lhs.proseQuery() + " is equal to " + rhs.proseQuery()
}
}
Predicate
νμ
μ ν΄λΉ tree walking λ©μλμ μ΅μμ λ 벨 λ©μλλ₯Ό μΆκ°νλ€:
extension Predicate {
func proseQuery() -> String? {
guard let expression = expression as? ProsePredicateExpression else { return nil }
return expression.proseQuery()
}
}
λ λμκ°λ€λ©΄, ν΄λΉ μ μ¬ νλ‘ν μ½μ μ±ννλ 컀μ€ν Predicate νμ μ μ μν μλ μμ κ²μ΄λ€. μ΄λ κ² ν κ²½μ° μ§μνμ§ μλ ννμμ μ¬μ©λ μ μλλ‘ μ°¨λ¨νλ€λ μ₯μ μ΄ μμΌλ, 컀μ€ν Predicate νμ μ μ μνλ λ°©λ² λ° κ΄λ ¨ APIκΉμ§λ μμ§ proposalμ΄ μ¬λΌμ€μ§ μμλ€.
struct ProsePredicate<Input...> {
let expression: any ProsePredicateExpression<Bool>
// ...
func convertToProseQuery() -> String {
return expression.proseQuery()
}
}