joinIterate<JK extends SdbKey, JV extends SdbValue> method

Future<void> joinIterate<JK extends SdbKey, JV extends SdbValue>(
  1. SdbClient client, {
  2. required SdbJoinTarget<JK, JV> target,
  3. SdbTransactionMode? mode,
  4. SdbFindOptions<SK>? options,
  5. SdbJoinFindOptions? joinOptions,
  6. required SdbJoinRowHandler<K, V, JK, JV> onRow,
})

Iterate the records of this source, each with the record(s) it references.

The order is the one of the source: primary key order for a store, index key order for an index (the rows sharing a join key are then consecutive).

target is what the join key is matched against: a store, on its primary key (at most one record), or an index, on its index key (any number of records, a source record then giving one row per match, the way an sql join does). Build it with authorStore.asJoinTarget or authorEmailIndex.asJoinTarget.

The join key is the index key for an index source, and for a store source the value at the key path of asJoinSourceAt, or its primary key when the source was built with asJoinSource.

This is a left join: a record whose join key is null, or whose join key matches nothing, is still handed to onRow with a null SdbJoinRow.joinedRecord. Pass inner: true in a SdbJoinFindOptions to skip those rows.

options.offset and options.limit apply to the rows handed to onRow, i.e. after inner and distinct dropped any row, the way an sql LIMIT applies after the join. Its boundaries apply to the key the source is walked by.

If client is a transaction, it must cover both stores, and its mode must match mode (asking for write mode on a read only transaction fails).

onRow returns false to stop the iteration. Like in a transaction, no lengthy operation should be performed there, but the database can be accessed.

Implementation

Future<void> joinIterate<JK extends SdbKey, JV extends SdbValue>(
  SdbClient client, {
  required SdbJoinTarget<JK, JV> target,
  SdbTransactionMode? mode,
  SdbFindOptions<SK>? options,
  SdbJoinFindOptions? joinOptions,
  required SdbJoinRowHandler<K, V, JK, JV> onRow,
}) => _joinRun<JK, JV>(
  client,
  target: target,
  mode: mode,
  options: options,
  joinOptions: joinOptions,
  emit: SdbJoinEmit.rows,
  onEmit: (row) => onRow(row.asRow()),
);