Skip to content

Add comparison operators for optional columns #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions Sources/StructuredQueriesCore/Operators.swift
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,120 @@ extension QueryExpression where QueryValue: QueryBindable {
}
}

extension QueryExpression where QueryValue: QueryBindable & _OptionalProtocol {
/// Returns a predicate expression indicating whether the value of the first expression is less
/// than that of the second expression.
///
/// > Important: Overloaded operators can strain the Swift compiler's type checking ability.
/// > Consider using ``lt(_:)``, instead.
///
/// - Parameters:
/// - lhs: An expression to compare.
/// - rhs: Another expression to compare.
/// - Returns: A predicate expression.
public static func < (
lhs: Self,
rhs: some QueryExpression<QueryValue.Wrapped>
) -> some QueryExpression<Bool> {
lhs.lt(rhs)
}

/// Returns a predicate expression indicating whether the value of the first expression is greater
/// than that of the second expression.
///
/// > Important: Overloaded operators can strain the Swift compiler's type checking ability.
/// > Consider using ``gt(_:)``, instead.
///
/// - Parameters:
/// - lhs: An expression to compare.
/// - rhs: Another expression to compare.
/// - Returns: A predicate expression.
public static func > (
lhs: Self,
rhs: some QueryExpression<QueryValue.Wrapped>
) -> some QueryExpression<Bool> {
lhs.gt(rhs)
}

/// Returns a predicate expression indicating whether the value of the first expression is less
/// than or equal to that of the second expression.
///
/// > Important: Overloaded operators can strain the Swift compiler's type checking ability.
/// > Consider using ``lte(_:)``, instead.
///
/// - Parameters:
/// - lhs: An expression to compare.
/// - rhs: Another expression to compare.
/// - Returns: A predicate expression.
public static func <= (
lhs: Self,
rhs: some QueryExpression<QueryValue.Wrapped>
) -> some QueryExpression<Bool> {
lhs.lte(rhs)
}

/// Returns a predicate expression indicating whether the value of the first expression is greater
/// than or equal to that of the second expression.
///
/// > Important: Overloaded operators can strain the Swift compiler's type checking ability.
/// > Consider using ``gte(_:)``, instead.
///
/// - Parameters:
/// - lhs: An expression to compare.
/// - rhs: Another expression to compare.
/// - Returns: A predicate expression.
public static func >= (
lhs: Self,
rhs: some QueryExpression<QueryValue.Wrapped>
) -> some QueryExpression<Bool> {
lhs.gte(rhs)
}

/// Returns a predicate expression indicating whether the value of the optional first expression is less
/// than that of the second expression.
///
/// - Parameter other: An expression to compare this one to.
/// - Returns: A predicate expression.
public func lt(
_ other: some QueryExpression<QueryValue.Wrapped>
) -> some QueryExpression<Bool> {
BinaryOperator(lhs: self, operator: "<", rhs: other)
}

/// Returns a predicate expression indicating whether the value of the optional first expression is greater
/// than that of the second expression.
///
/// - Parameter other: An expression to compare this one to.
/// - Returns: A predicate expression.
public func gt(
_ other: some QueryExpression<QueryValue.Wrapped>
) -> some QueryExpression<Bool> {
BinaryOperator(lhs: self, operator: ">", rhs: other)
}

/// Returns a predicate expression indicating whether the value of the optional first expression is less
/// than or equal to that of the second expression.
///
/// - Parameter other: An expression to compare this one to.
/// - Returns: A predicate expression.
public func lte(
_ other: some QueryExpression<QueryValue.Wrapped>
) -> some QueryExpression<Bool> {
BinaryOperator(lhs: self, operator: "<=", rhs: other)
}

/// Returns a predicate expression indicating whether the value of the optional first expression is greater
/// than or equal to that of the second expression.
///
/// - Parameter other: An expression to compare this one to.
/// - Returns: A predicate expression.
public func gte(
_ other: some QueryExpression<QueryValue.Wrapped>
) -> some QueryExpression<Bool> {
BinaryOperator(lhs: self, operator: ">=", rhs: other)
}
}

extension QueryExpression where QueryValue == Bool {
/// Returns a logical AND operation on two predicate expressions.
///
Expand Down
43 changes: 43 additions & 0 deletions Tests/StructuredQueriesTests/OperatorsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,49 @@ extension SnapshotTests {
"""
}
}

@Test func comparisonOptional() async throws {
assertInlineSnapshot(of: Row.columns.a.lt(0), as: .sql) {
"""
("rows"."a" < 0)
"""
}
assertInlineSnapshot(of: Row.columns.a.lte(0), as: .sql) {
"""
("rows"."a" <= 0)
"""
}
assertInlineSnapshot(of: Row.columns.a.gt(0), as: .sql) {
"""
("rows"."a" > 0)
"""
}
assertInlineSnapshot(of: Row.columns.a.gte(0), as: .sql) {
"""
("rows"."a" >= 0)
"""
}
assertInlineSnapshot(of: Row.columns.a < 0, as: .sql) {
"""
("rows"."a" < 0)
"""
}
assertInlineSnapshot(of: Row.columns.a <= 0, as: .sql) {
"""
("rows"."a" <= 0)
"""
}
assertInlineSnapshot(of: Row.columns.a > 0, as: .sql) {
"""
("rows"."a" > 0)
"""
}
assertInlineSnapshot(of: Row.columns.a >= 0, as: .sql) {
"""
("rows"."a" >= 0)
"""
}
}

@Test func logic() {
assertInlineSnapshot(of: Row.columns.bool && Row.columns.bool, as: .sql) {
Expand Down