diff --git a/CHANGELOG.md b/CHANGELOG.md index 21b5e0c00a..3d14d1fd66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/GRDB/Core/DatabaseRegion.swift b/GRDB/Core/DatabaseRegion.swift index 04c499538a..7df10aa59f 100644 --- a/GRDB/Core/DatabaseRegion.swift +++ b/GRDB/Core/DatabaseRegion.swift @@ -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 | /// |-------| |-------| |-------| |-------| |-------| @@ -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]?) { @@ -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)]) } diff --git a/README.md b/README.md index 97a2513f9c..de92945512 100644 --- a/README.md +++ b/README.md @@ -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).