swift定义iOS数据库框架4——插入数据(增)

swift定义iOS数据库框架4——插入数据(增),第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中提供可选类型:扩展系统Optional2、在Setter文件中新增可选类型运算符重载,同时在Setter结构体中也需要添加构造方法重载3、给我TableBuilder添加可选类型

插入流程

非空类型 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("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
    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类型->对应的->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)
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/996441.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存