IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> swift定义iOS数据库框架4 -> 正文阅读

[移动开发]swift定义iOS数据库框架4

插入流程

请添加图片描述

非空类型

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)
    }
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 21:02:21  更:2022-03-21 21:03:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 19:10:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码