@@ -206,6 +206,16 @@ extension Database {
206
206
///
207
207
/// For extra index options, see ``create(index:on:columns:options:condition:)``.
208
208
///
209
+ /// ### Generated columns
210
+ ///
211
+ /// See [Generated columns](https://sqlite.org/gencol.html) for
212
+ /// more information:
213
+ ///
214
+ /// ```swift
215
+ /// t.column("totalScore", .integer).generatedAs(sql: "score + bonus")
216
+ /// t.column("totalScore", .integer).generatedAs(Column("score") + Column("bonus"))
217
+ /// ```
218
+ ///
209
219
/// ### Integrity checks
210
220
///
211
221
/// SQLite will only let conforming rows in:
@@ -224,16 +234,6 @@ extension Database {
224
234
/// t.check(sql: "a + b < 10")
225
235
/// ```
226
236
///
227
- /// ### Generated columns
228
- ///
229
- /// [Generated columns](https://sqlite.org/gencol.html) are available with a
230
- /// [custom SQLite build](https://github.com/groue/GRDB.swift/blob/master/Documentation/CustomSQLiteBuilds.md):
231
- ///
232
- /// ```swift
233
- /// t.column("totalScore", .integer).generatedAs(sql: "score + bonus")
234
- /// t.column("totalScore", .integer).generatedAs(Column("score") + Column("bonus"))
235
- /// ```
236
- ///
237
237
/// ### Raw SQL columns and constraints
238
238
///
239
239
/// Columns and constraints can be defined with raw sql:
@@ -1396,6 +1396,11 @@ public final class TableAlteration {
1396
1396
/// - ``collate(_:)-4dljx``
1397
1397
/// - ``collate(_:)-9ywza``
1398
1398
///
1399
+ /// ### Generated Columns
1400
+ ///
1401
+ /// - ``generatedAs(_:_:)``
1402
+ /// - ``generatedAs(sql:_:)``
1403
+ ///
1399
1404
/// ### Other Constraints
1400
1405
///
1401
1406
/// - ``check(_:)``
@@ -1699,7 +1704,84 @@ public final class ColumnDefinition {
1699
1704
return self
1700
1705
}
1701
1706
1702
- #if GRDBCUSTOMSQLITE
1707
+ #if GRDBCUSTOMSQLITE || GRDBCIPHER
1708
+ /// Defines the column as a generated column.
1709
+ ///
1710
+ /// For example:
1711
+ ///
1712
+ /// ```swift
1713
+ /// // CREATE TABLE player(
1714
+ /// // id INTEGER PRIMARY KEY AUTOINCREMENT,
1715
+ /// // score INTEGER NOT NULL,
1716
+ /// // bonus INTEGER NOT NULL,
1717
+ /// // totalScore INTEGER GENERATED ALWAYS AS (score + bonus) STORED
1718
+ /// // )
1719
+ /// try db.create(table: "player") { t in
1720
+ /// t.autoIncrementedPrimaryKey("id")
1721
+ /// t.column("score", .integer).notNull()
1722
+ /// t.column("bonus", .integer).notNull()
1723
+ /// t.column("totalScore", .integer).generatedAs(sql: "score + bonus", .stored)
1724
+ /// }
1725
+ /// ```
1726
+ ///
1727
+ /// Related SQLite documentation: <https://sqlite.org/gencol.html>
1728
+ ///
1729
+ /// - parameters:
1730
+ /// - sql: An SQL expression.
1731
+ /// - qualification: The generated column's qualification, which
1732
+ /// defaults to ``GeneratedColumnQualification/virtual``.
1733
+ /// - returns: `self` so that you can further refine the column definition.
1734
+ @discardableResult
1735
+ public func generatedAs(
1736
+ sql: String ,
1737
+ _ qualification: GeneratedColumnQualification = . virtual)
1738
+ -> Self
1739
+ {
1740
+ let expression = SQL ( sql: sql) . sqlExpression
1741
+ generatedColumnConstraint = GeneratedColumnConstraint (
1742
+ expression: expression,
1743
+ qualification: qualification)
1744
+ return self
1745
+ }
1746
+
1747
+ /// Defines the column as a generated column.
1748
+ ///
1749
+ /// For example:
1750
+ ///
1751
+ /// ```swift
1752
+ /// // CREATE TABLE player(
1753
+ /// // id INTEGER PRIMARY KEY AUTOINCREMENT,
1754
+ /// // score INTEGER NOT NULL,
1755
+ /// // bonus INTEGER NOT NULL,
1756
+ /// // totalScore INTEGER GENERATED ALWAYS AS (score + bonus) STORED
1757
+ /// // )
1758
+ /// try db.create(table: "player") { t in
1759
+ /// t.autoIncrementedPrimaryKey("id")
1760
+ /// t.column("score", .integer).notNull()
1761
+ /// t.column("bonus", .integer).notNull()
1762
+ /// t.column("totalScore", .integer).generatedAs(Column("score") + Column("bonus"), .stored)
1763
+ /// }
1764
+ /// ```
1765
+ ///
1766
+ /// Related SQLite documentation: <https://sqlite.org/gencol.html>
1767
+ ///
1768
+ /// - parameters:
1769
+ /// - expression: The generated expression.
1770
+ /// - qualification: The generated column's qualification, which
1771
+ /// defaults to ``GeneratedColumnQualification/virtual``.
1772
+ /// - returns: `self` so that you can further refine the column definition.
1773
+ @discardableResult
1774
+ public func generatedAs(
1775
+ _ expression: some SQLExpressible ,
1776
+ _ qualification: GeneratedColumnQualification = . virtual)
1777
+ -> Self
1778
+ {
1779
+ generatedColumnConstraint = GeneratedColumnConstraint (
1780
+ expression: expression. sqlExpression,
1781
+ qualification: qualification)
1782
+ return self
1783
+ }
1784
+ #else
1703
1785
/// Defines the column as a generated column.
1704
1786
///
1705
1787
/// For example:
@@ -1726,6 +1808,7 @@ public final class ColumnDefinition {
1726
1808
/// - qualification: The generated column's qualification, which
1727
1809
/// defaults to ``GeneratedColumnQualification/virtual``.
1728
1810
/// - returns: `self` so that you can further refine the column definition.
1811
+ @available ( iOS 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , macOS 12 . 0 , * ) // SQLite 3.35.0+ (3.31 actually)
1729
1812
@discardableResult
1730
1813
public func generatedAs(
1731
1814
sql: String ,
@@ -1765,6 +1848,7 @@ public final class ColumnDefinition {
1765
1848
/// - qualification: The generated column's qualification, which
1766
1849
/// defaults to ``GeneratedColumnQualification/virtual``.
1767
1850
/// - returns: `self` so that you can further refine the column definition.
1851
+ @available ( iOS 15 . 0 , tvOS 15 . 0 , watchOS 8 . 0 , macOS 12 . 0 , * ) // SQLite 3.35.0+ (3.31 actually)
1768
1852
@discardableResult
1769
1853
public func generatedAs(
1770
1854
_ expression: some SQLExpressible ,
0 commit comments