Swift DSL for writing SQL statements.

What's New

Statement 0.7.1


Updates the SQLite implementation to generate a sqliteArgument for Data types that include single quotes.


Swift DSL for writing SQL statements.

Twitter: @richardpiazza

Using Swift to write SQL 🤯

let expressionId: Int = 123
let languageCode: LanguageCode? = .en
let regionCode: RegionCode? = .us

let statement = SQLiteStatement(
            .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))

The first part of the statement is rather clear:

SELECT, translation.expression_id, translation.language_code, translation.region_code, translation.value
FROM translation

But take a closer look at the elements provided in the .AND block. The languageCode & regionCode are both optionals, and there is an additional logical element clause when one is nil. With all of the optionals and logic, there is a possibility of producing 4 separate where clauses.

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'

Type-Safe Magic

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
    var language: String = LanguageCode.default.rawValue

    /// Region code specifier
    var region: String? = nil

    /// The translated string
    var value: String = ""

Automagical Epoxy

Using the Swift reflection api Mirror, the @Field property's are automatically synthesized.

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 {
            } else if let column = child.value as? Attribute {
        return _columns


Statement is distributed using the Swift Package Manager. To install it into a project, add it as a dependency within your Package.swift manifest:

let package = Package(
    dependencies: [
        .package(url: "", .upToNextMinor(from: "0.6.0")

Then import the Statement packages wherever you'd like to use it:

import Statement


  • Swift Tools 5.3.0
View More Packages from this Author


  • None
Last updated: Wed Nov 09 2022 04:30:27 GMT-0500 (GMT-05:00)