Skip to content

Commit 77b85be

Browse files
committed
Merge branch 'development'
2 parents bd9aea3 + bb8323b commit 77b85be

File tree

74 files changed

+884
-211
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+884
-211
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:
77

88
#### 6.x Releases
99

10+
- `6.26.x` Releases - [6.26.0](#6260)
1011
- `6.25.x` Releases - [6.25.0](#6250)
1112
- `6.24.x` Releases - [6.24.0](#6240) - [6.24.1](#6241) - [6.24.2](#6242)
1213
- `6.23.x` Releases - [6.23.0](#6230)
@@ -123,6 +124,17 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:
123124

124125
---
125126

127+
## 6.26.0
128+
129+
Released March 23, 2024
130+
131+
- **New**: [#1503](https://github.com/groue/GRDB.swift/pull/1503) by [@simba909](https://github.com/simba909): Conform Database.ColumnType to Sendable
132+
- **New**: [#1510](https://github.com/groue/GRDB.swift/pull/1510) by [@groue](https://github.com/groue): Add Sendable conformances and unavailabilities
133+
- **New**: [#1511](https://github.com/groue/GRDB.swift/pull/1511) by [@groue](https://github.com/groue): Database schema dump
134+
- **New**: [#1515](https://github.com/groue/GRDB.swift/pull/1515) by [@groue](https://github.com/groue): Support for the CAST SQLite function
135+
- **Fixed**: [#1508](https://github.com/groue/GRDB.swift/pull/1508) by [@groue](https://github.com/groue): Fix ValueObservation mishandling of database schema modification
136+
- **Fixed**: [#1512](https://github.com/groue/GRDB.swift/issues/1512): Decoding errors are now correctly reported when decoding NULL into a non-optional property of type `Data` or `Date`.
137+
126138
## 6.25.0
127139

128140
Released February 25, 2024

Documentation/AssociationsBasics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2661,7 +2661,7 @@ Aggregates can be modified and combined with Swift operators:
26612661
let request = Team.annotated(with: Team.players.min(Column("score")) ?? 0)
26622662
```
26632663

2664-
- SQL functions `ABS` and `LENGTH` are available as the `abs` and `length` Swift functions:
2664+
- SQL functions `ABS`, `CAST`, and `LENGTH` are available as the `abs`, `cast`, and `length` Swift functions:
26652665

26662666
<details>
26672667
<summary>SQL</summary>

GRDB.swift.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'GRDB.swift'
3-
s.version = '6.25.0'
3+
s.version = '6.26.0'
44

55
s.license = { :type => 'MIT', :file => 'LICENSE' }
66
s.summary = 'A toolkit for SQLite databases, with a focus on application development.'

GRDB/Core/Configuration.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ public struct Configuration {
294294
/// connection is opened.
295295
///
296296
/// Related SQLite documentation: <https://www.sqlite.org/pragma.html#pragma_journal_mode>
297-
public enum JournalModeConfiguration {
297+
public enum JournalModeConfiguration: Sendable {
298298
/// The default setup has ``DatabaseQueue`` perform no specific
299299
/// configuration of the journal mode, and ``DatabasePool``
300300
/// configure the database for the WAL mode (just like the

GRDB/Core/Cursor.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,11 @@ public final class AnyCursor<Element>: Cursor {
733733
}
734734
}
735735

736+
// Explicit non-conformance to Sendable: a type-erased cursor can't be more
737+
// sendable than non-sendable cursors (such as `DatabaseCursor`).
738+
@available(*, unavailable)
739+
extension AnyCursor: Sendable { }
740+
736741
/// A `Cursor` that consumes and drops n elements from an underlying `Base`
737742
/// cursor before possibly returning the first available element.
738743
public final class DropFirstCursor<Base: Cursor> {
@@ -747,6 +752,11 @@ public final class DropFirstCursor<Base: Cursor> {
747752
}
748753
}
749754

755+
// Explicit non-conformance to Sendable: `DropFirstCursor` is a mutable
756+
// class and there is no known reason for making it thread-safe.
757+
@available(*, unavailable)
758+
extension DropFirstCursor: Sendable { }
759+
750760
extension DropFirstCursor: Cursor {
751761
public func next() throws -> Base.Element? {
752762
while dropped < limit {
@@ -773,6 +783,11 @@ public final class DropWhileCursor<Base: Cursor> {
773783
}
774784
}
775785

786+
// Explicit non-conformance to Sendable: `DropWhileCursor` is a mutable
787+
// class and there is no known reason for making it thread-safe.
788+
@available(*, unavailable)
789+
extension DropWhileCursor: Sendable { }
790+
776791
extension DropWhileCursor: Cursor {
777792
public func next() throws -> Base.Element? {
778793
if predicateHasFailed {
@@ -818,6 +833,11 @@ public final class EnumeratedCursor<Base: Cursor> {
818833
}
819834
}
820835

836+
// Explicit non-conformance to Sendable: `EnumeratedCursor` is a mutable
837+
// class and there is no known reason for making it thread-safe.
838+
@available(*, unavailable)
839+
extension EnumeratedCursor: Sendable { }
840+
821841
extension EnumeratedCursor: Cursor {
822842
public func next() throws -> (Int, Base.Element)? {
823843
guard let element = try base.next() else { return nil }
@@ -875,6 +895,11 @@ public final class FlattenCursor<Base: Cursor> where Base.Element: Cursor {
875895
}
876896
}
877897

898+
// Explicit non-conformance to Sendable: `EnumeratedCursor` is a mutable
899+
// class and there is no known reason for making it thread-safe.
900+
@available(*, unavailable)
901+
extension FlattenCursor: Sendable { }
902+
878903
extension FlattenCursor: Cursor {
879904
public func next() throws -> Base.Element.Element? {
880905
while true {
@@ -901,6 +926,11 @@ public final class MapCursor<Base: Cursor, Element> {
901926
}
902927
}
903928

929+
// Explicit non-conformance to Sendable: There is no known reason for making
930+
// it thread-safe (`transform` a Sendable closure).
931+
@available(*, unavailable)
932+
extension MapCursor: Sendable { }
933+
904934
extension MapCursor: Cursor {
905935
public func next() throws -> Element? {
906936
guard let element = try base.next() else { return nil }
@@ -927,6 +957,11 @@ public final class PrefixCursor<Base: Cursor> {
927957
}
928958
}
929959

960+
// Explicit non-conformance to Sendable: `PrefixCursor` is a mutable
961+
// class and there is no known reason for making it thread-safe.
962+
@available(*, unavailable)
963+
extension PrefixCursor: Sendable { }
964+
930965
extension PrefixCursor: Cursor {
931966
public func next() throws -> Base.Element? {
932967
if taken >= maxLength { return nil }
@@ -954,6 +989,11 @@ public final class PrefixWhileCursor<Base: Cursor> {
954989
}
955990
}
956991

992+
// Explicit non-conformance to Sendable: `PrefixCursor` is a mutable
993+
// class and there is no known reason for making it thread-safe.
994+
@available(*, unavailable)
995+
extension PrefixWhileCursor: Sendable { }
996+
957997
extension PrefixWhileCursor: Cursor {
958998
public func next() throws -> Base.Element? {
959999
if !predicateHasFailed, let nextElement = try base.next() {

GRDB/Core/Database+Schema.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,7 @@ extension Database {
997997
///
998998
/// - [pragma `table_info`](https://www.sqlite.org/pragma.html#pragma_table_info)
999999
/// - [pragma `table_xinfo`](https://www.sqlite.org/pragma.html#pragma_table_xinfo)
1000-
public struct ColumnInfo: FetchableRecord {
1000+
public struct ColumnInfo: FetchableRecord, Sendable {
10011001
let cid: Int
10021002
let hidden: Int?
10031003

@@ -1083,9 +1083,9 @@ public struct ColumnInfo: FetchableRecord {
10831083
///
10841084
/// - [pragma `index_list`](https://www.sqlite.org/pragma.html#pragma_index_list)
10851085
/// - [pragma `index_info`](https://www.sqlite.org/pragma.html#pragma_index_info)
1086-
public struct IndexInfo {
1086+
public struct IndexInfo: Sendable{
10871087
/// The origin of an index.
1088-
public struct Origin: RawRepresentable, Equatable, DatabaseValueConvertible {
1088+
public struct Origin: RawRepresentable, Equatable, DatabaseValueConvertible, Sendable {
10891089
public var rawValue: String
10901090

10911091
public init(rawValue: String) {
@@ -1158,7 +1158,7 @@ public struct IndexInfo {
11581158
/// ```
11591159
///
11601160
/// Related SQLite documentation: <https://www.sqlite.org/pragma.html#pragma_foreign_key_check>
1161-
public struct ForeignKeyViolation {
1161+
public struct ForeignKeyViolation: Sendable {
11621162
/// The name of the table that contains the foreign key.
11631163
public var originTable: String
11641164

@@ -1307,7 +1307,7 @@ extension ForeignKeyViolation: CustomStringConvertible {
13071307
/// pk.rowIDColumn // nil
13081308
/// pk.isRowID // false
13091309
/// ```
1310-
public struct PrimaryKeyInfo {
1310+
public struct PrimaryKeyInfo: Sendable {
13111311
private enum Impl {
13121312
/// The hidden rowID.
13131313
case hiddenRowID
@@ -1433,7 +1433,7 @@ public struct PrimaryKeyInfo {
14331433
/// `Database` method.
14341434
///
14351435
/// Related SQLite documentation: [pragma `foreign_key_list`](https://www.sqlite.org/pragma.html#pragma_foreign_key_list).
1436-
public struct ForeignKeyInfo {
1436+
public struct ForeignKeyInfo: Sendable {
14371437
/// The first column in the output of the `foreign_key_list` pragma.
14381438
public var id: Int
14391439

GRDB/Core/Database+Statements.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,11 @@ public class SQLStatementCursor {
361361
}
362362
}
363363

364+
// Explicit non-conformance to Sendable: database cursors must be used from
365+
// a serialized database access dispatch queue.
366+
@available(*, unavailable)
367+
extension SQLStatementCursor: Sendable { }
368+
364369
extension SQLStatementCursor: Cursor {
365370
public func next() throws -> Statement? {
366371
guard offset < cString.count - 1 /* trailing \0 */ else {

GRDB/Core/Database.swift

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ let SQLITE_TRANSIENT = unsafeBitCast(OpaquePointer(bitPattern: -1), to: sqlite3_
7070
///
7171
/// - ``dumpContent(format:to:)``
7272
/// - ``dumpRequest(_:format:to:)``
73+
/// - ``dumpSchema(to:)``
7374
/// - ``dumpSQL(_:format:to:)``
7475
/// - ``dumpTables(_:format:tableHeader:stableOrder:to:)``
7576
/// - ``DumpFormat``
@@ -114,6 +115,7 @@ let SQLITE_TRANSIENT = unsafeBitCast(OpaquePointer(bitPattern: -1), to: sqlite3_
114115
/// - ``trace(options:_:)``
115116
/// - ``CheckpointMode``
116117
/// - ``DatabaseBackupProgress``
118+
/// - ``StorageClass``
117119
/// - ``TraceEvent``
118120
/// - ``TracingOptions``
119121
public final class Database: CustomStringConvertible, CustomDebugStringConvertible {
@@ -1729,6 +1731,11 @@ public final class Database: CustomStringConvertible, CustomDebugStringConvertib
17291731
}
17301732
}
17311733

1734+
// Explicit non-conformance to Sendable: `Database` must be used from a
1735+
// serialized database access dispatch queue (see `SerializedDatabase`).
1736+
@available(*, unavailable)
1737+
extension Database: Sendable { }
1738+
17321739
#if SQLITE_HAS_CODEC
17331740
extension Database {
17341741

@@ -1854,7 +1861,7 @@ extension Database {
18541861
/// The available checkpoint modes.
18551862
///
18561863
/// Related SQLite documentation: <https://www.sqlite.org/c3ref/wal_checkpoint_v2.html>
1857-
public enum CheckpointMode: CInt {
1864+
public enum CheckpointMode: CInt, Sendable {
18581865
/// The `SQLITE_CHECKPOINT_PASSIVE` mode.
18591866
case passive = 0
18601867

@@ -1873,7 +1880,7 @@ extension Database {
18731880
/// Related SQLite documentation:
18741881
/// - <https://www.sqlite.org/datatype3.html#collating_sequences>
18751882
/// - <https://www.sqlite.org/datatype3.html#collation>
1876-
public struct CollationName: RawRepresentable, Hashable {
1883+
public struct CollationName: RawRepresentable, Hashable, Sendable {
18771884
public let rawValue: String
18781885

18791886
/// Creates a collation name.
@@ -1910,7 +1917,7 @@ extension Database {
19101917
///
19111918
/// For more information, see
19121919
/// [Datatypes In SQLite](https://www.sqlite.org/datatype3.html).
1913-
public struct ColumnType: RawRepresentable, Hashable {
1920+
public struct ColumnType: RawRepresentable, Hashable, Sendable {
19141921
/// The SQL for the column type (`"TEXT"`, `"BLOB"`, etc.)
19151922
public let rawValue: String
19161923

@@ -1962,7 +1969,7 @@ extension Database {
19621969
/// An SQLite conflict resolution.
19631970
///
19641971
/// Related SQLite documentation: <https://www.sqlite.org/lang_conflict.html>
1965-
public enum ConflictResolution: String {
1972+
public enum ConflictResolution: String, Sendable {
19661973
/// The `ROLLBACK` conflict resolution.
19671974
case rollback = "ROLLBACK"
19681975

@@ -1982,7 +1989,7 @@ extension Database {
19821989
/// A foreign key action.
19831990
///
19841991
/// Related SQLite documentation: <https://www.sqlite.org/foreignkeys.html>
1985-
public enum ForeignKeyAction: String {
1992+
public enum ForeignKeyAction: String, Sendable {
19861993
/// The `CASCADE` foreign key action.
19871994
case cascade = "CASCADE"
19881995

@@ -1999,13 +2006,39 @@ extension Database {
19992006
/// An error log function that takes an error code and message.
20002007
public typealias LogErrorFunction = (_ resultCode: ResultCode, _ message: String) -> Void
20012008

2009+
/// An SQLite storage class.
2010+
///
2011+
/// For more information, see
2012+
/// [Datatypes In SQLite](https://www.sqlite.org/datatype3.html).
2013+
public struct StorageClass: RawRepresentable, Hashable, Sendable {
2014+
/// The SQL for the storage class (`"INTEGER"`, `"REAL"`, etc.)
2015+
public let rawValue: String
2016+
2017+
/// Creates an SQL storage class.
2018+
public init(rawValue: String) {
2019+
self.rawValue = rawValue
2020+
}
2021+
2022+
/// The `INTEGER` storage class.
2023+
public static let integer = StorageClass(rawValue: "INTEGER")
2024+
2025+
/// The `REAL` storage class.
2026+
public static let real = StorageClass(rawValue: "REAL")
2027+
2028+
/// The `TEXT` storage class.
2029+
public static let text = StorageClass(rawValue: "TEXT")
2030+
2031+
/// The `BLOB` storage class.
2032+
public static let blob = StorageClass(rawValue: "BLOB")
2033+
}
2034+
20022035
/// An option for the SQLite tracing feature.
20032036
///
20042037
/// You use `TracingOptions` with the `Database`
20052038
/// ``Database/trace(options:_:)`` method.
20062039
///
20072040
/// Related SQLite documentation: <https://www.sqlite.org/c3ref/c_trace.html>
2008-
public struct TracingOptions: OptionSet {
2041+
public struct TracingOptions: OptionSet, Sendable {
20092042
/// The raw trace event code.
20102043
public let rawValue: CInt
20112044

@@ -2138,15 +2171,15 @@ extension Database {
21382171
///
21392172
/// Related SQLite documentation: <https://www.sqlite.org/lang_transaction.html>.
21402173
@frozen
2141-
public enum TransactionCompletion {
2174+
public enum TransactionCompletion: Sendable {
21422175
case commit
21432176
case rollback
21442177
}
21452178

21462179
/// A transaction kind.
21472180
///
21482181
/// Related SQLite documentation: <https://www.sqlite.org/lang_transaction.html>.
2149-
public enum TransactionKind: String {
2182+
public enum TransactionKind: String, Sendable {
21502183
/// The `DEFERRED` transaction kind.
21512184
case deferred = "DEFERRED"
21522185

@@ -2179,3 +2212,13 @@ extension Database {
21792212
}
21802213
}
21812214
}
2215+
2216+
// Explicit non-conformance to Sendable: a trace event contains transient
2217+
// information.
2218+
@available(*, unavailable)
2219+
extension Database.TraceEvent: Sendable { }
2220+
2221+
// Explicit non-conformance to Sendable: a trace event contains transient
2222+
// information.
2223+
@available(*, unavailable)
2224+
extension Database.TraceEvent.Statement: Sendable { }

GRDB/Core/DatabaseBackupProgress.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/// Describe the progress of a database backup.
22
///
33
/// Related SQLite documentation: <https://www.sqlite.org/c3ref/backup_finish.html>
4-
public struct DatabaseBackupProgress {
4+
public struct DatabaseBackupProgress: Sendable {
55
/// The number of pages still to be backed up.
66
///
77
/// It is the result of the `sqlite3_backup_remaining` function.

GRDB/Core/DatabaseReader.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import Dispatch
3737
///
3838
/// - ``dumpContent(format:to:)``
3939
/// - ``dumpRequest(_:format:to:)``
40+
/// - ``dumpSchema(to:)``
4041
/// - ``dumpSQL(_:format:to:)``
4142
/// - ``dumpTables(_:format:tableHeader:stableOrder:to:)``
4243
/// - ``DumpFormat``

0 commit comments

Comments
 (0)