Skip to content

Commit

Permalink
[sqflite_commmon_ffi] fix sqlite3 dll resolving
Browse files Browse the repository at this point in the history
  • Loading branch information
alextekartik committed Oct 17, 2024
1 parent 047f4df commit 5b81d9d
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 22 deletions.
84 changes: 66 additions & 18 deletions sqflite_common_ffi/lib/src/windows/setup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void windowsInit() {
sqlite3.openInMemory().dispose();
}

/// Find sqflite_common_ffi path
/// Find sqflite_common_ffi path from a repository path
///
/// Return null if not found
String? findPackageLibPath(String path) {
Expand All @@ -60,29 +60,77 @@ String? findPackageLibPath(String path) {
return null;
}

/// Secret trick to find the windows dll path from a given path
/// It looks for a parent (or same directory) pubspec.lock file
/// to resolve the sqflite_common_ffi package
String? findWindowsSqlite3DllPathFromPath(String path) {
try {
path = normalize(absolute(path));
var packageTopPath = findCurrentPackageTopPath(path);
if (packageTopPath != null) {
var libPath = findPackageLibPath(packageTopPath);
if (libPath != null) {
var sqlite3DllPath = packageGetSqlite3DllPath(libPath);
if (File(sqlite3DllPath).existsSync()) {
return sqlite3DllPath;
}
}
}
} catch (_) {}
return null;
}

///
/// checking recursively to find a valid parent directory
///
String? pathFindTopLevelPath(String path,
{required bool Function(String path) pathIsTopLevel}) {
path = normalize(absolute(path));
String parent;
while (true) {
if (FileSystemEntity.isDirectorySync(path)) {
if (pathIsTopLevel(path)) {
return path;
}
}
parent = dirname(path);
if (parent == path) {
break;
}
path = parent;
}
return null;
}

/// Look for pubspec.lock file
/// Which seems the safest to handle package in global pub too
String? findCurrentPackageTopPath(String path) {
return pathFindTopLevelPath(path, pathIsTopLevel: (path) {
var lockFile = File(join(path, 'pubspec.lock'));
if (lockFile.existsSync()) {
return true;
}
return false;
});
}

/// Compat
String? findWindowsDllPath() => findWindowsSqlite3DllPath();

/// Find windows dll path.
String? findWindowsSqlite3DllPath() {
var location = findPackageLibPath(Directory.current.path);
if (location == null) {
// Try to handle when using global run
// When using `global run` we might not be able to find the lib path.
// Try from the script
// when running using global run: file:///C:/oxxxdevx/git/github.com/tekartik/sqflite/packages/console_test_app/.dart_tool/pub/bin/sqflite_ffi_console_test_app/sqflite_ffi_simple_bin.dart-2.19.0.snapshot
// when running normally: C:\xxx\devx\git\github.com\tekartik\sqflite\packages\console_test_app\bin\sqflite_ffi_simple_bin.dart
// When running hoster: C:\Users\xxx\AppData\Local\Pub\Cache\bin\pubglobalupdate.bat
try {
// This the case when activated from path...ugly but worth trying.
var projectPath = dirname(
dirname(dirname(dirname(dirname(Platform.script.toFilePath())))));
location = findPackageLibPath(projectPath);
} catch (_) {}
/// Try to look from the current path
/// Handles and dart script ran withing a project importing sqflite_common_ffi
var dllPath = findWindowsSqlite3DllPathFromPath(Directory.current.path);
if (dllPath != null) {
return dllPath;
}
if (location != null) {
var path = packageGetSqlite3DllPath(normalize(join(location)));
return path;

/// Try to look from the script path, handles script using global run
dllPath = findWindowsSqlite3DllPathFromPath(Platform.script.toFilePath());
if (dllPath != null) {
return dllPath;
}

return null;
}
2 changes: 1 addition & 1 deletion sqflite_common_ffi/lib/windows/sqflite_ffi_setup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
library;

export 'package:sqflite_common_ffi/src/windows/setup.dart'
show findWindowsSqlite3DllPath;
show findWindowsSqlite3DllPath, findWindowsSqlite3DllPathFromPath;
12 changes: 11 additions & 1 deletion sqflite_common_ffi/test/sqflite_ffi_windows_setup_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Future<String?> windowsFindOpenssl() async {
}

void main() {
var dllPath = findWindowsSqlite3DllPath()!;
var helper = Sqlite3DllSetupHelper(sqlite3Info);
var srcZip = sqlite3Info.srcZip;
var localZip = join('.local', basename(srcZip));
Expand All @@ -63,7 +64,6 @@ void main() {
});

test('checkDll', () async {
var dllPath = findWindowsDllPath()!;
if (await helper.getZip()) {
final inputStream = InputFileStream(localZip);
final archive = ZipDecoder().decodeBuffer(inputStream);
Expand All @@ -75,5 +75,15 @@ void main() {
expect(existingDllContent, downloadedDllContent);
}
});

test('findWindowsSqlite3DllPathFromPath', () async {
expect(findWindowsSqlite3DllPathFromPath('.'), dllPath);
expect(findWindowsSqlite3DllPathFromPath('test'), dllPath);
var path = join('..', 'sqflite_common_test');
if (Directory(path).existsSync()) {
expect(findWindowsSqlite3DllPathFromPath(path), dllPath);
expect(findWindowsSqlite3DllPathFromPath(join(path, 'test')), dllPath);
}
});
});
}
4 changes: 2 additions & 2 deletions sqflite_common_test/test/setup_impl_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ library;

import 'dart:io';

import 'package:sqflite_common_ffi/src/windows/setup.dart';
import 'package:sqflite_common_ffi/windows/sqflite_ffi_setup.dart';
import 'package:test/test.dart';

void main() {
group('setup', () {
test('findWindowsDllPath', () {
expect(File(findWindowsDllPath()!).existsSync(), isTrue);
expect(File(findWindowsSqlite3DllPath()!).existsSync(), isTrue);
});
});
}

0 comments on commit 5b81d9d

Please sign in to comment.