Skip to content

Instantly share code, notes, and snippets.

@mortenbekditlevsen
Created October 19, 2021 12:24
Show Gist options
  • Save mortenbekditlevsen/9cd48ca0b0d2b1d4ceda9332b6645a3a to your computer and use it in GitHub Desktop.
Save mortenbekditlevsen/9cd48ca0b0d2b1d4ceda9332b6645a3a to your computer and use it in GitHub Desktop.
enum QueryPredicate {
case isEqualTo(_ field: String, _ value: Any)
case isNotEqualTo(_ field: String, _ value: Any)
case isIn(_ field: String, _ values: [Any])
case isNotIn(_ field: String, _ values: [Any])
case arrayContains(_ field: String, _ value: Any)
case arrayContainsAny(_ field: String, _ values: [Any])
case isLessThan(_ field: String, _ value: Any)
case isGreaterThan(_ field: String, _ value: Any)
case isLessThanOrEqualTo(_ field: String, _ value: Any)
case isGreaterThanOrEqualTo(_ field: String, _ value: Any)
case orderBy(_ field: String, _ value: Bool)
case limitTo(_ value: Int)
case limitToLast(_ value: Int)
}
public struct Query {
}
struct Predicate<
ArrayContains,
InAndFriends,
Inequality,
OrderBy>
where
ArrayContains: QueryApplication,
InAndFriends: QueryApplication,
Inequality: QueryApplication,
OrderBy: QueryApplication {
private var predicates: [QueryPredicate]
private var inequalityField: String?
func evaluate(_ query: Query) -> Query {
// TODO: Actually modify query with predicates
query
}
}
protocol QueryApplication {}
enum Applied: QueryApplication {}
enum NotApplied: QueryApplication {}
extension Predicate where ArrayContains == NotApplied,
InAndFriends == NotApplied,
Inequality == NotApplied,
OrderBy == NotApplied {
static func isEqualTo(_ field: String, _ value: Any) -> Predicate<NotApplied, NotApplied, NotApplied, NotApplied> {
.init(predicates: [.isEqualTo(field, value)], inequalityField: nil)
}
}
extension Predicate where ArrayContains == NotApplied,
InAndFriends == NotApplied,
Inequality == Applied,
OrderBy == NotApplied {
static func isGreaterThan(_ field: String, _ value: Any) -> Predicate<NotApplied, NotApplied, Applied, NotApplied> {
.init(predicates: [.isGreaterThan(field, value)], inequalityField: field)
}
static func isGreaterThanOrEqualTo(_ field: String, _ value: Any) -> Predicate<NotApplied, NotApplied, Applied, NotApplied> {
.init(predicates: [.isGreaterThanOrEqualTo(field, value)], inequalityField: field)
}
static func isLessThan(_ field: String, _ value: Any) -> Predicate<NotApplied, NotApplied, Applied, NotApplied> {
.init(predicates: [.isLessThan(field, value)], inequalityField: field)
}
static func isLessThanOrEqualTo(_ field: String, _ value: Any) -> Predicate<NotApplied, NotApplied, Applied, NotApplied> {
.init(predicates: [.isLessThanOrEqualTo(field, value)], inequalityField: field)
}
static func isNotEqualTo(_ field: String, _ value: Any) -> Predicate<NotApplied, NotApplied, Applied, NotApplied> {
.init(predicates: [.isNotEqualTo(field, value)], inequalityField: field)
}
}
extension Predicate where OrderBy == NotApplied {
func isEqualTo(_ field: String, _ value: Any) -> Predicate<ArrayContains, InAndFriends, Inequality, OrderBy> {
.init(predicates: [.isEqualTo(field, value)], inequalityField: inequalityField)
}
}
extension Predicate where ArrayContains == NotApplied, OrderBy == NotApplied {
func arrayContains(_ field: String, _ value: Any) -> Predicate<Applied, InAndFriends, Inequality, OrderBy> {
.init(predicates: self.predicates + [.arrayContains(field, value)], inequalityField: inequalityField)
}
}
extension Predicate where ArrayContains == NotApplied, InAndFriends == NotApplied, OrderBy == NotApplied {
func arrayContainsAny(_ field: String, _ values: [Any]) -> Predicate<ArrayContains, Applied, Inequality, OrderBy> {
.init(predicates: self.predicates + [.arrayContainsAny(field, values)], inequalityField: inequalityField)
}
}
extension Predicate where Inequality == NotApplied, OrderBy == NotApplied {
func isLessThan(_ field: String, _ value: Any) -> Predicate<ArrayContains, InAndFriends, Applied, OrderBy> {
.init(predicates: self.predicates + [.isLessThan(field, value)], inequalityField: field)
}
func isGreaterThan(_ field: String, _ value: Any) -> Predicate<ArrayContains, InAndFriends, Applied, OrderBy> {
.init(predicates: [.isGreaterThan(field, value)], inequalityField: field)
}
func isGreaterThanOrEqualTo(_ field: String, _ value: Any) -> Predicate<ArrayContains, InAndFriends, Applied, OrderBy> {
.init(predicates: [.isGreaterThanOrEqualTo(field, value)], inequalityField: field)
}
func isLessThanOrEqualTo(_ field: String, _ value: Any) -> Predicate<ArrayContains, InAndFriends, Applied, OrderBy> {
.init(predicates: [.isLessThanOrEqualTo(field, value)], inequalityField: field)
}
func isNotEqualTo(_ field: String, _ value: Any) -> Predicate<ArrayContains, InAndFriends, Applied, OrderBy> {
.init(predicates: [.isNotEqualTo(field, value)], inequalityField: field)
}
}
extension Predicate where Inequality == Applied, OrderBy == NotApplied {
func andGreaterThan(_ value: Any) -> Predicate<ArrayContains, InAndFriends, Applied, OrderBy> {
.init(predicates: self.predicates + [.isGreaterThan(inequalityField!, value)], inequalityField: inequalityField!)
}
func andLessThan(_ value: Any) -> Predicate<ArrayContains, InAndFriends, Applied, OrderBy> {
.init(predicates: self.predicates + [.isLessThan(inequalityField!, value)], inequalityField: inequalityField)
}
func andGreaterThanOrEqualTo(_ value: Any) -> Predicate<ArrayContains, InAndFriends, Applied, OrderBy> {
.init(predicates: [.isGreaterThanOrEqualTo(inequalityField!, value)], inequalityField: inequalityField)
}
func andLessThanOrEqualTo(_ value: Any) -> Predicate<ArrayContains, InAndFriends, Applied, OrderBy> {
.init(predicates: [.isLessThanOrEqualTo(inequalityField!, value)], inequalityField: inequalityField)
}
func andNotEqualTo(_ value: Any) -> Predicate<ArrayContains, InAndFriends, Applied, OrderBy> {
.init(predicates: [.isNotEqualTo(inequalityField!, value)], inequalityField: inequalityField)
}
}
extension Predicate where InAndFriends == NotApplied, OrderBy == NotApplied, Inequality == Applied {
func andNotIn(_ values: [Any]) -> Predicate<ArrayContains, Applied, Applied, OrderBy> {
.init(predicates: self.predicates + [.isNotIn(inequalityField!, values)], inequalityField: inequalityField)
}
}
extension Predicate where InAndFriends == NotApplied, OrderBy == NotApplied, Inequality == NotApplied {
func isIn(_ field: String, _ values: [Any]) -> Predicate<ArrayContains, Applied, Inequality, OrderBy> {
.init(predicates: self.predicates + [.isIn(field, values)], inequalityField: inequalityField)
}
func isNotIn(_ field: String, _ values: [Any]) -> Predicate<ArrayContains, Applied, Applied, OrderBy> {
.init(predicates: self.predicates + [.isNotIn(field, values)], inequalityField: field)
}
}
extension Predicate where OrderBy == Applied, Inequality == Applied {
func orderBy(_ field: String, _ descending: Bool) -> Predicate<ArrayContains, InAndFriends, Applied, Applied> {
.init(predicates: predicates + [.orderBy(field, descending)], inequalityField: inequalityField)
}
}
extension Predicate where OrderBy == Applied, Inequality == NotApplied {
func orderBy(_ field: String, _ descending: Bool) -> Predicate<ArrayContains, InAndFriends, NotApplied, Applied> {
.init(predicates: predicates + [.orderBy(field, descending)], inequalityField: inequalityField)
}
}
extension Predicate where OrderBy == NotApplied, Inequality == NotApplied {
func orderBy(_ field: String, _ descending: Bool) -> Predicate<ArrayContains, InAndFriends, NotApplied, Applied> {
.init(predicates: predicates + [.orderBy(field, descending)], inequalityField: inequalityField)
}
}
extension Predicate where OrderBy == NotApplied, Inequality == Applied {
func order(_ descending: Bool) -> Predicate<ArrayContains, InAndFriends, Applied, Applied> {
.init(predicates: predicates + [.orderBy(inequalityField!, descending)], inequalityField: inequalityField)
}
}
let a = Predicate.isEqualTo("state", "CA")
.isNotIn("population", [23, 24])
.andLessThan(4)
.andGreaterThan(2)
.andNotEqualTo(3)
.isEqualTo("by_the_ocean", true)
.order(false)
.orderBy("a", true)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment