Skip to content

Commit

Permalink
[sqflite] fix multi factory path issue
Browse files Browse the repository at this point in the history
  • Loading branch information
alextekartik committed Jul 28, 2024
1 parent 377040a commit b0033c4
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 23 deletions.
2 changes: 1 addition & 1 deletion app_sqflite/lib/sqflite.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ DatabaseFactory get databaseFactory => src.databaseFactory;

/// Get the database factory for a given package (setting in home path)
///
/// [packageName] or [rootPath] only used on linux and windows for now
/// [packageName] or [rootPath] only used on desktop (linux, windows and mac) for now
///
/// autoInit is sqflite_ffi on windows
DatabaseFactory getDatabaseFactory(
Expand Down
2 changes: 1 addition & 1 deletion app_sqflite/lib/src/sqflite.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export 'sqflite_stub.dart'
if (dart.library.html) 'sqflite_web.dart'
if (dart.library.js_interop) 'sqflite_web.dart'
if (dart.library.io) 'sqflite_io.dart';
101 changes: 80 additions & 21 deletions app_sqflite/lib/src/sqflite_io.dart
Original file line number Diff line number Diff line change
@@ -1,36 +1,95 @@
import 'dart:io';
import 'dart:typed_data';

import 'package:path/path.dart';
import 'package:process_run/process_run.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';

String buildDatabasesPath(String packageName) {
var dataPath = join(userAppDataPath, packageName, 'databases');
try {
var dir = Directory(dataPath);
if (!dir.existsSync()) {
dir.createSync(recursive: true);
}
} catch (_) {}
return dataPath;
}
import 'package:sqflite_common/sqflite.dart' as sqflite;
import 'package:sqflite_common_ffi/sqflite_ffi.dart' as ffi;

DatabaseFactory get _defaultDatabaseFactory => databaseFactoryFfi;
sqflite.DatabaseFactory get _defaultDatabaseFactory =>
// ignore: invalid_use_of_visible_for_testing_member
sqflite.databaseFactoryOrNull ?? ffi.databaseFactoryFfi;

/// All but Linux/Windows
DatabaseFactory get databaseFactory => _defaultDatabaseFactory;
sqflite.DatabaseFactory get databaseFactory => _defaultDatabaseFactory;

/// Use sqflite on any platform
DatabaseFactory getDatabaseFactory(
sqflite.DatabaseFactory getDatabaseFactory(
{String? packageName, String? rootPath, bool autoInit = true}) {
var databaseFactory = databaseFactoryFfi;
if (autoInit) {
sqfliteWindowsFfiInit();
}
// Should not return a future...or ignore
databaseFactory
.setDatabasesPath(rootPath ?? buildDatabasesPath(packageName ?? '.'));
return databaseFactory;
if ((Platform.isMacOS || Platform.isLinux || Platform.isWindows) &&
(packageName != null || rootPath != null)) {
return _DatabaseFactory(
packageName: packageName,
rootPath: rootPath,
delegate: databaseFactory);
} else {
return databaseFactory;
}
}

void sqfliteWindowsFfiInit() => sqfliteFfiInit();
void sqfliteWindowsFfiInit() => ffi.sqfliteFfiInit();

class _DatabaseFactory implements sqflite.DatabaseFactory {
final String? packageName;
final String? rootPath;
final sqflite.DatabaseFactory delegate;
late final String databasesPath;
_DatabaseFactory(
{required this.packageName,
required this.rootPath,
required this.delegate}) {
databasesPath = packageName != null
? join(userAppDataPath, packageName, 'databases')
: rootPath!;
}

String _fixPath(String path) {
if (!isAbsolute(path)) {
path = join(databasesPath, path);
}
return path;
}

String _fixAndCreatePath(String path) {
path = _fixPath(path);
try {
var dir = Directory(dirname(path));
if (!dir.existsSync()) {
dir.createSync(recursive: true);
}
} catch (_) {}
return path;
}

@override
Future<bool> databaseExists(String path) =>
delegate.databaseExists(_fixPath(path));

@override
Future<void> deleteDatabase(String path) =>
delegate.deleteDatabase(_fixPath(path));

@override
Future<String> getDatabasesPath() async => databasesPath;

@override
Future<sqflite.Database> openDatabase(String path,
{sqflite.OpenDatabaseOptions? options}) =>
delegate.openDatabase(_fixAndCreatePath(path), options: options);

@override
Future<Uint8List> readDatabaseBytes(String path) =>
delegate.readDatabaseBytes(_fixPath(path));

@override
Future<void> setDatabasesPath(String path) async {
databasesPath = path;
}

@override
Future<void> writeDatabaseBytes(String path, Uint8List bytes) =>
delegate.writeDatabaseBytes(_fixAndCreatePath(path), bytes);
}
5 changes: 5 additions & 0 deletions app_sqflite/lib/src/sqflite_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ DatabaseFactory getDatabaseFactory(
/// Only needed/implemented on windows
void sqfliteWindowsFfiInit() => _stub('sqfliteWindowsFfiInit');

/// no op on the web
String getDatabasePath(String databasePath,
{String? packageName, String? rootPath}) =>
databasePath;

T _stub<T>(String message) {
throw UnimplementedError(message);
}

0 comments on commit b0033c4

Please sign in to comment.