createBackgroundConnection static method

DatabaseConnection createBackgroundConnection(
  1. File file, {
  2. bool logStatements = false,
  3. DatabaseSetup? setup,
  4. IsolateSetup? isolateSetup,
  5. bool enableMigrations = true,
  6. bool cachePreparedStatements = _cacheStatementsByDefault,
  7. int readPool = _defaultReadPoolSize,
})

Like createInBackground, except that it returns the whole DatabaseConnection instead of just the executor.

This creates a database writing data to the given file. The database runs in a background isolate and is stopped when closed.

Implementation

static DatabaseConnection createBackgroundConnection(
  File file, {
  bool logStatements = false,
  DatabaseSetup? setup,
  IsolateSetup? isolateSetup,
  bool enableMigrations = true,
  bool cachePreparedStatements = _cacheStatementsByDefault,
  int readPool = _defaultReadPoolSize,
}) {
  RangeError.checkNotNegative(readPool);

  return DatabaseConnection.delayed(Future.sync(() async {
    final receiveIsolate = ReceivePort();
    final receive = StreamQueue(receiveIsolate.cast<DriftIsolate>());

    Future<void> spawnIsolate(String kind) async {
      await Isolate.spawn(
        _NativeIsolateStartup.start,
        _NativeIsolateStartup(
          file.absolute.path,
          logStatements,
          cachePreparedStatements,
          enableMigrations,
          setup,
          isolateSetup,
          receiveIsolate.sendPort,
        ),
        debugName: 'Drift isolate $kind for ${file.path}',
      );
    }

    await spawnIsolate('worker');
    final driftIsolate = await receive.next;

    var connection = await driftIsolate.connect(singleClientMode: true);
    if (readPool != 0) {
      final readers = <QueryExecutor>[];

      for (var i = 0; i < readPool; i++) {
        await spawnIsolate('reader');
      }

      for (var i = 0; i < readPool; i++) {
        final spawned = await receive.next;
        readers.add(await spawned.connect(singleClientMode: true));
      }

      connection = DatabaseConnection(
        MultiExecutor.withReadPool(
          reads: readers,
          write: connection.executor,
        ),
        streamQueries: connection.streamQueries,
        connectionData: connection.connectionData,
      );
    }

    await receive.cancel();
    receiveIsolate.close();
    return connection;
  }));
}