diff --git a/sqflite_common_ffi/lib/src/windows/setup.dart b/sqflite_common_ffi/lib/src/windows/setup.dart index f8e69729..ef4786ce 100644 --- a/sqflite_common_ffi/lib/src/windows/setup.dart +++ b/sqflite_common_ffi/lib/src/windows/setup.dart @@ -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) { @@ -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; } diff --git a/sqflite_common_ffi/lib/windows/sqflite_ffi_setup.dart b/sqflite_common_ffi/lib/windows/sqflite_ffi_setup.dart index f6348a4c..20f4ae78 100644 --- a/sqflite_common_ffi/lib/windows/sqflite_ffi_setup.dart +++ b/sqflite_common_ffi/lib/windows/sqflite_ffi_setup.dart @@ -2,4 +2,4 @@ library; export 'package:sqflite_common_ffi/src/windows/setup.dart' - show findWindowsSqlite3DllPath; + show findWindowsSqlite3DllPath, findWindowsSqlite3DllPathFromPath; diff --git a/sqflite_common_ffi/test/sqflite_ffi_windows_setup_test.dart b/sqflite_common_ffi/test/sqflite_ffi_windows_setup_test.dart index a23092e4..234491bc 100644 --- a/sqflite_common_ffi/test/sqflite_ffi_windows_setup_test.dart +++ b/sqflite_common_ffi/test/sqflite_ffi_windows_setup_test.dart @@ -43,6 +43,7 @@ Future windowsFindOpenssl() async { } void main() { + var dllPath = findWindowsSqlite3DllPath()!; var helper = Sqlite3DllSetupHelper(sqlite3Info); var srcZip = sqlite3Info.srcZip; var localZip = join('.local', basename(srcZip)); @@ -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); @@ -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); + } + }); }); } diff --git a/sqflite_common_test/test/setup_impl_test.dart b/sqflite_common_test/test/setup_impl_test.dart index 84847108..8c0ae4d5 100644 --- a/sqflite_common_test/test/setup_impl_test.dart +++ b/sqflite_common_test/test/setup_impl_test.dart @@ -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); }); }); }