添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
逼格高的打火机  ·  wsl2 kvm-ok-掘金·  1 年前    · 
八块腹肌的小狗  ·  php - how to parse ...·  1 年前    · 
逼格高的碗  ·  cuda ...·  1 年前    · 



动态操作——SQL插入

  • 插入流程
  • 非空类型
  • 1、新增一个Setter文件
  • 1.1 自定义运算符:分析赋值原理,
  • 1.2 实现运算符重载功能:Setter结构体
  • 1.3 实现表达式
  • 1.4 在Helper类添加infix拼接方法
  • 2、在Table中添加insert方法。同时在QueryType中,添加Insert结构体
  • 2.1在Table中添加insert方法
  • 2.2在QueryType中,添加Insert结构体
  • 3、执行SQL语句:提供run方法执行Insert语句
  • 可选类型
  • 1、在Helper中提供可选类型:扩展系统Optional
  • 2、在Setter文件中新增可选类型运算符重载,同时在Setter结构体中也需要添加构造方法重载
  • 3、给我TableBuilder添加可选类型


插入流程

swift 递增变量名字 swift insert_swift 递增变量名字

非空类型

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 {
    //结合类型:left(左结合)、right(右结合)、none(无)->结合方向
    associativity: left
    //是否是赋值运算符
    //let name = Expression<String>("name")
    //let nameValue:Setter = name <- "NSLog"
    assignment: true
    //指定运算符优先级
    //优先级要低于AssignmentPrecedence类型操作符
    //AssignmentPrecedence->标记优先级
    lowerThan: AssignmentPrecedence
    //AssignmentPrecedence什么意思?
	//在我们iOS系统里面(Swift语言中)
	//1、2、3、4,不用数字表示,用的常量,枚举...(AssignmentPrecedence表示)
//前缀(prefix)、中缀(infix)、后缀(postfix)
//前缀(prefix),例如:++index
//中缀(infix),例如:a + b
//后缀(postfix),例如:index--
//自定义赋值运算符<-属于中缀
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
    //方法重载->方便调用
    //参数一:字段名称
    //参数二:字段对应的值->Expression<V>
    fileprivate init<V : Value>(column: Expression<V>, value: Expression<V>) {
        self.column = column
        self.value = value
    //方法重载->方便调用
    //参数一:字段名称
    //参数二:字段对应的值->V
    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类型

  • 将对象转为String类型
extension Setter : Expressible {
    public var expression: Expression<Void> {
        //拼接->infix中缀
        //column = value
        //其实:name = 'NSLog'
        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])
        //clauses->其实就是SQL语句
        //注意数组顺序不能够写错了,否则拼接结果是错误的
        //INSERT INTO t_user VALUES (name = 'NSLog', sex = '男')
        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>
        //创建结构体
        //compactMap->去除nil值
        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 {
            //执行SQL语句,同时绑定在代码块里面
            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)
                            
jquery语言 jquery-ui

jQuery-UI组件EffectsjQuery UI介绍预设动画方法语法预设动画详解color动画类动画css样式覆盖规则语法jQuery UI介绍 jQuery UI 交互Interactions 小部件Widgets 效果库Effects