Skip to content
This repository has been archived by the owner on Sep 16, 2022. It is now read-only.

Commit

Permalink
Update to version 5.7.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven Grosmark committed Oct 25, 2021
1 parent a002004 commit 42835c1
Show file tree
Hide file tree
Showing 174 changed files with 14,327 additions and 7,455 deletions.
2 changes: 1 addition & 1 deletion GRDB-xcframework.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Pod::Spec.new do |s|
s.name = 'GRDB-xcframework'

s.module_name = 'GRDB'
s.version = '5.5.0'
s.version = '5.7.2'

s.summary = 'A toolkit for SQLite databases, with a focus on application development.'
s.description = <<-DESC
Expand Down
26 changes: 13 additions & 13 deletions GRDB.swift/.travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ git:

jobs:
include:

###########################################
## Test GRDB Xcode 11.4

- name: "Test GRDB Xcode 11.4 - GRDBiOS iOS maxTarget"
gemfile: .ci/gemfiles/Gemfile.travis
osx_image: xcode11.4
script: make test_framework_GRDBiOS_maxTarget_maxSwift

- name: "Test GRDB Xcode 11.4 - GRDBiOS iOS minTarget"
gemfile: .ci/gemfiles/Gemfile.travis
osx_image: xcode11.4
script: make test_framework_GRDBiOS_minTarget

###########################################
## Test GRDB Xcode 12.2
Expand Down Expand Up @@ -146,16 +159,3 @@ jobs:
gemfile: .ci/gemfiles/Gemfile.travis
osx_image: xcode12.2
script: make test_install_customSQLite

###########################################
## Test GRDB Xcode 11.4

- name: "Test GRDB Xcode 11.4 - GRDBiOS iOS maxTarget"
gemfile: .ci/gemfiles/Gemfile.travis
osx_image: xcode11.4
script: make test_framework_GRDBiOS_maxTarget_maxSwift

- name: "Test GRDB Xcode 11.4 - GRDBiOS iOS minTarget"
gemfile: .ci/gemfiles/Gemfile.travis
osx_image: xcode11.4
script: make test_framework_GRDBiOS_minTarget
82 changes: 82 additions & 0 deletions GRDB.swift/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:

#### 5.x Releases

