Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose DatabaseRegion(table:) initializer #510

Merged
merged 6 commits into from
Apr 9, 2019
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one expection:
- [#499](https://github.com/groue/GRDB.swift/pull/499): Extract EncodableRecord from MutablePersistableRecord
- [#502](https://github.com/groue/GRDB.swift/pull/502): Rename Future to DatabaseFuture
- [#503](https://github.com/groue/GRDB.swift/pull/503): IFNULL support for association aggregates
- [#510](https://github.com/groue/GRDB.swift/pull/510) by [@charlesmchen-signal](https://github.com/charlesmchen-signal): Expose DatabaseRegion(table:) initializer

### Fixed

Expand Down
40 changes: 16 additions & 24 deletions GRDB/Core/DatabaseRegion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
/// `observes(eventsOfKind:)` and `databaseDidChange(with:)` methods.
///
/// A database region is the union of any number of "table regions", which can
/// cover a full table, or the combination of columns and rows (identified by
/// their rowids):
/// cover a full table, or the combination of columns and rows:
///
/// |Table1 | |Table2 | |Table3 | |Table4 | |Table5 |
/// |-------| |-------| |-------| |-------| |-------|
Expand All @@ -13,32 +12,23 @@
/// |x|x|x|x| |x| | | | | | | | | |x|x| |x| | | | | |
/// |x|x|x|x| |x| | | | | | | | | | | | | | | | | | |
///
/// You don't create a database region directly. Instead, you use one of
/// those methods:
/// To create a database region, you use one of those methods:
///
/// - `SelectStatement.databaseRegion`:
/// - `DatabaseRegion.fullDatabase`: the region that covers all database tables.
///
/// let statement = db.makeSelectStatement(sql: "SELECT name, score FROM player")
/// print(statement.databaseRegion)
/// // prints "player(name,score)"
/// - `DatabaseRegion()`: the empty region.
///
/// - `FetchRequest.databaseRegion(_:)`
/// - `DatabaseRegion(table:)`: the region that covers one database table.
///
/// let request = Player.filter(key: 1)
/// try print(request.databaseRegion(db))
/// // prints "player(*)[1]"
/// - `SelectStatement.databaseRegion`:
///
/// Database regions returned by requests can be more precise than regions
/// returned by select statements. Especially, regions returned by statements
/// don't know about rowids:
/// let statement = try db.makeSelectStatement(sql: "SELECT name, score FROM player")
/// let region = statement.databaseRegion
///
/// // A plain statement
/// let statement = db.makeSelectStatement(sql: "SELECT * FROM player WHERE id = 1")
/// statement.databaseRegion // "player(*)"
/// - `FetchRequest.databaseRegion(_:)`
///
/// // A query interface request that executes the same statement:
/// let request = Player.filter(key: 1)
/// try request.databaseRegion(db) // "player(*)[1]"
/// let request = Player.filter(key: 1)
/// let region = try request.databaseRegion(db)
public struct DatabaseRegion: CustomStringConvertible, Equatable {
private let tableRegions: [String: TableRegion]?
private init(tableRegions: [String: TableRegion]?) {
Expand All @@ -58,13 +48,15 @@ public struct DatabaseRegion: CustomStringConvertible, Equatable {
/// from all tables.
public static let fullDatabase = DatabaseRegion(tableRegions: nil)

/// The empty database region
/// Creates an empty database region.
public init() {
self.init(tableRegions: [:])
}

/// A full table: (all columns in the table) × (all rows)
init(table: String) {
/// Creates a region that spans all rows and columns of a database table.
///
/// - parameter table: A table name.
public init(table: String) {
self.init(tableRegions: [table: TableRegion(columns: nil, rowIds: nil)])
}

Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7271,8 +7271,6 @@ DatabaseRegion fuels, for example, [ValueObservation and DatabaseRegionObservati

For example, if you observe the region of `Player.select(max(Column("score")))`, then you'll get be notified of all changes performed on the `score` column of the `player` table (updates, insertions and deletions), even if they do not modify the value of the maximum score. However, you will not get any notification for changes performed on other database tables, or updates to other columns of the player table.

Similarly, observing the region of `Country.filter(key: "FR")` will notify all changes that happen to the whole `country` table. That is because SQLite only notifies the numerical [rowid](https://www.sqlite.org/rowidtable.html) of changed rows, and we can't check if it is the row "FR" that has been changed, or another. This limitation does not apply to tables whose primary key is the rowid: `Player.filter(key: 42)` will only notify of changes performed on the row with id 42.

For more details, see the [reference](http://groue.github.io/GRDB.swift/docs/3.7/Structs/DatabaseRegion.html#/s:4GRDB14DatabaseRegionV10isModified2bySbAA0B5EventV_tF).


Expand Down