Skip to content

Commit a1ed3ce

Browse files
committed
add public table name, add where not in query
1 parent 70fb7af commit a1ed3ce

File tree

4 files changed

+42
-2
lines changed

4 files changed

+42
-2
lines changed

Sources/SQLite/Helpers.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ extension String {
8888
return "\(self) ".wrap(expressions) as Expression<Void>
8989
}
9090

91-
func wrap<T>(_ expression: Expressible) -> Expression<T> {
91+
public func wrap<T>(_ expression: Expressible) -> Expression<T> {
9292
return Expression("\(self)(\(expression.expression.template))", expression.expression.bindings)
9393
}
9494

95-
func wrap<T>(_ expressions: [Expressible]) -> Expression<T> {
95+
public func wrap<T>(_ expressions: [Expressible]) -> Expression<T> {
9696
return wrap(", ".join(expressions))
9797
}
9898

Sources/SQLite/Typed/CoreFunctions.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ private enum Function: String {
4040
case substr
4141
case like = "LIKE"
4242
case `in` = "IN"
43+
case notIn = "NOT IN"
4344
case glob = "GLOB"
4445
case match = "MATCH"
4546
case regexp = "REGEXP"
@@ -704,6 +705,38 @@ extension Collection where Iterator.Element : Value {
704705
let templates = [String](repeating: "?", count: count).joined(separator: ", ")
705706
return Function.in.infix(expression, Expression<Void>("(\(templates))", map { $0.datatypeValue }))
706707
}
708+
709+
/// Builds a copy of the expression prepended with an `NOT IN` check against the
710+
/// collection.
711+
///
712+
/// let name = Expression<String>("name")
713+
/// ["alice", "betty"].containsNot(name)
714+
/// // "name" NOT IN ('alice', 'betty')
715+
///
716+
/// - Parameter pattern: A pattern to match.
717+
///
718+
/// - Returns: A copy of the expression prepended with an `NOT IN` check against
719+
/// the collection.
720+
public func containsNot(_ expression: Expression<Iterator.Element>) -> Expression<Bool> {
721+
let templates = [String](repeating: "?", count: count).joined(separator: ", ")
722+
return Function.notIn.infix(expression, Expression<Void>("(\(templates))", map { $0.datatypeValue }))
723+
}
724+
725+
/// Builds a copy of the expression prepended with an `NOT IN` check against the
726+
/// collection.
727+
///
728+
/// let name = Expression<String>("name")
729+
/// ["alice", "betty"].containsNot(name)
730+
/// // "name" NOT IN ('alice', 'betty')
731+
///
732+
/// - Parameter pattern: A pattern to match.
733+
///
734+
/// - Returns: A copy of the expression prepended with an `NOT IN` check against
735+
/// the collection.
736+
public func containsNot(_ expression: Expression<Iterator.Element?>) -> Expression<Bool?> {
737+
let templates = [String](repeating: "?", count: count).joined(separator: ", ")
738+
return Function.notIn.infix(expression, Expression<Void>("(\(templates))", map { $0.datatypeValue }))
739+
}
707740

708741
}
709742

Sources/SQLite/Typed/Query.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,10 +801,12 @@ extension QueryType {
801801
public struct Table : SchemaType {
802802

803803
public static let identifier = "TABLE"
804+
public let name: String
804805

805806
public var clauses: QueryClauses
806807

807808
public init(_ name: String, database: String? = nil) {
809+
self.name = name
808810
clauses = QueryClauses(name, alias: nil, database: database)
809811
}
810812

Tests/SQLiteTests/CoreFunctionsTests.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,5 +141,10 @@ class CoreFunctionsTests : XCTestCase {
141141
AssertSQL("(\"string\" IN ('hello', 'world'))", ["hello", "world"].contains(string))
142142
AssertSQL("(\"stringOptional\" IN ('hello', 'world'))", ["hello", "world"].contains(stringOptional))
143143
}
144+
145+
func test_contains_buildsExpressionWithNotInOperator() {
146+
AssertSQL("(\"string\" NOT IN ('hello', 'world'))", ["hello", "world"].containsNot(string))
147+
AssertSQL("(\"stringOptional\" NOT IN ('hello', 'world'))", ["hello", "world"].containsNot(stringOptional))
148+
}
144149

145150
}

0 commit comments

Comments
 (0)