Skip to main content

sqflite_ffi 0.1.1+1 copy "sqflite_ffi: ^0.1.1+1" to clipboard
sqflite_ffi: ^0.1.1+1 copied to clipboard

sqflite ffi based implementation for flutter, sharing the sqflite isolate between isolates using IsolateNameServer.

sqflite_ffi #

sqflite ffi based implementation for flutter, based on sqflite_common_ffi.

Unlike sqflite_common_ffi where each isolate spawns its own sqflite isolate, the sqflite isolate send port is registered using flutter IsolateNameServer so that all the isolates of an application (main isolate, compute, Isolate.run...) share the same sqflite isolate and hence the same database instances (singleInstance works across isolates).

Getting Started #

sqflite_ffi is a (dart only) flutter plugin: at startup SqfliteFfiPlugin.registerWith() is called automatically, initializes ffi (Windows specific setup) and sets sqfliteDatabaseFactoryFfi as the default database factory (unless another factory - for example the native sqflite plugin - is already registered). So the global sqflite API works directly:

import 'package:sqflite_ffi/sqflite_ffi.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  var db = await openDatabase(inMemoryDatabasePath);
  // ...
  await db.close();
}

The factory can also be used explicitly:

Future<Database> openMyDatabase() async {
  var factory = sqfliteDatabaseFactoryFfi;
  return await factory.openDatabase(inMemoryDatabasePath);
}

In background isolates not started by the flutter engine, plugin registration does not happen automatically; either call DartPluginRegistrant.ensureInitialized() or use sqfliteDatabaseFactoryFfi directly.

On the web, no op.

Databases path #

Relative database paths (and getDatabasesPath()) resolve to .dart_tool/sqflite_common_ffi/databases in the current directory, the sqflite_common_ffi default. That is fine when running from the project folder on desktop (flutter run, flutter test) but not in a real application:

  • on Android and iOS the current directory is /, which is not writable, so opening a database fails;
  • on desktop an installed application can be started from any directory.

sqflite_ffi does not depend on path_provider, so set the databases path yourself once in main(), before opening any database, typically with path_provider and path added to your app.

Per platform #

Platform Native sqflite plugin folder path_provider code
Android /data/user/0/<package>/databases join(dirname((await getApplicationSupportDirectory()).path), 'databases')
iOS Documents (await getApplicationDocumentsDirectory()).path
macOS Documents (inside the container for a sandboxed app) (await getApplicationDocumentsDirectory()).path
Linux none join((await getApplicationSupportDirectory()).path, 'databases') (~/.local/share/<application id>/databases)
Windows none join((await getApplicationSupportDirectory()).path, 'databases') (%APPDATA%\<company>\<product>\databases)

Use the native folders to keep the databases of an existing app moving from sqflite to sqflite_ffi:

import 'dart:io';

import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';

/// The folders used by the native sqflite plugin on Android, iOS and macOS,
/// the application support directory on Linux and Windows.
Future<String> sqflitePluginDatabasesPath() async {
  if (Platform.isAndroid) {
    // The files directory and the databases directory share the same parent,
    // the application data directory.
    var supportDir = await getApplicationSupportDirectory();
    return join(dirname(supportDir.path), 'databases');
  } else if (Platform.isIOS || Platform.isMacOS) {
    return (await getApplicationDocumentsDirectory()).path;
  }
  return join((await getApplicationSupportDirectory()).path, 'databases');
}

One location for all platforms #

For a new app, a databases folder in the application support directory works everywhere with the same code. It is private to the application, writable, not shown to the user (unlike Documents on iOS or on a non sandboxed macOS app), and the location used by the sqflite_ffi_test_app:

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite_ffi/sqflite_ffi.dart';

/// A `databases` folder in the application support directory.
Future<String> appDatabasesPath() async {
  var supportDir = await getApplicationSupportDirectory();
  return join(supportDir.path, 'databases');
}

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  if (!kIsWeb) {
    await databaseFactory.setDatabasesPath(await appDatabasesPath());
  }
  // Relative paths now resolve in the application support directory.
  var db = await openDatabase('app.db');
  // ...
}

The path is set on the factory of the isolate calling setDatabasesPath. In a compute or Isolate.run callback, pass the full database path (from join(await getDatabasesPath(), 'app.db') in the main isolate) rather than a relative one.

0
likes
160
points
480
downloads

Documentation

API reference

Publisher

verified publishertekartik.com

Weekly Downloads

sqflite ffi based implementation for flutter, sharing the sqflite isolate between isolates using IsolateNameServer.

Repository (GitHub)
View/report issues

Topics

#sql #database

Funding

Consider supporting this project:

github.com

License

BSD-2-Clause (license)

Dependencies

flutter, sqflite_common_ffi

More

Packages that depend on sqflite_ffi

Packages that implement sqflite_ffi