Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
groue committed Sep 9, 2022
2 parents 49cce0a + 589e53b commit 0ac4357
Show file tree
Hide file tree
Showing 62 changed files with 694 additions and 384 deletions.
19 changes: 18 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:

#### 6.x Releases

- `6.0.x` Releases - [6.0.0](#600)
- `6.0.0` Betas - [6.0.0-beta](#600-beta) | [6.0.0-beta.2](#600-beta2) | [6.0.0-beta.3](#600-beta3) | [6.0.0-beta.4](#600-beta4)

#### 5.x Releases

- `5.26.x` Releases - [5.26.0](#5260)
- `5.26.x` Releases - [5.26.0](#5260) - [5.26.1](#5261)
- `5.25.x` Releases - [5.25.0](#5250)
- `5.24.x` Releases - [5.24.0](#5240) | [5.24.1](#5241)
- `5.23.x` Releases - [5.23.0](#5230)
Expand Down Expand Up @@ -97,6 +98,16 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:

---

## 6.0.0

Released September 9, 2022 • [diff](https://github.com/groue/GRDB.swift/compare/v6.0.0-beta.4...v6.0.0)

- **New**: Bump custom SQLite builds v3.39.3
- **Fixed**: [#1274](https://github.com/groue/GRDB.swift/discussions/1274) Fixed a bug with HasManyThrough associations when the "through" association has the same association key as the association itself.
- **Fixed**: [#1275](https://github.com/groue/GRDB.swift/issues/1275) Enhance error message for some requests involving associations on common table expressions.
- **Fixed**: [#1276](https://github.com/groue/GRDB.swift/issues/1276) Fix build error with Xcode 14.0 RC (14A309)
- **Breaking Change**: Request methods that accept a closure with a `Database` argument have been renamed with the `WhenConnected` suffix: `request.filterWhenConnected { db in ... }`, etc.

## 6.0.0-beta.4

Released August 28, 2022 • [diff](https://github.com/groue/GRDB.swift/compare/v6.0.0-beta.3...v6.0.0-beta.4)
Expand Down Expand Up @@ -179,6 +190,12 @@ Upgrading your app can bring improvements: check [Migrating From GRDB 5 to GRDB
- The `statement` property of database cursors was replaced with read-only properties such as `sql` or `columnNames`.
- The `Database.afterNextTransactionCommit(_:)` method was renamed `Database.afterNextTransaction(onCommit:onRollback:)`, and is now able to report rollbacks as well as commits.

## 5.26.1

Released September 8, 2022 • [diff](https://github.com/groue/GRDB.swift/compare/v5.26.0...v5.26.1)

- **Fixed**: [#1276](https://github.com/groue/GRDB.swift/issues/1276) Fix build error with Xcode 14.0 RC (14A309)

## 5.26.0

Released July 9, 2022 • [diff](https://github.com/groue/GRDB.swift/compare/v5.25.0...v5.26.0)
Expand Down
2 changes: 1 addition & 1 deletion Documentation/Concurrency.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ try dbQueue.write { db in
<details>
<summary><b>Swift concurrency</b> (async/await)</summary>

[**:fire: EXPERIMENTAL**](../README.md#what-are-experimental-features) GRDB support for Swift concurrency requires Xcode 13.3.1+.
[**:fire: EXPERIMENTAL**](../README.md#what-are-experimental-features)

```swift
let playerCount = try await dbQueue.read { db in
Expand Down
2 changes: 1 addition & 1 deletion Documentation/CustomSQLiteBuilds.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Custom SQLite Builds

By default, GRDB uses the version of SQLite that ships with the target operating system.

**You can build GRDB with a custom build of [SQLite 3.39.2](https://www.sqlite.org/changes.html).**
**You can build GRDB with a custom build of [SQLite 3.39.3](https://www.sqlite.org/changes.html).**

A custom SQLite build can activate extra SQLite features, and extra GRDB features as well, such as support for the [FTS5 full-text search engine](../../../#full-text-search), and [SQLite Pre-Update Hooks](../../../#support-for-sqlite-pre-update-hooks).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "56026C9725B8A7D000D1DF3F"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "56026C9725B8A7D000D1DF3F"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "56185BEF25B80B8900B9C30F"
Expand Down
4 changes: 2 additions & 2 deletions Documentation/FullTextSearch.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ let pattern = FTS3Pattern(matchingAnyTokenIn: "") // nil
let pattern = FTS3Pattern(matchingAnyTokenIn: "*") // nil
```

FTS3Pattern are regular [values](../README.md#values). You can use them as query [arguments](http://groue.github.io/GRDB.swift/docs/6.0.0-beta.4/Structs/StatementArguments.html):
FTS3Pattern are regular [values](../README.md#values). You can use them as query [arguments](http://groue.github.io/GRDB.swift/docs/6.0/Structs/StatementArguments.html):

```swift
let documents = try Document.fetchAll(db,
Expand Down Expand Up @@ -587,7 +587,7 @@ let pattern = FTS5Pattern(matchingAnyTokenIn: "") // nil
let pattern = FTS5Pattern(matchingAnyTokenIn: "*") // nil
```

FTS5Pattern are regular [values](../README.md#values). You can use them as query [arguments](http://groue.github.io/GRDB.swift/docs/6.0.0-beta.4/Structs/StatementArguments.html):
FTS5Pattern are regular [values](../README.md#values). You can use them as query [arguments](http://groue.github.io/GRDB.swift/docs/6.0/Structs/StatementArguments.html):

```swift
let documents = try Document.fetchAll(db,
Expand Down
2 changes: 1 addition & 1 deletion Documentation/Migrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ try dbQueue.read { db in
}
```

See the [DatabaseMigrator reference](http://groue.github.io/GRDB.swift/docs/6.0.0-beta.4/Structs/DatabaseMigrator.html) for more migrator methods.
See the [DatabaseMigrator reference](http://groue.github.io/GRDB.swift/docs/6.0/Structs/DatabaseMigrator.html) for more migrator methods.


## The `eraseDatabaseOnSchemaChange` Option
Expand Down
2 changes: 1 addition & 1 deletion GRDB.swift.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'GRDB.swift'
s.version = '6.0.0-beta.4'
s.version = '6.0.0'

s.license = { :type => 'MIT', :file => 'LICENSE' }
s.summary = 'A toolkit for SQLite databases, with a focus on application development.'
Expand Down
3 changes: 2 additions & 1 deletion GRDB.xcodeproj/xcshareddata/xcschemes/GRDB.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "56E5D7F81B4D422D00430942"
Expand Down
8 changes: 6 additions & 2 deletions GRDB/Core/Cursor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -690,14 +690,18 @@ public final class AnyCursor<Element>: Cursor {

/// Creates a cursor that wraps a base iterator but whose type depends only
/// on the base iterator’s element type
public convenience init(iterator: some IteratorProtocol<Element>) {
public convenience init<I>(iterator: I)
where I: IteratorProtocol, I.Element == Element
{
var iterator = iterator
self.init { iterator.next() }
}

/// Creates a cursor that wraps a base sequence but whose type depends only
/// on the base sequence’s element type
public convenience init(_ s: some Sequence<Element>) {
public convenience init<S>(_ s: S)
where S: Sequence, S.Element == Element
{
self.init(iterator: s.makeIterator())
}

Expand Down
10 changes: 6 additions & 4 deletions GRDB/Core/Database+Schema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -485,10 +485,11 @@ extension Database {
/// try db.table("t", hasUniqueKey: ["c"]) // false
/// try db.table("t", hasUniqueKey: ["id", "a"]) // true
/// try db.table("t", hasUniqueKey: ["id", "a", "b", "c"]) // true
public func table(
public func table<Columns>(
_ tableName: String,
hasUniqueKey columns: some Sequence<String>)
hasUniqueKey columns: Columns)
throws -> Bool
where Columns: Sequence, Columns.Element == String
{
try columnsForUniqueKey(Array(columns), in: tableName) != nil
}
Expand Down Expand Up @@ -725,10 +726,11 @@ extension Database {
/// returns the columns of the unique key, ordered as the matching index (or
/// primary key). The case of returned columns is not guaranteed to match
/// the case of input columns.
func columnsForUniqueKey(
_ columns: some Sequence<String>,
func columnsForUniqueKey<Columns>(
_ columns: Columns,
in tableName: String)
throws -> [String]?
where Columns: Sequence, Columns.Element == String
{
let lowercasedColumns = Set(columns.map { $0.lowercased() })
if lowercasedColumns.isEmpty {
Expand Down
33 changes: 21 additions & 12 deletions GRDB/Core/Database.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1013,24 +1013,33 @@ public final class Database: CustomStringConvertible, CustomDebugStringConvertib
///
/// - parameter readOnly: If true, writes are forbidden.
func isolated<T>(readOnly: Bool = false, _ block: () throws -> T) throws -> T {
var result: T?
if readOnly {
// Enter read-only mode before starting a transaction, so that the
// transaction commit does not trigger database observation.
// See <https://github.com/groue/GRDB.swift/pull/1213>.
try self.readOnly {
if sqlite3_get_autocommit(sqliteConnection) == 0 {
// Spare savepoints
if readOnly {
return try self.readOnly(block)
} else {
return try block()
}
} else {
var result: T?
if readOnly {
// Enter read-only mode before starting a transaction, so that the
// transaction commit does not trigger database observation.
// See <https://github.com/groue/GRDB.swift/pull/1213>.
try self.readOnly {
try inSavepoint {
result = try block()
return .commit
}
}
} else {
try inSavepoint {
result = try block()
return .commit
}
}
} else {
try inSavepoint {
result = try block()
return .commit
}
return result!
}
return result!
}

/// Executes a block inside a savepoint.
Expand Down
4 changes: 2 additions & 2 deletions GRDB/Core/DatabaseReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ extension DatabaseReader {
// started from a database access.
let value = try unsafeReentrantRead { db in
try db.isolated(readOnly: true) {
try observation.fetchValue(db)
try observation.fetchInitialValue(db)
}
}
onChange(value)
Expand All @@ -575,7 +575,7 @@ extension DatabaseReader {
guard !isCancelled else { return }

let result = dbResult.flatMap { db in
Result { try observation.fetchValue(db) }
Result { try observation.fetchInitialValue(db) }
}

scheduler.schedule {
Expand Down
8 changes: 3 additions & 5 deletions GRDB/Core/DatabaseValue.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
// TODO: remove @preconcurrency when Data conformance to Sendable is exposed.
@preconcurrency import Foundation

// MARK: - DatabaseValue

Expand Down Expand Up @@ -158,10 +159,7 @@ extension DatabaseValue: StatementBinding {
}

extension DatabaseValue: Sendable { }

// @unchecked due to Foundation.Data not conforming to Sendable
// TODO: Remove @unchecked when Foundation has been upgraded
extension DatabaseValue.Storage: @unchecked Sendable { }
extension DatabaseValue.Storage: Sendable { }

// MARK: - Hashable & Equatable

Expand Down
4 changes: 2 additions & 2 deletions GRDB/Core/DatabaseWriter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ extension DatabasePublishers {
public typealias Output = Output
public typealias Failure = Error

fileprivate let upstream: any Publisher<Output, Error>
fileprivate let upstream: AnyPublisher<Output, Error>

public func receive<S>(subscriber: S) where S: Subscriber, Self.Failure == S.Failure, Self.Output == S.Input {
upstream.receive(subscriber: subscriber)
Expand All @@ -636,7 +636,7 @@ extension DatabasePublishers {
@available(OSX 10.15, iOS 13, tvOS 13, watchOS 6, *)
extension Publisher where Failure == Error {
fileprivate func eraseToWritePublisher() -> DatabasePublishers.Write<Output> {
.init(upstream: self)
.init(upstream: self.eraseToAnyPublisher())
}
}
#endif
Expand Down
36 changes: 20 additions & 16 deletions GRDB/Core/Row.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1619,17 +1619,19 @@ extension Row {
str += "\n" + prefix + "- " + name + ": " + scopedRow.debugDescription(level: level + 1)
}
for key in prefetchedRows.keys.sorted() {
let rows = prefetchedRows[key]!
let prefetchedRowsDescription: String
switch rows.count {
case 0:
prefetchedRowsDescription = "0 row"
case 1:
prefetchedRowsDescription = "1 row"
case let count:
prefetchedRowsDescription = "\(count) rows"
// rows is nil if key is a pivot in a "through" association
if let rows = prefetchedRows[key] {
let prefetchedRowsDescription: String
switch rows.count {
case 0:
prefetchedRowsDescription = "0 row"
case 1:
prefetchedRowsDescription = "1 row"
case let count:
prefetchedRowsDescription = "\(count) rows"
}
str += "\n" + prefix + "+ " + key + ": \(prefetchedRowsDescription)"
}
str += "\n" + prefix + "+ " + key + ": \(prefetchedRowsDescription)"
}

return str
Expand Down Expand Up @@ -1912,8 +1914,10 @@ extension Row {
var fifo = Array(prefetches)
while !fifo.isEmpty {
let (prefetchKey, prefetch) = fifo.removeFirst()
if prefetchKey == key {
return prefetch.rows
if prefetchKey == key,
let rows = prefetch.rows // nil for "through" associations
{
return rows
}
fifo.append(contentsOf: prefetch.prefetches)
}
Expand Down Expand Up @@ -2025,7 +2029,9 @@ extension RowImpl {
struct ArrayRowImpl: RowImpl {
let columns: [(String, DatabaseValue)]

init(columns: some Collection<(String, DatabaseValue)>) {
init<Columns>(columns: Columns)
where Columns: Collection, Columns.Element == (String, DatabaseValue)
{
self.columns = Array(columns)
}

Expand All @@ -2051,9 +2057,7 @@ struct ArrayRowImpl: RowImpl {
}
}

// @unchecked because columns property is not inferred as Sendable
// TODO: remove this @unchecked when compiler can handle tuples.
extension ArrayRowImpl: @unchecked Sendable { }
extension ArrayRowImpl: Sendable { }

// TODO: merge with ArrayRowImpl eventually?
/// See Row.init(copiedFromStatementRef:sqliteStatement:)
Expand Down
4 changes: 3 additions & 1 deletion GRDB/Core/RowAdapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ public struct _LayoutedColumnMapping {
///
/// // [foo:"foo" bar: "bar"]
/// try Row.fetchOne(db, sql: "SELECT NULL, 'foo', 'bar'", adapter: FooBarAdapter())
init(layoutColumns: some Sequence<(Int, String)>) {
init<S>(layoutColumns: S)
where S: Sequence, S.Element == (Int, String)
{
self._layoutColumns = Array(layoutColumns)
self.lowercaseColumnIndexes = Dictionary(
layoutColumns
Expand Down
4 changes: 2 additions & 2 deletions GRDB/Core/SQL.swift
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ extension SQL: SQLOrderingTerm {
}
}

extension Sequence<SQL> {
extension Sequence where Element == SQL {
/// Returns the concatenated `SQL` literal of this sequence of literals,
/// inserting the given raw SQL separator between each element.
///
Expand All @@ -272,7 +272,7 @@ extension Sequence<SQL> {
}
}

extension Collection<SQL> {
extension Collection where Element == SQL {
/// Returns the concatenated `SQL` literal of this collection of literals,
/// inserting the given raw SQL separator between each element.
///
Expand Down
Loading

0 comments on commit 0ac4357

Please sign in to comment.