Forked from
pointfreeco/swift-structured-queries, by way ofcoenttb/swift-structured-queries-postgres.
Type-safe, composable SQL query building whose Swift API reads like the SQL it generates — SELECT, INSERT, UPDATE, DELETE, joins, common table expressions, and safe raw-SQL escapes, without an ORM's query language to learn.
- Bindings separated from SQL text —
QueryFragmenttracks raw SQL segments and bound values independently, so interpolating a Swift value never risks SQL injection the way naive string concatenation does. - Type-safe statement building —
Table,Select,Insert,Update,Delete, andCTEcompose into full statements whose column references are checked against the table's declaredTableColumnsat compile time. - Typed query bindings and decoding —
QueryBindingmodels every bindable SQL value (text, int, bool, double, date, UUID, decimal, arrays,jsonb, …) with a matchingQueryDecoderside for round-tripping results back into Swift types viaQueryRepresentable. Taggedintegration — phantom-typed wrappers fromswift-tagged-primitivesconform toQueryBindable,QueryDecodable,QueryExpression, andQueryRepresentabledirectly, so aTagged<UserID.Tag, Int>primary key binds and decodes exactly like itsUnderlyingtype.- Views and window functions —
Views,WindowSpec, andFrameClausecover SQL surfaces beyond basic CRUD.
QueryFragment is this package's building block: it separates literal SQL text from bound values so that interpolating a Swift value can never smuggle SQL into the query string.
import Structured_Queries_Primitives
// Naive string interpolation risks SQL injection — the value becomes part of the SQL text:
let userInput = "O'Brien"
let unsafe = "SELECT * FROM users WHERE name = '\(userInput)'"
// "SELECT * FROM users WHERE name = 'O'Brien'" -- broken syntax, or worse, injectable
// QueryFragment keeps the value out of the SQL text as a separate binding:
let name = "O'Brien"
let fragment: QueryFragment = "SELECT * FROM \(quote: "users") WHERE name = \(name.queryBinding)"
let (sql, bindings) = fragment.prepare { offset in "$\(offset)" }
// sql: SELECT * FROM "users" WHERE name = $1
// bindings: ['O''Brien'] -- QueryBinding.text("O'Brien"), rendered via its debugDescription\(quote:) safely quotes identifiers (table and column names); interpolating a QueryBinding produces a .binding segment rather than splicing the value into the SQL text.
Add the dependency to your Package.swift:
dependencies: [
.package(url: "https://github.com/swift-primitives/swift-structured-queries-primitives.git", branch: "main")
]Add a product to your target:
.target(
name: "App",
dependencies: [
.product(name: "Structured Queries Primitives", package: "swift-structured-queries-primitives")
]
)The package is pre-1.0 — depend on branch: "main" until 0.1.0 is tagged. Requires Swift 6.3 and macOS 26 / iOS 26 / tvOS 26 / watchOS 26 / visionOS 26 (or the corresponding Linux / Windows toolchain).
Important: This package builds type-safe SQL statements; it does not include a database driver or the
@Table/@Selection/#sqlcode-generation macros. It is the runtime core that macro-generatedTableconformances (or hand-written ones, perTableDefinition) target.
| Product | Contents | When to import |
|---|---|---|
Structured Queries Primitives |
QueryFragment, Table, Select/Insert/Update/Delete statements, QueryBinding/QueryDecoder, CTEs, views, window functions |
Building or executing SQL statements |
Structured Queries Primitives Support |
SQL identifier quoting and inflection helpers used internally by QueryFragment |
Rarely imported directly; pulled in transitively |
Structured Queries Primitives Test Support |
Test-only fixtures for exercising Table conformances |
Test targets only |
| Platform | CI | Status |
|---|---|---|
| macOS 26 | Yes | Full support |
| Linux | Yes | Full support |
| Windows | Yes | Full support |
| iOS/tvOS/watchOS | — | Supported |
| Swift Embedded | — | Pending (nightly-toolchain follow-up) |
swift-tagged-primitives— the phantom-typedTagged<Tag, Underlying>wrapper this package conforms toQueryBindable,QueryDecodable,QueryExpression, andQueryRepresentable.
Discussion thread will be created at first public flip.
Apache 2.0 (Institute) with MIT attribution to the upstream pointfreeco/swift-structured-queries (Copyright (c) 2025 Point-Free, Inc.). The combined-license text — Institute Apache 2.0 + the upstream's preserved MIT block — is in LICENSE.md. MIT requires preservation of the original copyright notice in derivative works; the Institute's Apache 2.0 governs new contributions on top of the fork point.