一切都应尽可能简单,但不能过于简单。
—阿尔伯特·爱因斯坦
Skull Swift 包 为 SQLite 提供了一个极其精简 (400 行代码) 的接口。它强调简洁性,其同步 API 实现了一组最少的功能,用于与 SQLite 交互。
import Foundation
import Skull
let skull: DispatchQueue = DispatchQueue(label: "ink.codes.skull")
let db = skull.sync {
return try! Skull()
}
skull.async {
let sql = "create table planets (id integer primary key, au double, name text);"
try! db.exec(sql)
}
skull.async {
let sql = "insert into planets values (?, ?, ?);"
try! db.update(sql, 0, 0.4, "Mercury")
try! db.update(sql, 1, 0.7, "Venus")
try! db.update(sql, 2, 1, "Earth")
try! db.update(sql, 3, 1.5, "Mars")
}
skull.sync {
let sql = "select name from planets where au=1;"
try! db.query(sql) { er, row in
assert(er == nil)
let name = row?["name"] as! String
assert(name == "Earth")
print(name)
return 0
}
}
Skull 被刻意设计得很轻量,其微小的 API 将访问序列化留给用户处理。如上例所示,利用专用的串行队列可以直观地确保序列化访问。
enum SkullError: Error
SkullError
枚举了显式错误。
alreadyOpen(String) (已打开(String))
failedToFinalize(Array<Error>) (终结失败(Error 数组))
invalidURL (无效 URL)
notOpen (未打开)
sqliteError(Int, String) (SQLite 错误(Int, String))
sqliteMessage(String) (SQLite 消息(String))
unsupportedType (不支持的类型)
typealias SkullRow = Dictionary<String, Any>
SkullRow
模拟 SQLite 表中的一个 row
(行)。作为一个 Dictionary
(字典),它提供对列值的下标访问,列值可以是以下三种基本类型
String (字符串)
Int (整数)
Double (双精度浮点数)
例如
row["a"] as String == "500.0"
row["b"] as Int == 500
row["c"] as Double == 500.0
class Skull: SQLDatabase
Skull
,本模块的主要对象,代表一个 SQLite 数据库连接。它采用了 SQLDatabase
协议,该协议定义了其接口
protocol SQLDatabase {
var url: URL? { get }
func flush() throws
func exec(_ sql: String, cb: @escaping (SkullError?, [String : String]) -> Int) throws
func query(_ sql: String, cb: (SkullError?, SkullRow?) -> Int) throws
func update(_ sql: String, _ params: Any?...) throws
}
要打开数据库连接,您需要初始化一个新的 Skull
对象。
init(_ url: URL? = nil) throws
url
要打开的数据库文件的位置。打开位于文件 url
的数据库。如果该文件不存在,则会创建它。跳过 url
或传递 nil
将打开一个内存数据库。
代表数据库连接的 Skull
对象,提供以下方法来访问数据库。
func exec(sql: String, cb: ((SkullError?, [String:String]) -> Int)?)) throws
sql
零个或多个 UTF-8 编码的、以分号分隔的 SQL 语句。cb
用于处理结果或通过返回非零值来中止的回调。执行 SQL 语句并为每个结果应用回调,在本例中仅限于字符串。回调是可选的,如果提供,它可以返回非零值来中止执行。回调不仅处理结果,还可以监控执行,并在必要时中止操作;它会被应用零次或多次。
func query(sql: String, cb: (SkullError?, SkullRow?) -> Int) throws
sql
用于查询数据库的 SQL 语句。cb
用于处理结果错误和行的回调。使用指定的选择性 SQL 语句查询数据库,并为每个结果行或发生的错误应用回调。
func update(sql: String, params: Any?...) throws
sql
要应用的 SQL 语句。params
要绑定到语句的参数。通过将指定的参数绑定到 SQLite 语句来更新数据库,例如
let sql = "insert into planets values (?, ?, ?);"
try! db.update(sql, 0, 0.4, "Mercury")
此方法可能会抛出 SkullError.sqliteError(Int, String)
或 SkullError.unsupportedType
。
func flush() throws
移除并终结所有缓存的预处理语句。
var url: URL? { get }
数据库文件的位置。
只需释放 Skull
对象即可关闭数据库。
📦 将 https://github.com/michaelnisi/skull
添加到您的 Package Manifest。