createBackgroundConnection static method

DatabaseConnection createBackgroundConnection(
  1. File file, {
  2. bool logStatements = false,
  3. bool isolateDebugLog = false,
  4. DatabaseSetup? setup,
  5. SqliteResolver sqlite3 = _NativeDelegate._defaultResolver,
  6. IsolateSetup? isolateSetup,
  7. bool enableMigrations = true,
  8. bool cachePreparedStatements = _cacheStatementsByDefault,
  9. 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,
  bool isolateDebugLog = false,
  DatabaseSetup? setup,
  SqliteResolver sqlite3 = _NativeDelegate._defaultResolver,
  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(
            path: file.absolute.path,
            enableLogs: logStatements,
            cachePreparedStatements: cachePreparedStatements,
            enableMigrations: enableMigrations,
            setup: setup,
            isolateSetup: isolateSetup,
            sqlite3: sqlite3,
            sendServer: receiveIsolate.sendPort,
          ),
          debugName: 'Drift isolate $kind for ${file.path}',
        );
      }

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

      var connection = await driftIsolate.connect(
        singleClientMode: true,
        isolateDebugLog: isolateDebugLog,
      );
      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,
              isolateDebugLog: isolateDebugLog,
            ),
          );
        }

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

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