用于编写 SQL 语句的 Swift DSL。
let expressionId: Int = 123
let languageCode: LanguageCode? = .en
let regionCode: RegionCode? = .us
let statement = SQLiteStatement(
.SELECT(
.column(Translation["id"]!),
.column(Translation["expression_id"]!),
.column(Translation["language_code"]!),
.column(Translation["region_code"]!),
.column(Translation["value"]!)
),
.FROM_TABLE(Translation.self),
.WHERE(
.AND(
.comparison(Translation.expressionID, .equal(expressionID)),
.unwrap(languageCode, transform: { .comparison(Translation["language_code"]!, .equal($0.rawValue)) }),
.unwrap(regionCode, transform: { .comparison(Translation["region_code"]!, .equal($0.rawValue)) }),
.if(languageCode != nil && regionCode == nil, .logical(Translation.region, .isNull))
)
)
)
statement 的第一部分应该清晰明了
SELECT translation.id, translation.expression_id, translation.language_code, translation.region_code, translation.value
FROM translation
...
但是,请仔细查看 .AND
块中提供的元素。languageCode
和 regionCode
都是可选的,当其中一个为 nil 时,还有一个额外的逻辑元素子句。考虑到所有可选参数和逻辑,有可能生成 4 个独立的 where 子句。
WHERE translation.expression_id = 123
---
WHERE translation.expression_id = 123 AND translation.language_code = 'en' AND translation.region_code IS NULL
---
WHERE translation.expression_id = 123 AND translation.region_code = 'US'
---
WHERE translation.expression_id = 123 AND translation.language_code = 'en' AND translation.region_code = 'US'
struct Translation: Entity, Identifiable {
let tableName: String = "translation"
/// Unique/Primary Key
@Field("id", unique: true, primaryKey: true, autoIncrement: true)
var id: Int = 0
/// Expression (Foreign Key)
@Field("expression_id", foreignKey: .init("expression", "id"))
var expressionID: Expression.ID = 0
/// Language of the translation
@Field("language_code")
var language: String = LanguageCode.default.rawValue
/// Region code specifier
@Field("region_code")
var region: String? = nil
/// The translated string
@Field("value")
var value: String = ""
}
使用 Swift 反射 API Mirror
,@Field
属性会被自动合成。
extension Entity {
var attributes: [Attribute] {
var _columns: [Attribute] = []
let mirror = Mirror(reflecting: self)
for child in mirror.children {
if let column = child.value as? AttributeConvertible {
_columns.append(column.attribute)
} else if let column = child.value as? Attribute {
_columns.append(column)
}
}
return _columns
}
}
Statement 通过 Swift 包管理器 分发。要将其安装到项目中,请将其作为依赖项添加到您的 Package.swift
清单文件中。
let package = Package(
...
dependencies: [
.package(url: "https://github.com/richardpiazza/Statement.git", .upToNextMinor(from: "0.8.0")
],
...
)
然后,在您想要使用它的任何地方导入 Statement 包
import Statement