Skip to content

Commit 671d825

Browse files
committed
refactor: organize quantified comparisons under Subquery namespace
Splits QuantifiedComparison.swift into focused files following namespace pattern: - Subquery.swift: namespace enum + convenience typealiases (SubqueryAny, SubqueryAll, SubquerySome) - Subquery.Any.swift, Subquery.All.swift, Subquery.Some.swift: individual quantifier implementations - Subquery+Extensions.swift: comparison methods and convenience functions Uses backtick escaping for Swift keyword conflicts (`Any`, `All`, `Some`) while maintaining clean API names. Convenience typealiases provided for external consumers, but internal code uses canonical backticked names. Follows PostgreSQL §9.24 (Subquery Expressions) structure.
1 parent 5ba13c1 commit 671d825

File tree

5 files changed

+112
-82
lines changed

5 files changed

+112
-82
lines changed

Sources/StructuredQueriesPostgres/Functions/SubqueryExpressions/QuantifiedComparison.swift renamed to Sources/StructuredQueriesPostgres/Functions/SubqueryExpressions/Subquery+Extensions.swift

Lines changed: 6 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,6 @@
11
import Foundation
22
import StructuredQueriesCore
33

4-
// MARK: - PostgreSQL Quantified Comparison Operators
5-
//
6-
// PostgreSQL Chapter 9.24: Subquery Expressions
7-
// https://www.postgresql.org/docs/18/functions-subquery.html
8-
//
9-
// Quantified comparison operators for comparing a value against a set of values from a subquery.
10-
// Syntax: expression operator ANY/ALL/SOME (subquery)
11-
12-
// MARK: - ANY Operator
13-
14-
/// Wrapper for ANY quantified comparison
15-
///
16-
/// PostgreSQL's ANY operator returns true if the comparison is true for any value in the subquery.
17-
///
18-
/// ```swift
19-
/// Product.where { $0.price < .any(competitorPrices) }
20-
/// // SELECT … FROM "products" WHERE "products"."price" < ANY (SELECT price FROM competitors)
21-
/// ```
22-
public struct AnyQuantifier<Value: QueryBindable>: QueryExpression {
23-
public typealias QueryValue = Value
24-
25-
public let queryFragment: QueryFragment
26-
27-
public init<Q: QueryExpression>(_ subquery: Q) where Q.QueryValue == [Value] {
28-
self.queryFragment = "ANY (\(subquery.queryFragment))"
29-
}
30-
31-
public init(_ subquery: QueryFragment) {
32-
self.queryFragment = "ANY (\(subquery))"
33-
}
34-
}
35-
36-
/// Wrapper for ALL quantified comparison
37-
///
38-
/// PostgreSQL's ALL operator returns true if the comparison is true for all values in the subquery.
39-
///
40-
/// ```swift
41-
/// User.where { $0.score > .all(teamScores) }
42-
/// // SELECT … FROM "users" WHERE "users"."score" > ALL (SELECT score FROM team_members)
43-
/// ```
44-
public struct AllQuantifier<Value: QueryBindable>: QueryExpression {
45-
public typealias QueryValue = Value
46-
47-
public let queryFragment: QueryFragment
48-
49-
public init<Q: QueryExpression>(_ subquery: Q) where Q.QueryValue == [Value] {
50-
self.queryFragment = "ALL (\(subquery.queryFragment))"
51-
}
52-
53-
public init(_ subquery: QueryFragment) {
54-
self.queryFragment = "ALL (\(subquery))"
55-
}
56-
}
57-
58-
/// Wrapper for SOME quantified comparison (synonym for ANY)
59-
///
60-
/// PostgreSQL's SOME operator is a synonym for ANY.
61-
///
62-
/// ```swift
63-
/// Product.where { $0.price < .some(competitorPrices) }
64-
/// // SELECT … FROM "products" WHERE "products"."price" < SOME (SELECT price FROM competitors)
65-
/// ```
66-
public struct SomeQuantifier<Value: QueryBindable>: QueryExpression {
67-
public typealias QueryValue = Value
68-
69-
public let queryFragment: QueryFragment
70-
71-
public init<Q: QueryExpression>(_ subquery: Q) where Q.QueryValue == [Value] {
72-
self.queryFragment = "SOME (\(subquery.queryFragment))"
73-
}
74-
75-
public init(_ subquery: QueryFragment) {
76-
self.queryFragment = "SOME (\(subquery))"
77-
}
78-
}
79-
804
// MARK: - Quantified Comparison Extensions
815

