Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Sources/StructuredQueries/Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@ public macro Table(
/// - name: The column's name. Defaults to the property's name, _e.g._ 'id' becomes `"id"`.
/// - representableType: A type that represents the property type in a query expression. For types
/// that don't have a single representation in SQL, like `Date` and `UUID`.
/// - generated: Allows to declare the column as a read-only database computed column, making it
/// available for queries but not for updates.
/// - primaryKey: The column is its table's auto-incrementing primary key.
@attached(peer)
public macro Column(
_ name: String = "",
as representableType: (any QueryRepresentable.Type)? = nil,
generated: GeneratedColumn? = nil,
primaryKey: Bool = false
) =
#externalMacro(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ that represent those database definitions.
* [Default representations for dates and UUIDs](#Default-representations-for-dates-and-UUIDs)
* [Primary keyed tables](#Primary-keyed-tables)
* [Ephemeral columns](#Ephemeral-columns)
* [Generated columns](#Generated-columns)
* [Table definition tools](#Table-definition-tools)

### Defining a table
Expand Down Expand Up @@ -447,6 +448,31 @@ struct Book {
}
```

### Generated columns

Some databases, including SQLite, support [generated columns](https://www.sqlite.org/gencol.html),
which are columns whose values are computed from other columns in the same row. Since these columns
are read-only from an application's perspective, they should be included in `SELECT` statements but
excluded from `INSERT` or `UPDATE` statements.

You can mark a property as a generated column by using the `generated` parameter of the `@Column`
macro with a value of `.stored` or `.virtual`. This ensures the property is decoded when
fetching data but is not included in the `Draft` type used for creating or updating records.

For example, if your database computes a stored `endAt` timestamp, you can model it like this:

```swift
@Table
struct Event {
let id: UUID
var startAt: Date
var duration: TimeInterval

@Column(generated: .stored)
var endAt: Date
}
```

### Table definition tools

This library does not come with any tools for actually constructing table definition queries,
Expand Down
12 changes: 12 additions & 0 deletions Sources/StructuredQueriesCore/TableColumn.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,15 @@ where Value.QueryOutput: Sendable {
)
}
}

/// A type that describes how a table column is generated (e.g. SQLite generated columns).
///
/// You provide a value of this type to a `@Column` macro to differentiate between generated columns
/// that are physically stored in the database table and those that are "virtual".
///
/// ```swift
/// @Column(generated: .stored)
/// ```
public enum GeneratedColumn {
case virtual, stored
}
Loading