ValueObservation
public struct ValueObservation<Reducer>
ValueObservation tracks changes in the results of database requests, and notifies fresh values whenever the database changes.
For example:
let observation = ValueObservation.trackingAll(Player.all)
let observer = try observation.start(in: dbQueue) { players: [Player] in
print("Players have changed.")
}
-
Default is false. Set this property to true when the observation requires write access in order to fetch fresh values. Fetches are then wrapped inside a savepoint.
Don’t set this flag to true unless you really need it. A read/write observation is less efficient than a read-only observation.
Declaration
Swift
public var requiresWriteAccess: Bool -
The extent of the database observation. The default is
.observerLifetime: the observation lasts until the observer returned by thestart(in:onError:onChange:)method is deallocated.Declaration
Swift
public var extent: Database.TransactionObservationExtent -
schedulingcontrols how fresh values are notified. Default is.mainQueue..mainQueue: all values are notified on the main queue.If the observation starts on the main queue, an initial value is notified right upon subscription, synchronously::
// On main queue let observation = ValueObservation.trackingAll(Player.all()) let observer = try observation.start(in: dbQueue) { players: [Player] in print("fresh players: \(players)") } // <- here "fresh players" is already printed.If the observation does not start on the main queue, an initial value is also notified on the main queue, but asynchronously:
// Not on the main queue: "fresh players" is eventually printed // on the main queue. let observation = ValueObservation.trackingAll(Player.all()) let observer = try observation.start(in: dbQueue) { players: [Player] in print("fresh players: \(players)") }When the database changes, fresh values are asynchronously notified:
// Eventually prints "fresh players" on the main queue try dbQueue.write { db in try Player(...).insert(db) }.onQueue(_:startImmediately:): all values are asychronously notified on the specified queue.An initial value is fetched and notified if
startImmediatelyis true.unsafe(startImmediately:): values are not all notified on the same dispatch queue.If
startImmediatelyis true, an initial value is notified right upon subscription, synchronously, on the dispatch queue which starts the observation.// On any queue var observation = ValueObservation.trackingAll(Player.all()) observation.scheduling = .unsafe(startImmediately: true) let observer = try observation.start(in: dbQueue) { players: [Player] in print("fresh players: \(players)") } // <- here "fresh players" is already printed.When the database changes, other values are notified on unspecified queues.
Declaration
Swift
public var scheduling: ValueScheduling -
Returs a ValueObservation which observes regions, and notifies the values returned by the reducer whenever one of the observed regions is modified by a database transaction.
This method is the most fundamental way to create a ValueObservation.
For example, this observation counts the number of a times the player table is modified:
var count = 0 let reducer = AnyValueReducer( fetch: { _ in }, value: { _ -> Int? in count += 1 return count }) let observation = ValueObservation.tracking(Player.all(), reducer: reducer) let observer = observation.start(in: dbQueue) { count: Int in print("Players have been modified \(count) times.") }The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
startis deallocated.
Declaration
Swift
public static func tracking( _ regions: DatabaseRegionConvertible..., reducer: Reducer) -> ValueObservationParameters
regionsA list of observed regions.
reducerA reducer that turns database changes in the modified regions into fresh values. Currently only reducers that adopt the ValueReducer protocol are supported.
- When started with the
-
Returns a ValueObservation which transforms the values returned by this ValueObservation.
Declaration
Swift
public func map<T>(_ transform: @escaping (Reducer.Value) -> T) -> ValueObservation<MapValueReducer<Reducer, T>>
-
Creates a ValueObservation which observes regions, and notifies the values returned by the fetch closure whenever one of the observed regions is modified by a database transaction.
For example:
let observation = ValueObservation.tracking( Player.all(), fetch: { db in return try Player.fetchAll(db) }) let observer = try observation.start(in: dbQueue) { player: [Player] in print("Players have changed") }The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
startis deallocated.
Declaration
Swift
public static func tracking<Value>( _ regions: DatabaseRegionConvertible..., fetch: @escaping (Database) throws -> Value) -> ValueObservation<ValueReducers.Raw<Value>>Parameters
regionsA list of observed regions.
fetchA closure that fetches a value.
- When started with the
-
Creates a ValueObservation which observes regions, and notifies the values returned by the fetch closure whenever one of the observed regions is modified by a database transaction. Consecutive equal values are filtered out.
For example:
let observation = ValueObservation.tracking( Player.all(), fetchDistinct: { db in return try Player.fetchAll(db) }) let observer = try observation.start(in: dbQueue) { player: [Player] in print("Players have changed") }The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
startis deallocated.
Declaration
Swift
public static func tracking<Value>( _ regions: DatabaseRegionConvertible..., fetchDistinct fetch: @escaping (Database) throws -> Value) -> ValueObservation<ValueReducers.Distinct<Value>> where Value: EquatableParameters
regionsA list of observed regions.
fetchA closure that fetches a value.
- When started with the
-
Starts the value observation in the provided database reader (such as a database queue or database pool), and returns a transaction observer.
Declaration
Swift
public func start( in reader: DatabaseReader, onError: ((Error) -> Void)? = nil, onChange: @escaping (Reducer.Value) -> Void) throws -> TransactionObserverParameters
readerA DatabaseReader.
onErrorA closure that is provided eventual errors that happen during observation
onChangeA closure that is provided fresh values
Return Value
a TransactionObserver
-
Creates a ValueObservation which observes request, and notifies its count whenever it is modified by a database transaction.
For example:
let request = Player.all() let observation = ValueObservation.trackingCount(request) let observer = try observation.start(in: dbQueue) { count: Int in print("Number of players has changed") }The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
startis deallocated.
Declaration
Swift
public static func trackingCount<Request: FetchRequest>(_ request: Request) -> ValueObservation<ValueReducers.Distinct<Int>>Parameters
requestthe observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies fresh rows whenever the request is modified by a database transaction.
For example:
let request = SQLRequest<Row>("SELECT * FROM player") let observation = ValueObservation.trackingAll(request) let observer = try observation.start(in: dbQueue) { rows: [Row] in print("Players have changed") }The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
startis deallocated.
Declaration
Swift
public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<ValueReducers.Distinct<[Row]>> where Request.RowDecoder == RowParameters
requestthe observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies a fresh row whenever the request is modified by a database transaction.
For example:
let request = SQLRequest<Row>("SELECT * FROM player WHERE id = ?", arguments: [1]) let observation = ValueObservation.trackingOne(request) let observer = try observation.start(in: dbQueue) { row: Row? in print("Players have changed") }The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
startis deallocated.
Declaration
Swift
public static func trackingOne<Request: FetchRequest>(_ request: Request) -> ValueObservation<ValueReducers.Distinct<Row?>> where Request.RowDecoder == RowParameters
requestthe observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies fresh records whenever the request is modified by a database transaction.
For example:
let request = Player.all() let observation = ValueObservation.trackingAll(request) let observer = try observation.start(in: dbQueue) { players: [Player] in print("Players have changed") }The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
startis deallocated.
Declaration
Swift
public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<ValueReducers.Records<Request.RowDecoder>> where Request.RowDecoder: FetchableRecordParameters
requestthe observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies a fresh record whenever the request is modified by a database transaction.
For example:
let request = Player.filter(key: 1) let observation = ValueObservation.trackingOne(request) let observer = try observation.start(in: dbQueue) { player: Player? in print("Player has changed") }The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
startis deallocated.
Declaration
Swift
public static func trackingOne<Request: FetchRequest>(_ request: Request) -> ValueObservation<ValueReducers.Record<Request.RowDecoder>> where Request.RowDecoder: FetchableRecordParameters
requestthe observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies fresh values whenever the request is modified by a database transaction.
For example:
let request = Player.select(Column("name"), as: String.self) let observation = ValueObservation.trackingAll(request) let observer = try observation.start(in: dbQueue) { names: [String] in print("Player names have changed") }The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
startis deallocated.
Declaration
Swift
public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<ValueReducers.Values<Request.RowDecoder>> where Request.RowDecoder: DatabaseValueConvertibleParameters
requestthe observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies a fresh value whenever the request is modified by a database transaction.
For example:
let request = Player.select(max(Column("score")), as: Int.self) let observation = ValueObservation.trackingOne(request) let observer = try observation.start(in: dbQueue) { maxScore: Int? in print("Maximum score has changed") }The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
startis deallocated.
Declaration
Swift
public static func trackingOne<Request: FetchRequest>(_ request: Request) -> ValueObservation<ValueReducers.Value<Request.RowDecoder>> where Request.RowDecoder: DatabaseValueConvertibleParameters
requestthe observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies fresh values whenever the request is modified by a database transaction.
For example:
let request = Player.select(Column("name"), as: Optional<String>.self) let observation = ValueObservation.trackingAll(request) let observer = try observation.start(in: dbQueue) { names: [String?] in print("Player names have changed") }The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
startis deallocated.
Declaration
Swift
public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<ValueReducers.OptionalValues<Request.RowDecoder._Wrapped>> where Request.RowDecoder: _OptionalProtocol, Request.RowDecoder._Wrapped: DatabaseValueConvertibleParameters
requestthe observed request.
Return Value
a ValueObservation.
- When started with the
View on GitHub
Install in Dash
ValueObservation Structure Reference