826
extension QueryExpression where QueryValue: Comparable & QueryBindable {
@@ -315,9 +239,9 @@ extension QueryExpression where QueryValue: Equatable & QueryBindable {
315239
/// Product.where { $0.price < any(competitorPrices) }
316240
/// // WHERE "products"."price" < ANY (SELECT price FROM competitors)
317241
/// ```
318-
public func any<Value: QueryBindable, Q: QueryExpression>(_ subquery: Q) -> AnyQuantifier<Value>
242+
public func any<Value: QueryBindable, Q: QueryExpression>(_ subquery: Q) -> Subquery.`Any`<Value>
319243
where Q.QueryValue == [Value] {
320-
AnyQuantifier(subquery)
244+
Subquery.`Any`(subquery)
321245
}
322246

323247
/// Creates an ALL quantifier from a subquery
@@ -326,9 +250,9 @@ where Q.QueryValue == [Value] {
326250
/// User.where { $0.score > all(teamScores) }
327251
/// // WHERE "users"."score" > ALL (SELECT score FROM team_members)
328252
/// ```
329-
public func all<Value: QueryBindable, Q: QueryExpression>(_ subquery: Q) -> AllQuantifier<Value>
253+
public func all<Value: QueryBindable, Q: QueryExpression>(_ subquery: Q) -> Subquery.`All`<Value>
330254
where Q.QueryValue == [Value] {
331-
AllQuantifier(subquery)
255+
Subquery.`All`(subquery)
332256
}
333257

334258
/// Creates a SOME quantifier from a subquery (synonym for ANY)
@@ -337,7 +261,7 @@ where Q.QueryValue == [Value] {
337261
/// Product.where { $0.price < some(competitorPrices) }
338262
/// // WHERE "products"."price" < SOME (SELECT price FROM competitors)
339263
/// ```
340-
public func some<Value: QueryBindable, Q: QueryExpression>(_ subquery: Q) -> SomeQuantifier<Value>
264+
public func some<Value: QueryBindable, Q: QueryExpression>(_ subquery: Q) -> Subquery.`Some`<Value>
341265
where Q.QueryValue == [Value] {
342-
SomeQuantifier(subquery)
266+
Subquery.`Some`(subquery)
343267
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import Foundation
2+
import StructuredQueriesCore
3+
4+
extension Subquery {
5+
/// Wrapper for ALL quantified comparison
6+
///
7+
/// PostgreSQL's ALL operator returns true if the comparison is true for all values in the subquery.
8+
///
9+
/// ```swift
10+
/// User.where { $0.score > .all(teamScores) }
11+
/// // SELECT … FROM "users" WHERE "users"."score" > ALL (SELECT score FROM team_members)
12+
/// ```
13+
public struct `All`<Value: QueryBindable>: QueryExpression {
14+
public typealias QueryValue = Value
15+
16+
public let queryFragment: QueryFragment
17+
18+
public init<Q: QueryExpression>(_ subquery: Q) where Q.QueryValue == [Value] {
19+
self.queryFragment = "ALL (\(subquery.queryFragment))"
20+
}
21+
22+
public init(_ subquery: QueryFragment) {
23+
self.queryFragment = "ALL (\(subquery))"
24+
}
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import Foundation
2+
import StructuredQueriesCore
3+
4+
extension Subquery {
5+
/// Wrapper for ANY quantified comparison
6+
///
7+
/// PostgreSQL's ANY operator returns true if the comparison is true for any value in the subquery.
8+
///
9+
/// ```swift
10+
/// Product.where { $0.price < .any(competitorPrices) }
11+
/// // SELECT … FROM "products" WHERE "products"."price" < ANY (SELECT price FROM competitors)
12+
/// ```
13+
public struct `Any`<Value: QueryBindable>: QueryExpression {
14+
public typealias QueryValue = Value
15+
16+
public let queryFragment: QueryFragment
17+
18+
public init<Q: QueryExpression>(_ subquery: Q) where Q.QueryValue == [Value] {
19+
self.queryFragment = "ANY (\(subquery.queryFragment))"
20+
}
21+
22+
public init(_ subquery: QueryFragment) {
23+
self.queryFragment = "ANY (\(subquery))"
24+
}
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import Foundation
2+
import StructuredQueriesCore
3+
4+
extension Subquery {
5+
/// Wrapper for SOME quantified comparison (synonym for ANY)
6+
///
7+
/// PostgreSQL's SOME operator is a synonym for ANY.
8+
///
9+
/// ```swift
10+
/// Product.where { $0.price < .some(competitorPrices) }
11+
/// // SELECT … FROM "products" WHERE "products"."price" < SOME (SELECT price FROM competitors)
12+
/// ```
13+
public struct `Some`<Value: QueryBindable>: QueryExpression {
14+
public typealias QueryValue = Value
15+
16+
public let queryFragment: QueryFragment
17+
18+
public init<Q: QueryExpression>(_ subquery: Q) where Q.QueryValue == [Value] {
19+
self.queryFragment = "SOME (\(subquery.queryFragment))"
20+
}
21+
22+
public init(_ subquery: QueryFragment) {
23+
self.queryFragment = "SOME (\(subquery))"
24+
}
25+
}
26+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Foundation
2+
import StructuredQueriesCore
3+
4+
// MARK: - PostgreSQL Subquery Expressions
5+
//
6+
// PostgreSQL Chapter 9.24: Subquery Expressions
7+
// https://www.postgresql.org/docs/current/functions-subquery.html
8+
//
9+
// Quantified comparison operators for comparing a value against a set of values from a subquery.
10+
// Syntax: expression operator ANY/ALL/SOME (subquery)
11+
12+
/// Namespace for PostgreSQL subquery expression types.
13+
///
14+
/// Contains quantified comparison operators (ANY, ALL, SOME) for subquery operations.
15+
///
16+
/// See <doc:SubqueryExpressions> for more information.
17+
public enum Subquery {}
18+
19+
// MARK: - Convenience Typealiases
20+
21+
/// Convenience typealias for `Subquery.`Any`<Value>`
22+
public typealias SubqueryAny<Value: QueryBindable> = Subquery.`Any`<Value>
23+
24+
/// Convenience typealias for `Subquery.`All`<Value>`
25+
public typealias SubqueryAll<Value: QueryBindable> = Subquery.`All`<Value>
26+
27+
/// Convenience typealias for `Subquery.`Some`<Value>`
28+
public typealias SubquerySome<Value: QueryBindable> = Subquery.`Some`<Value>

0 commit comments

Comments
 (0)