putQueuedAwaitResult method

  1. @Deprecated("Use putAsync which supports relations, or for a large number of parallel calls putQueued.")
Future<int> putQueuedAwaitResult(
  1. T object, {
  2. PutMode mode = PutMode.put,
})

Like putQueued, but waits on the put to complete.

For typical use cases, use putAsync instead which supports objects with relations. Use this when a large number of puts needs to be performed in parallel (e.g. this is called many times) for better performance. But then putQueued will achieve even better performance as it does not have to notify all callers of completion.

The returned future completes with an ID of the object. If it is a new object (its ID property is 0), a new ID will be assigned to object, after the returned Future completes.

In extreme scenarios (e.g. having hundreds of thousands async operations per second), this may fail as internal queues fill up if the disk can't keep up. However, this should not be a concern for typical apps.

The returned future may complete with an error if the put failed for another reason, for example a unique constraint violation. In that case the object's id field remains unchanged (0 if it was a new object).

See also putQueued which doesn't return a Future but a pre-allocated ID immediately, even though the actual database put operation may fail.

Implementation

@Deprecated(
    "Use putAsync which supports relations, or for a large number of parallel calls putQueued.")
Future<int> putQueuedAwaitResult(T object,
        {PutMode mode = PutMode.put}) async =>
    // Wrap with [Future.sync] to avoid mixing sync and async errors.
    // Note: doesn't seem to decrease performance at all.
    // https://dart.dev/guides/libraries/futures-error-handling#potential-problem-accidentally-mixing-synchronous-and-asynchronous-errors
    Future.sync(() async {
      if (_hasRelations) {
        throw UnsupportedError(
            'putAsync() is currently not supported on entity '
            '${T.toString()} because it has relations.');
      }
      _async ??= _AsyncBoxHelper(this);

      // Note: we can use the shared flatbuffer object, because:
      // https://dart.dev/codelabs/async-await#execution-flow-with-async-and-await
      // > An async function runs synchronously until the first await keyword.
      // > This means that within an async function body, all synchronous code
      // > before the first await keyword executes immediately.
      _builder.fbb.reset();
      var id = _entity.objectToFB(object, _builder.fbb);
      final newId = _async!.put(id, _builder, mode);
      _builder.resetIfLarge(); // reset before `await`
      if (id == 0) {
        // Note: if the newId future completes with an error, ID isn't set.
        _entity.setId(object, await newId);
      }
      return newId;
    });