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
-
scheduling
controls 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
startImmediately
is true.unsafe(startImmediately:)
: values are not all notified on the same dispatch queue.If
startImmediately
is 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
-
Undocumented
Declaration
Swift
public static func combine<R1: ValueReducer, R2: ValueReducer>( _ o1: ValueObservation<R1>, _ o2: ValueObservation<R2>) -> ValueObservation<AnyValueReducer< (R1.Fetched, R2.Fetched), (R1.Value, R2.Value)>>
-
Undocumented
Declaration
Swift
public static func combine<R1: ValueReducer, R2: ValueReducer, R3: ValueReducer>( _ o1: ValueObservation<R1>, _ o2: ValueObservation<R2>, _ o3: ValueObservation<R3>) -> ValueObservation<AnyValueReducer< (R1.Fetched, R2.Fetched, R3.Fetched), (R1.Value, R2.Value, R3.Value)>>
-
Undocumented
Declaration
Swift
public static func combine<R1: ValueReducer, R2: ValueReducer, R3: ValueReducer, R4: ValueReducer>( _ o1: ValueObservation<R1>, _ o2: ValueObservation<R2>, _ o3: ValueObservation<R3>, _ o4: ValueObservation<R4>) -> ValueObservation<AnyValueReducer< (R1.Fetched, R2.Fetched, R3.Fetched, R4.Fetched), (R1.Value, R2.Value, R3.Value, R4.Value)>>
-
Undocumented
Declaration
Swift
public static func combine<R1: ValueReducer, R2: ValueReducer, R3: ValueReducer, R4: ValueReducer, R5: ValueReducer>( _ o1: ValueObservation<R1>, _ o2: ValueObservation<R2>, _ o3: ValueObservation<R3>, _ o4: ValueObservation<R4>, _ o5: ValueObservation<R5>) -> ValueObservation<AnyValueReducer< (R1.Fetched, R2.Fetched, R3.Fetched, R4.Fetched, R5.Fetched), (R1.Value, R2.Value, R3.Value, R4.Value, R5.Value)>>
-
Returns a ValueObservation which notifies the non-nil results of calling the given transformation which each element notified by this value observation.
Declaration
Swift
public func compactMap<T>(_ transform: @escaping (Reducer.Value) -> T?) -> ValueObservation<CompactMapValueReducer<Reducer, T>>
-
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
start
is deallocated.
Declaration
Swift
public static func trackingCount<Request: FetchRequest>(_ request: Request) -> ValueObservation<DistinctUntilChangedValueReducer<RawValueReducer<Int>>>
Parameters
request
the 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
start
is deallocated.
Declaration
Swift
public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<DatabaseValuesReducer<Request>> where Request.RowDecoder: DatabaseValueConvertible
Parameters
request
the 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
start
is deallocated.
Declaration
Swift
public static func trackingOne<Request: FetchRequest>(_ request: Request) -> ValueObservation<DatabaseValueReducer<Request>> where Request.RowDecoder: DatabaseValueConvertible
Parameters
request
the 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
start
is deallocated.
Declaration
Swift
public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<OptionalDatabaseValuesReducer<Request>> where Request.RowDecoder: _OptionalProtocol, Request.RowDecoder._Wrapped: DatabaseValueConvertible
Parameters
request
the observed request.
Return Value
a ValueObservation.
- When started with the
-
Returns a ValueObservation which filters out consecutive equal values.
Declaration
Swift
public func distinctUntilChanged() -> ValueObservation<DistinctUntilChangedValueReducer<Reducer>>
-
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
start
is deallocated.
Declaration
Swift
public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<FetchableRecordsReducer<Request.RowDecoder>> where Request.RowDecoder: FetchableRecord
Parameters
request
the 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
start
is deallocated.
Declaration
Swift
public static func trackingAll<Record: FetchableRecord>(_ request: QueryInterfaceRequest<Record>) -> ValueObservation<FetchableRecordsReducer<Record>>
Parameters
request
the 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
start
is deallocated.
Declaration
Swift
public static func trackingOne<Request: FetchRequest>(_ request: Request) -> ValueObservation<FetchableRecordReducer<Request.RowDecoder>> where Request.RowDecoder: FetchableRecord
Parameters
request
the 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
start
is deallocated.
Declaration
Swift
public static func trackingOne<Record: FetchableRecord>(_ request: QueryInterfaceRequest<Record>) -> ValueObservation<FetchableRecordReducer<Record>>
Parameters
request
the observed request.
Return Value
a ValueObservation.
- When started with the
-
Returns a ValueObservation which notifies the results of calling the given transformation which each element notified by this value observation.
Declaration
Swift
public func map<T>(_ transform: @escaping (Reducer.Value) -> T) -> ValueObservation<MapValueReducer<Reducer, T>>
-
Returns a ValueObservation with a transformed reducer.
Declaration
Swift
public func mapReducer<R>(_ transform: @escaping (Database, Reducer) throws -> R) -> ValueObservation<R>
-
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>(sql: "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
start
is deallocated.
Declaration
Swift
public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<RowsReducer> where Request.RowDecoder == Row
Parameters
request
the 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>(sql: "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
start
is deallocated.
Declaration
Swift
public static func trackingAll(_ request: QueryInterfaceRequest<Row>) -> ValueObservation<RowsReducer>
Parameters
request
the 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>(sql: "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
start
is deallocated.
Declaration
Swift
public static func trackingOne<Request: FetchRequest>(_ request: Request) -> ValueObservation<RowReducer> where Request.RowDecoder == Row
Parameters
request
the 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>(sql: "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
start
is deallocated.
Declaration
Swift
public static func trackingOne(_ request: QueryInterfaceRequest<Row>) -> ValueObservation<RowReducer>
Parameters
request
the observed request.
Return Value
a ValueObservation.
- 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 -> TransactionObserver
Parameters
reader
A DatabaseReader.
onError
A closure that is provided eventual errors that happen during observation
onChange
A closure that is provided fresh values
Return Value
a TransactionObserver
-
Returns 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 /* don't fetch anything */ }, value: { _ -> Int? in defer { count += 1 } return count }) let observation = ValueObservation.tracking(Player.all(), reducer: { db in 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
start
is deallocated.
Declaration
Swift
public static func tracking( _ regions: DatabaseRegionConvertible..., reducer: @escaping (Database) throws -> Reducer) -> ValueObservation
Parameters
regions
A list of observed regions.
reducer
A 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 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 /* don't fetch anything */ }, value: { _ -> Int? in defer { count += 1 } return count }) let observation = ValueObservation.tracking([Player.all()], reducer: { db in 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
start
is deallocated.
Declaration
Swift
public static func tracking( _ regions: [DatabaseRegionConvertible], reducer: @escaping (Database) throws -> Reducer) -> ValueObservation
Parameters
regions
A list of observed regions.
reducer
A 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
-
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) { 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
start
is deallocated.
Declaration
Swift
public static func tracking<Value>( _ regions: DatabaseRegionConvertible..., fetch: @escaping (Database) throws -> Value) -> ValueObservation<RawValueReducer<Value>>
Parameters
regions
A list of observed regions.
fetch
A 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.
For example:
let observation = ValueObservation.tracking( [Player.all()], fetch: { db in return try Player.fetchAll(db) }) 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
start
is deallocated.
Declaration
Swift
public static func tracking<Value>( _ regions: [DatabaseRegionConvertible], fetch: @escaping (Database) throws -> Value) -> ValueObservation<RawValueReducer<Value>>
Parameters
regions
A list of observed regions.
fetch
A closure that fetches a value.
- When started with the