Open richard457 opened 3 years ago
It was in the works, but with the new "stable" release of Dart they introduced some breaking changes in dart:ffi, Changes that somehow I had no idea are coming even though I develop and test on the master branch.
It's in the works.
@Rudiksz looked at the codebase, but I think in order for me to contribute, it's good if we can have a talk so we can have some common understanding.
I have almost completed the migration and I hope I'll be able to publish the new version this week.
@Rudiksz I really like this package and I am doing extensive experiments with it, will be happy to write documentation and some writing about it and also to contribute moving forward. Looking to #null safety
You can find a prerelease on the ffi1.0 branch: https://github.com/Rudiksz/couchbase_lite_dart/tree/ffi1.0
Pub release: https://pub.dev/packages/couchbase_lite_dart/versions/0.5.0-nullsafety.2
A few things to note:
No API changes were made so it should work with existing code, as long as the code is null-safe.
Added empty
constructors the Database, Document, Query and Replicator classes to create 'empty' classes - this needs some extra testing.
@Rudiksz Thanks for the good work, doing testing with the existing app now.
Tested the new API here is my finding
1) The API did not change ( :) happy)
Yes. but with a big caveat. While it's nullsafe for Dart, it is definitely not null-safe yet, and there's a few extra internal checks I need to implement to make the C memory management truly nullsafe. At the moment you should consider every class (Database, Document, Query, Replicator) as nullable and use their isEmpty
method before performing operations on them - unless you know for sure you initialised them. isEmpty
basically checks that the underlying C pointer is not a nullpointer. There are still some cases that would cause a hard crash on the C side. It's definitely not production ready yet.
I'm still deciding how to handle these checks on the Dart side. Take the following Query class for example.
final query = Query.empty();
final string = query.explain();
This will crash the app with a nullptr exception. Of course I will add a guard in the method, but the question is: should it throw a Dart excpetion, or just fail silently and return an empty string? I'm leaning to the second option, but I'm open to other opinions.
2) When building a windows app the build does not copy the dynlib inbuilt app release so I have to manually copy the folder into the release folder
This was the case also before. When Flutter builds a windws app it only copies the flutter dll at the moment. Maybe there's a gradle setting or something to include custom artifacts in the release folder, but I haven't looked yet.
Flutter's build process does not seem to support bundling dynamic libraries from external packages. All the examples they have is how to link them if you are building an app. Linking in a package and then requiring the package does not automatically link them to you app. That's why you have to manually copy the libraries in your app's folder when you are developing.
What is new I guess, is that the windows dll is no longer bundled with the package, and you need to manually copy it to your app. Just like the android and macos files. I felt there's no reason to keep it separate and it makes the pub package itself much smaller and releases that don't affect the C library (I do have some custom hacks) much leaner to upgrade to.
3) The android does not work (No binaries known)
I uploaded them to the release page. Did some initial testing only for now.
did another deep testing now on the release app, the app works just fine on the same machine where the development is, but then run the same app to another machine it does not work, even when copied the folder "dynlib" in the same folder. I can confirm that the issue is how couchbase_lite_dart is loading .dll files. @Rudiksz
- The API did not change ( :) happy)
Yes. but with a big caveat. While it's nullsafe for Dart, it is definitely not null-safe yet, and there's a few extra internal checks I need to implement to make the C memory management truly nullsafe. At the moment you should consider every class (Database, Document, Query, Replicator) as nullable and use their
isEmpty
method before performing operations on them - unless you know for sure you initialised them.isEmpty
basically checks that the underlying C pointer is not a nullpointer. There are still some cases that would cause a hard crash on the C side. It's definitely not production ready yet.I'm still deciding how to handle these checks on the Dart side. Take the following Query class for example.
final query = Query.empty(); final string = query.explain();
This will crash the app with a nullptr exception. Of course I will add a guard in the method, but the question is: should it throw a Dart excpetion, or just fail silently and return an empty string? I'm leaning to the second option, but I'm open to other opinions.
- When building a windows app the build does not copy the dynlib inbuilt app release so I have to manually copy the folder into the release folder
This was the case also before. When Flutter builds a windws app it only copies the flutter dll at the moment. Maybe there's a gradle setting or something to include custom artifacts in the release folder, but I haven't looked yet.
Flutter's build process does not seem to support bundling dynamic libraries from external packages. All the examples they have is how to link them if you are building an app. Linking in a package and then requiring the package does not automatically link them to you app. That's why you have to manually copy the libraries in your app's folder when you are developing.
What is new I guess, is that the windows dll is no longer bundled with the package, and you need to manually copy it to your app. Just like the android and macos files. I felt there's no reason to keep it separate and it makes the pub package itself much smaller and releases that don't affect the C library (I do have some custom hacks) much leaner to upgrade to.
- The android does not work (No binaries known)
I uploaded them to the release page. Did some initial testing only for now.
This will crash the app with a nullptr exception. Of course I will add a guard in the method, but the question is: should it throw a Dart excpetion, or just fail silently and return an empty string? I'm leaning to the second option, but I'm open to other opinions.
I think for this case failing silently is not bad I like non-blocking error and throwing dart error I guess will break the entire execution
bundling dynamic libraries from external packages
Was looking to this https://pub.dev/packages/external_asset_bundle as a way we can load external library but would like to see other options, still Researching.
bundling dynamic libraries from external packages
Copying the dll file should work, but probably I have to fix in the library, because I changed that part.
@Rudiksz any update?
Try the new 0.5.0-nullsafety.3 version.
Please note that I changed the location of the libraries (again), from dynlib
to vendor/cblite
. This is relative to your project root. I'm not aware of any accepted standard in Dart and Flutter to where to put third party packages, and vendor
being the standard in some other languages I like it more than dynlib
. I will keep support for vendor
even if a different location emerges in the dart community.
Edit: for windows, when distributing exe files, the dll can be either next to the exe file (in the same folder), or in the vendor/cblite
subfolder relative to the exe.
should the .dll files from v.0.5.0-null safety.2 be used? or there are other compiled files for this 0.5.0-nullsafety.3 versions.?
I agree with you, the vendor seems familiar with the developer community
should the .dll files from v.0.5.0-null safety.2 be used? or there are other compiled files for this 0.5.0-nullsafety.3 versions.?
The same same ones are good. There's no other change in this release.