- `5.7.x` Releases - [5.7.0](#570) | [5.7.1](#571) | [5.7.2](#572)
- `5.6.x` Releases - [5.6.0](#560)
- `5.5.x` Releases - [5.5.0](#550)
- `5.4.x` Releases - [5.4.0](#540)
- `5.3.x` Releases - [5.3.0](#530)
Expand Down Expand Up @@ -71,6 +73,86 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:
- [0.110.0](#01100), ...


#### 5.7.2

- **Fixed**: Really fix breaking change and restore `SQLLiteral` as a deprecated alias for `SQL`.

#### 5.7.1

- **Fixed**: Fix breaking change and restore `SQLLiteral` as a deprecated alias for `SQL`.

## 5.7.0

Released March 28, 2021 &bull; [diff](https://github.com/groue/GRDB.swift/compare/v5.6.0...v5.7.0)

- **New**: [#947](https://github.com/groue/GRDB.swift/pull/947) by [@chrisballinger](https://github.com/chrisballinger): Allow access to Encoder from KeyedEncodingContainer

- **New**: Record types that adopt the standard [Identifiable](https://developer.apple.com/documentation/swift/identifiable) protocol have gained type-safe methods that deal with the primary key. For example:

```swift
let player = try Player.fetchOne(db, id: 42)
try Player.deleteAll(db, ids: [1, 2, 3])
```

See the new [Identifiable Records](README.md#identifiable-records) documentation chapter for more information.

- **New**: `SQLLiteral` has more use cases than initialy expected, and is renamed `SQL`.

- **New**: [`SQL` literal](Documentation/SQLInterpolation.md#sql-literal) can now be directly used as an expression, an ordering term, or a selection item.:

```swift
let name = "O'Brien"
let request = Player
.select(SQL("id, score"), ...)
.filter(SQL("name = \(name)") && ...)
.order(SQL("score DESC"), ...)
```

- **New**: Table creation DSL now supports columns and constraints defined with raw SQL String or [SQL literal](Documentation/SQLInterpolation.md#sql-literal):

```swift
try db.create(table: "player") do { t in
t.column(sql: "id INTEGER PRIMARY KEY AUTOINCREMENT")
t.column(literal: "name TEXT DEFAULT \("Anonymous")")
t.constraint(sql: "CHECK (LENGTH(name) > 0)")
t.constraint(literal: "CHECK (LENGTH(name) <= \(100))")
}
```

- **New**: Prepared statements can profit from [SQL Interpolation](Documentation/SQLInterpolation.md):

```swift
let updateStatement = try db.makeUpdateStatement(literal: "INSERT ...")
let selectStatement = try db.makeSelectStatement(literal: "SELECT ...")
// ~~~~~~~
```

- **New**: [DatabaseMigrator](Documentation/Migrations.md#asynchronous-migrations) can now asynchronously migrate a database. A Combine publisher is also available.

- **New**: Added support for the `EXISTS` and `NOT EXISTS` subquery operators. See the updated [SQL Operators](README.md#sql-operators) documentation.

- **New**: `Foundation.Decimal` can now be stored in the database, and all Foundation number types can be decoded from decimal numbers stored as strings. See the [NSNumber, NSDecimalNumber, and Decimal](README.md#nsnumber-nsdecimalnumber-and-decimal) chapter for details.

## 5.6.0

Released March 12, 2021 &bull; [diff](https://github.com/groue/GRDB.swift/compare/v5.5.0...v5.6.0)

- **Fixed**: [#933](https://github.com/groue/GRDB.swift/pull/933): Fix DatabaseMigrator.eraseDatabaseOnSchemaChange in the context of shared databases

- **Fixed**: [#934](https://github.com/groue/GRDB.swift/pull/934): Fix a crash in the ValueObservation publisher

- **New**: [#936](https://github.com/groue/GRDB.swift/pull/936): Complete Associations and the DerivableRequest Protocol

- **New**: Database cursors can feed more standard Swift collections: `Array(cursor, minimumCapacity: ...)`, `Dictionary(uniqueKeysWithValues: cursor)`, etc (see [Cursors](README.md#cursors)).

- **Documentation update**: The [Associations Guide](Documentation/AssociationsBasics.md) has gained a new [Further Refinements to Associations](Documentation/AssociationsBasics.md#further-refinements-to-associations) chapter which shows the new association methods brought by [#936](https://github.com/groue/GRDB.swift/pull/936).

- **Documentation update**: The [Good Practices for Designing Record Types](Documentation/GoodPracticesForDesigningRecordTypes.md) guide has an updated [Define Record Requests](Documentation/GoodPracticesForDesigningRecordTypes.md#define-record-requests) chapter, now that the `DerivableRequest` protocol has access to `limit`, `distinct`, `group`, `having`, association aggregates, and common table expressions.

- **Documentation update**: The [Good Practices for Designing Record Types](Documentation/GoodPracticesForDesigningRecordTypes.md) guide has a new chapter of good practices: [Record Types Hide Intimate Database Details](Documentation/GoodPracticesForDesigningRecordTypes.md#record-types-hide-intimate-database-details).

- **Documentation update**: A new [Single-Row Tables](Documentation/SingleRowTables.md) guide provides guidance for designing tables that store configuration values, user preferences, and generally some global application state.

## 5.5.0

Released March 3, 2021 &bull; [diff](https://github.com/groue/GRDB.swift/compare/v5.4.0...v5.5.0)
Expand Down
137 changes: 133 additions & 4 deletions GRDB.swift/Documentation/AssociationsBasics.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ GRDB Associations
- [Sorting Associations]
- [Ordered Associations]
- [Columns Selected by an Association]
- [Further Refinements to Associations]
- [Table Aliases]
- [Refining Association Requests]
- [Fetching Values from Associations]
Expand Down Expand Up @@ -88,7 +89,7 @@ struct BookInfo {

let books = try Book.fetchAll(db)
let bookInfos = books.map { book -> BookInfo in
let author = try Author.fetchOne(db, key: book.authorId)
let author = try Author.fetchOne(db, id: book.authorId)
return BookInfo(book: book, author: author)
}
```
Expand Down Expand Up @@ -781,6 +782,7 @@ Fetch requests do not visit the database until you fetch values from them. This
- [Sorting Associations]
- [Ordered Associations]
- [Columns Selected by an Association]
- [Further Refinements to Associations]
- [Table Aliases]
- [Refining Association Requests]

Expand Down Expand Up @@ -855,14 +857,22 @@ Before we describe them in detail, let's see a few requests they can build:
let request = Author
.including(all: Author.books)

/// All authors with their three most popular books
let request = Author
.including(all: Author.books.order(Column("popularity").desc).limit(3))

/// All authors with their awarded books
let request = Author
.including(all: Author.books.having(Book.awards.isEmpty == false))

/// All books with their respective author
let request = Book
.including(required: Book.author)

/// All books with their respective author, sorted by title
let request = Book
.order(Column("title"))
.including(required: Book.author)
.order(Column("title"))

/// All books written by a French author
let request = Book
Expand Down Expand Up @@ -1058,7 +1068,7 @@ let bookInfos: [BookInfo] = try BookInfo.fetchAll(db, request)
**You can filter associated records.**
The `filter(_:)`, `filter(key:)` and `filter(keys:)` methods, that you already know for [filtering simple requests](../README.md#requests), can filter associated records as well:
The `filter(_:)`, `filter(id:)`, `filter(ids:)`, `filter(key:)` and `filter(keys:)` methods, that you already know for [filtering simple requests](../README.md#requests), can filter associated records as well:
```swift
// SELECT book.*
Expand Down Expand Up @@ -1235,7 +1245,6 @@ let teamInfos = try Team
.fetchAll(db)
```


## Columns Selected by an Association

By default, associated records include all their columns:
Expand All @@ -1262,6 +1271,124 @@ let request = Book.including(required: restrictedAuthor)
To specify the default selection for all inclusions of a given type, see [Columns Selected by a Request](../README.md#columns-selected-by-a-request).


## Further Refinements to Associations

Associations support more refinements:

- `limit`

Fetch all authors with their three most popular books:

```swift
struct AuthorInfo: FetchableRecord, Decodable {
var author: Author
var books: [Book]
}

let mostPopularBooks = Author.books
.order(Column("popularity").desc)
.limit(3)

let authorInfos: [AuthorInfo] = try Author
.including(all: mostPopularBooks)
.asRequest(of: AuthorInfo.self)
.fetchAll(db)
```

- `distinct`

Fetch all authors with the kinds of books they write (novels, poems, plays, etc):

```swift
struct AuthorInfo: Decodable, FetchableRecord {
var author: Author
var bookKinds: Set<Book.Kind>
}

let distinctBookKinds = Author.books
.select(Column("kind"))
.distinct()
.forKey("bookKinds")

let authorInfos: [AuthorInfo] = try Author
.including(all: distinctBookKinds)
.asRequest(of: AuthorInfo.self)
.fetchAll(db)
```

- `group`, `having`

Fetch all authors with the year of their latest book for each kind (novels, poems, plays, etc):

```swift
struct BookKindInfo: Decodable {
var kind: Book.Kind
var maxYear: Int
}

struct AuthorInfo: Decodable, FetchableRecord {
var author: Author
var bookKindInfos: [BookKindInfo]
}

let bookKindInfos = Author.books
.select(
Column("kind"),
max(Column("year")).forKey("maxYear"))
.group(Column("kind"))
.forKey("bookKindInfos")

let authorInfos: [AuthorInfo] = try Author
.including(all: bookKindInfos)
.asRequest(of: AuthorInfo.self)
.fetchAll(db)
```

- [Association Aggregates]

Fetch all authors with their awarded books:

```swift
struct AuthorInfo: FetchableRecord, Decodable {
var author: Author
var awardedBooks: [Book]
}

let awardedBooks = Author.books
.having(Book.awards.isEmpty == false)
.forKey("awardedBooks")

let authorInfos: [AuthorInfo] = try Author
.including(all: awardedBooks)
.asRequest(of: AuthorInfo.self)
.fetchAll(db)
```

- [Common Table Expressions]

Association can use their own CTEs:

```swift
struct AuthorInfo: FetchableRecord, Decodable {
var author: Author
var specialBooks: [Book]
}

let specialCTE = CommonTableExpression(...)
let specialBooks = Author.books
.with(specialCTE)
... // use the CTE in the book association
.forKey("specialBooks")

let authorInfos = try Author
.including(all: specialBooks)
.asRequest(of: AuthorInfo.self)
.fetchAll(db)
```

> :warning: **Warning**: associations refined with `limit`, `distinct`, `group`, `having`, or association aggregates can only be used with `including(all:)`. You will get a fatal error if you use them with other joining methods: `including(required:)`, etc.


## Table Aliases

In all examples we have seen so far, all associated records are joined, included, filtered, and sorted independently. We could not filter them on conditions that involve several records, for example.
Expand Down Expand Up @@ -2447,6 +2574,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
[Choosing Between BelongsTo and HasOne]: #choosing-between-belongsto-and-hasone
[Self Joins]: #self-joins
[Ordered Associations]: #ordered-associations
[Further Refinements to Associations]: #further-refinements-to-associations
[The Types of Associations]: #the-types-of-associations
[FetchableRecord]: ../README.md#fetchablerecord-protocols
[migration]: Migrations.md
Expand Down Expand Up @@ -2497,4 +2625,5 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
[ValueObservation]: ../README.md#valueobservation
[FAQ]: ../README.md#faq-associations
[common table expressions]: CommonTableExpressions.md
[Common Table Expressions]: CommonTableExpressions.md
[Associations to Common Table Expressions]: CommonTableExpressions.md#associations-to-common-table-expressions
19 changes: 17 additions & 2 deletions GRDB.swift/Documentation/Combine.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ let newPlayerCount = dbQueue.writePublisher { db -> Int in

</details>

<details>
<summary><strong>Asynchronously migrate the database</strong></summary>

This publisher migrates a database:

```swift
// DatabasePublishers.Migrate
let migrator: DatabaseMigrator = ...
let publisher = migrator.migratePublisher(dbQueue)
```

</details>

<details>
<summary><strong>Observe changes in database values</strong></summary>

Expand Down Expand Up @@ -99,11 +112,12 @@ let cancellable = publisher.sink(

# Asynchronous Database Access

GRDB provide publishers that perform asynchronous database accesses.
GRDB provide publishers that perform asynchronous database accesses:

- [`readPublisher(receiveOn:value:)`]
- [`writePublisher(receiveOn:updates:)`]
- [`writePublisher(receiveOn:updates:thenRead:)`]
- [`migratePublisher(_:receiveOn:)`]


#### `DatabaseReader.readPublisher(receiveOn:value:)`
Expand All @@ -125,7 +139,7 @@ When you use a [database pool], reads are generally non-blocking, unless the max

This publisher can be subscribed from any thread. A new database access starts on every subscription.

The fetched value is published on the main queue, unless you provide a specific scheduler to the `receiveOn` argument.
The fetched value is published on the main queue, unless you provide a specific [scheduler] to the `receiveOn` argument.


#### `DatabaseWriter.writePublisher(receiveOn:updates:)`
Expand Down Expand Up @@ -321,6 +335,7 @@ See [DatabaseRegionObservation] for more information.
[`readPublisher(receiveOn:value:)`]: #databasereaderreadpublisherreceiveonvalue
[`writePublisher(receiveOn:updates:)`]: #databasewriterwritepublisherreceiveonupdates
[`writePublisher(receiveOn:updates:thenRead:)`]: #databasewriterwritepublisherreceiveonupdatesthenread
[`migratePublisher(_:receiveOn:)`]: Migrations.md#asynchronous-migrations
[configured]: ../README.md#databasepool-configuration
[database pool]: ../README.md#database-pools
[database queue]: ../README.md#database-queues
Expand Down
Loading

0 comments on commit 42835c1

Please sign in to comment.