插入流程
非空类型
1、新增一个Setter文件
1.1 自定义运算符:分析赋值原理,
let insert = users.insert(id <- "1", name <- "NSLog", email <- "nslog@qq.com", phone <- nil)
try! db.run(insert)
注意:"<- "调用的一个方法:<- 运算符重载函数,插入对象数据
Swift 2.0写法
infix operator <- {
associativity none
precedence 130
}
Swift3.0写法 precedencegroup:表示运算符优先级组,例如 自定义运算符: “<- ” 系统运算符: -、+、/、… 系统原生运算符有优先级: (/、)->高,(-、+)->低
precedencegroup ColumnAssignment {
associativity: left
assignment: true
lowerThan: AssignmentPrecedence
}
infix operator <- : ColumnAssignment
可将这些统一定义在Setter文件中
infix operator || : LogicalDisjunctionPrecedence
infix operator && : LogicalConjunctionPrecedence
infix operator < : ComparisonPrecedence
infix operator <= : ComparisonPrecedence
infix operator > : ComparisonPrecedence
infix operator >= : ComparisonPrecedence
infix operator == : ComparisonPrecedence
infix operator != : ComparisonPrecedence
infix operator === : ComparisonPrecedence
infix operator !== : ComparisonPrecedence
infix operator ~= : ComparisonPrecedence
infix operator ?? : NilCoalescingPrecedence
infix operator + : AdditionPrecedence
infix operator - : AdditionPrecedence
infix operator &+ : AdditionPrecedence
infix operator &- : AdditionPrecedence
infix operator | : AdditionPrecedence
infix operator ^ : AdditionPrecedence
infix operator * : MultiplicationPrecedence
infix operator / : MultiplicationPrecedence
infix operator % : MultiplicationPrecedence
infix operator &* : MultiplicationPrecedence
infix operator & : MultiplicationPrecedence
infix operator << : BitwiseShiftPrecedence
infix operator >> : BitwiseShiftPrecedence
infix operator ..< : RangeFormationPrecedence
infix operator ... : RangeFormationPrecedence
infix operator *= : AssignmentPrecedence
infix operator /= : AssignmentPrecedence
infix operator %= : AssignmentPrecedence
infix operator += : AssignmentPrecedence
infix operator -= : AssignmentPrecedence
infix operator <<= : AssignmentPrecedence
infix operator >>= : AssignmentPrecedence
infix operator &= : AssignmentPrecedence
infix operator ^= : AssignmentPrecedence
infix operator |= : AssignmentPrecedence
1.2 实现运算符重载功能:Setter结构体
public struct Setter {
let column: Expressible
let value: Expressible
fileprivate init<V : Value>(column: Expression<V>, value: Expression<V>) {
self.column = column
self.value = value
}
fileprivate init<V : Value>(column: Expression<V>, value: V) {
self.column = column
self.value = value
}
}
1.3 实现表达式
let name = Expression<String>("name")
let nameValue:Setter = name <- "NSLog"
结果: 在Setter结构体中添加一个拼接方法 SQL语句:insert into t_user values(name = 'NSLog') 拼接结果:name = 'NSLog' 拼接结果得到这个字符串"name = ‘NSLog’" 将对象转为String类型
extension Setter : Expressible {
public var expression: Expression<Void> {
return "=".infix(column, value, wrap: false)
}
}
1.4 在Helper类添加infix拼接方法
SQL插入
func infix<T>(_ lhs: Expressible, _ rhs: Expressible, wrap: Bool = true) -> Expression<T> {
let expression = Expression<T>(" \(self) ".join([lhs, rhs]).expression)
guard wrap else {
return expression
}
return "".wrap(expression)
}
2、在Table中添加insert方法。同时在QueryType中,添加Insert结构体
2.1在Table中添加insert方法
在QueryType,扩展SQL插入
public func insert(_ value: Setter, _ more: Setter...) -> Insert {
return insert([value] + more)
}
fileprivate func insert(_ values: [Setter]) -> Insert {
let insert = values.reduce((columns: [Expressible](), values: [Expressible]())) { insert, setter in
(insert.columns + [setter.column], insert.values + [setter.value])
}
let clauses: [Expressible?] = [
Expression<Void>(literal: "INSERT"),
Expression<Void>(literal: "INTO"),
tableName(),
"".wrap(insert.columns) as Expression<Void>,
Expression<Void>(literal: "VALUES"),
"".wrap(insert.values) as Expression<Void>
]
return Insert(" ".join(clauses.compactMap { $0 }).expression)
}
public func insert() -> Insert {
return Insert(" ".join([
Expression<Void>(literal: "INSERT INTO"),
tableName(),
Expression<Void>(literal: "DEFAULT VALUES")
]).expression)
}
2.2在QueryType中,添加Insert结构体
public struct Insert : ExpressionType {
public var template: String
public var bindings: [Binding?]
public init(_ template: String, _ bindings: [Binding?]) {
self.template = template
self.bindings = bindings
}
}
3、执行SQL语句:提供run方法执行Insert语句
extension Connection {
@discardableResult public func run(_ query: Insert) throws -> Int64 {
let expression = query.expression
return try sync {
try self.run(expression.template, expression.bindings)
return self.lastInsertRowId
}
}
}
Setter中添加运用操作符
public func <-<V : Value>(column: Expression<V>, value: Expression<V>) -> Setter {
return Setter(column: column, value: value)
}
public func <-<V : Value>(column: Expression<V>, value: V) -> Setter {
return Setter(column: column, value: value)
}
可选类型
1、在Helper中提供可选类型:扩展系统Optional
自定义类型协议:泛型设计
public protocol _OptionalType {
associatedtype WrappedType
}
extension Optional : _OptionalType {
public typealias WrappedType = Wrapped
}
2、在Setter文件中新增可选类型运算符重载,同时在Setter结构体中也需要添加构造方法重载
public struct Setter {
...
fileprivate init<V : Value>(column: Expression<V?>, value: Expression<V>) {
self.column = column
self.value = value
}
fileprivate init<V : Value>(column: Expression<V?>, value: Expression<V?>) {
self.column = column
self.value = value
}
fileprivate init<V : Value>(column: Expression<V?>, value: V?) {
self.column = column
self.value = Expression<V?>(value: value)
}
}
public func <-<V : Value>(column: Expression<V?>, value: Expression<V>) -> Setter {
return Setter(column: column, value: value)
}
public func <-<V : Value>(column: Expression<V?>, value: Expression<V?>) -> Setter {
return Setter(column: column, value: value)
}
public func <-<V : Value>(column: Expression<V?>, value: V?) -> Setter {
return Setter(column: column, value: value)
}
问题:到了这一步为啥还是报错? 原因:自定义可选类型没有使用,让我们的自定义表示支持可选类型,目前表达式是不支持可选类型。 解决:在Expression文件中,扩展表达式类型可选类型,即扩展ExpressionType
ExpressionType和系统Optional可以相互转换:强制类型转换 ExpressionType类型可以是可选类型 Expression<String> (String类型->对应的->UnderlyingType) 实际上就是规定Expression->DataType类型->_OptionalType可选类型 UnderlyingType.WrappedType->可选类型协议中具体值->必需是Value子类 规定了DataType类型允许是可选类型,同时类型范围必需是Value子类 高深->运用了面向协议 + 泛型类型 UnderlyingType表示类型可选(可以为nil) WrappedType具体类型,例如:String、Int… 例如:String?,Int?,Double? 1、 UnderlyingType对应:? 2、 WrappedType对应:String 组合1+2:String? 两个约束条件
extension ExpressionType where UnderlyingType : _OptionalType, UnderlyingType.WrappedType : Value {
public static var null: Self {
return self.init(value: nil)
}
public init(value: UnderlyingType.WrappedType?) {
self.init("?", [value?.datatypeValue])
}
}
领悟Swift 泛型精髓 方法:反复看(至少5遍)
3、给我TableBuilder添加可选类型
@discardableResult public func column<V : Value>(_ name: Expression<V?>) -> TableBuilder {
return column(name, V.declaredDatatype)
}
|