medz / prisma-dart

Prisma Client Dart is an auto-generated type-safe ORM. It uses Prisma Engine as the data access layer and is as consistent as possible with the Prisma Client JS/TS APIs.
https://prisma.pub
BSD 3-Clause "New" or "Revised" License
450 stars 30 forks source link

Support Flutter App #328

Open medz opened 8 months ago

medz commented 8 months ago

Prisma Dart Client was originally built for the Dart server-side, and we look forward to introducing it in Flutter.

Progress

listepo commented 8 months ago

Can not wait:)

medz commented 8 months ago

@listepo Thank you for looking forward to it, but I don't know how long it will take. Prisma officials have revealed that they are experimenting with the C ABI engine, but have not announced the time or plan.

It is not feasible to implement the C ABI engine as a third party because it has already failed once. After the build is completed, the upstream repo is Prisma's internal engine. They have many destructive commits every day, making it difficult for the downstream to maintain it continuously (especially if it is only me. case)

In order to achieve the unification of Dart Server-side and Flutter, WASM is the best choice. But the real problem is that Dart does not have the ability to load WASM natively. Flutter only experimentally allows Flutter code to be compiled into wasm.

Many helplessness and many problems are like mountains before our eyes, making it difficult to overcome.

listepo commented 7 months ago

@medz any news?

medz commented 6 months ago

https://github.com/prisma/prisma-engines/pull/4774

The latest news, the C ABI engine of Prisma Engines. Once it is Merge, I will immediately implement the support of Flutter.

medz commented 5 months ago

news https://github.com/prisma/prisma-engines/pull/4793

listepo commented 5 months ago

is there any success?

medz commented 5 months ago

@listepo

image

It has not been merged yet. Once it is merged to produce the C ABI engine, I will follow up immediately.

medz commented 5 months ago

@listepo I noticed that it has been merged, thank you for bringing this matter to my attention again.

I am following up and looking for any information about the C ABI engine and official examples of its use in RN.

At present, it seems to only support SQLite, but it is sufficient, and most Flutter developers do not want to link to remote databases. SQLite+Prisma can help a large number of developers complete local data structure storage and have intuitive CRUD APIs

listepo commented 5 months ago

@medz I'll be happy to help with testing

kidusdev commented 5 months ago

Hy @medz i am using prisma-dart for my flutter desktop application. I didn't struggle or have error until now. How can i help?

20240417_104930.jpg

20240417_105050.jpg

All the above data table, numbers and authentication is implemented using prisma-dart.

medz commented 5 months ago

Bad news, I still need to implement a C ABI engine myself. But Prisma has provided a great template

listepo commented 5 months ago

@medz How is it going? help is needed?

MulverineX commented 4 months ago

still need to implement a C ABI engine myself

why is that? In what way is theirs unsuited for this library? I'm also curious what your timeline is looking like, and am interested in helping, hopefully more than simply testing & working on #281. After getting https://github.com/openwebf/mercury fully working for my usecase, this library is what I'm waiting on to continue with https://github.com/RefractureMedia/refracture-music

edit: just noticed your status, get well soon! I really appreciate all of the work that you've done thusfar on the library! Also, once funds are a little less tight on my end I plan on setting up recurring Sponsorship for your work on this library, I understand that motivation for open source projects can be pretty tough at times.

MulverineX commented 4 months ago

Another potential route this project could take is use of https://github.com/fzyzcjy/flutter_rust_bridge , which appears to be reaching a reliable, efficient, and cross-platform state.

medz commented 4 months ago

@MulverineX I hope that C Engine can also be applied on the server.

MulverineX commented 4 months ago

What do you mean? flutter_rust_bridge supports server-side Dart applications as well. And as for my other questions?

medz commented 4 months ago

@MulverineX flutter_rust_bridge is useful, but my plan is to write a general C Engine. flutter_rust_bridge will keep my code locked to a certain language, internally I'm using Zig. So I may also release a Zig version of Prisma in the future.

Prisma is officially experimenting with a static version of Android/iOS (only supports sqlite), because the binary engine in the current version has many problems, such as inconsistent messages and the inability to detect the exit of the main process and terminate the binary.

I'm writing it manually in Rust and, if nothing unexpected happens, will probably release it in two months. (I'm experimenting in a private repo, not in this repo to avoid polluting commits)

listepo commented 4 months ago

@medz Is it possible to run the code on only MaсOS with flutter? will the lib api remain the same?

medz commented 4 months ago

@listepo APIs will not change, but customizing the Engine may be a disaster. But usually the Engine is provided for use by the Generator.

listepo commented 4 months ago

Is it possible to add support for the desktop version? like pure dart version for OS? load correct prisma-query-engine now error

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Exception: No query engine binary found (prisma-query-engine) in [/Users/listepo/Library/Containers/com.example.flutterApplication/Data, /Users/listepo/Library/Containers/com.example.flutterApplication/Data/prisma, /Users/listepo/Library/Containers/com.example.flutterApplication/Data/.dart_tool]

put correct file into /Users/listepo/Library/Containers/com.example.flutterApplication/Data or etc

listepo commented 4 months ago

because for the operating system there is no difference, the code is launched only through dart or flutter, I understand why the mobile version doesn't work. Maybe it makes sense to add support for the desktop version first? so people can start experimenting with flutter

MulverineX commented 4 months ago

@listepo the problem is not cross-platform builds, the Prisma team already solved that (they're releasing a React Native module by the end of the month). The problem is that medz is trying to switch this library from running the query engine in child-process, to directly invoking it through FFI calls. Doing that is more difficult because the engine is written in Rust, not cross-platform considerations.

Here's his plan as I understand it:

listepo commented 4 months ago

@medz can you give access to a private repository? I would like to help

MulverineX commented 4 months ago

So would I (alternatively, if you want you could make it a public branch on this repository, and when its done/stable, you can PR it into main with a Squash commit to avoid polluting the commit history)

medz commented 4 months ago

News: https://github.com/prisma/prisma/issues/24295 https://github.com/dart-lang/native/issues/934#issuecomment-1894151501

My implementation: I originally built the C ABI in Rust, but upstream prisma/prisma-engines had too many breaking changes for me to safely maintain (I had to keep an eye on upstream and fix it). Later, I used zig combined with prisma C ABI to create a unified engine for Android/iOS. I gave up because not all developers had zig installed on their computers. Finally, I created the flutter native plug-in directly. The problem I encounter now is that the prisma c abi engine is not a dylib, but a static library. Dart ffi does not support static libraries.

Now I have two options:

  1. Use c/cpp link prisma c abi to re-create the APIs
  2. Use the corresponding platform language to implement it through flutter channel on different platforms.

Pros and cons:

1: The client can be implemented uniformly to reduce maintenance difficulty, but the performance will be greatly reduced. 2: Through flutter channel, call c abi in the native language, no need to worry about performance issues. Channel message uses string for data interaction.

Worrying: Prisma C ABI engine only supports sqlite3, which is definitely enough as a local database for flutter. But the server-side still has to face the previous problems.

medz commented 4 months ago

Now, I am working on the flutter branch, and I am going to sleep now, because I have been confused about the static library problem for several days, and finally found the problem, dart FFI does not support static libraries.

I will try more options tomorrow.

medz commented 4 months ago

On iOS, another headache is that vendored_frameworks in the podspec is handled by flutter tools instead of cocoapods. This caused my configuration to not work. Maybe I'll try writing a shell to solve it. I hope so. I have encountered too many problems with flutter and dart ffi recently. Most of the issues found in the search were from a few years ago and there is no solution.

MulverineX commented 4 months ago

In my opinion, we should just go with Option 1 until https://github.com/prisma/prisma/issues/24295 is resolved. Thank you for pushing your code to a public branch, I'll look into helping implement Option 1 myself soon.

Worrying: Prisma C ABI engine only supports sqlite3, which is definitely enough as a local database for flutter. But the server-side still has to face the previous problems.

I think for now this can be ignored, as people running server-side dart can actually run their own Prisma server.

MulverineX commented 4 months ago

@listepo Would you like to hop into a voice call at some point to dig into this?

medz commented 4 months ago

@MulverineX I experimented by adding a static library for vendored_frameworks to podcasts. Unable to find typing in Dart FFI, but can correctly link static libraries and find functions in the c file.

That is to say, a bridge needs to be built. Even if the bridge is beyond doubt, the only purpose is to compile it into a dynamic library and then call the static library of Prisma C-Abi.

medz commented 4 months ago

News: Flutter support has achieved initial success. I use C to call the Prisma C-ABI engine static library functions, and then ffigen hides the static library functions, resulting in a dynamic library (its only purpose is to discover the Prisma QueryEngine static library and create APIs to call it)

The source code can now be viewed at https://github.com/medz/prisma-dart/tree/flutter/packages/prisma_flutter. Dart writing for APIs has not yet been completed. Currently, only one function for creation and initialization has been written (create) can be seen at https://github.com/medz/prisma-dart/blob/flutter/packages/prisma_flutter/lib/src/query_engine.dart#L29.

An example of creating an engine can be viewed at https://github.com/medz/prisma-dart/blob/flutter/packages/prisma_flutter/example/lib/main.dart#L45

Currently, I am only developing on iOS support and solving the problem of Dart FFI not being able to discover third-party static libraries. (Native language code C/C++/Swift/Java can all find third-party static libraries, so you can use your own c files to perform function training)

The C-bridge code can be found at https://github.com/medz/prisma-dart/blob/flutter/packages/prisma_flutter/src/prisma_flutter.c.

This is delightful news.

medz commented 4 months ago
image

News: Prisma has been successfully run in Flutter (in iOS). The next step is to release the Prisma Flutter package.

Next plan:

  1. Create Android support
  2. Creating web support (binding Prisma WASM), but not included in this plan

In about three hours, I will publish it to pub.dev and update the document. I have very few use cases in Flutter, and I look forward to your feedback.

MulverineX commented 4 months ago

Screenshot_20240528-101401.png

These still need to happen, is this work that can be done in this repo? If that's the case, I'd like to help. This issue shouldn't be closed until all 5 native platforms are supported (WASM can be a separate issue).

Of course, once iOS & Android support are in, an update can be published to allow those who are developing mobile-only apps to use it.

medz commented 4 months ago

News: I released orm v4.2.0 and orm_flutter v0.0.1 versions, and the integration documentation can be found at https://prisma.pub/getting-started/flutter.html, and I placed the demo program at https://github.com/medz/prisma-dart/tree/main/examples/flutter_with_orm  Next time I will start building support for Android.

medz commented 4 months ago

@MulverineX

These still need to happen, is this work that can be done in this repo?

Yes, Linux/macOS/Windows can re-package the binary engine, initialize and download the binary engine during the running of the app.

This issue shouldn't be closed until all 5 native platforms are supported (WASM can be a separate issue).

Yes, the issue will not be closed until support for all native platforms except web is complete (sometimes the merge PR may be closed automatically and I will open it manually)

Of course, once iOS & Android support are in, an update can be published to allow those who are developing mobile-only apps to use it.

I won't release v1.x until all native platforms support it, and I will be releasing on v0.x for a long time to come.

MulverineX commented 4 months ago

Ideally, A version of the engine could be bundled with the app, to avoid requiring an online install. Downloading it is okay for now though. Could you point me in the right direction, where I should work on getting initial support for desktop platforms in?

Or is that something that you will be able to manage to do very soon?

medz commented 4 months ago

@MulverineX The desktop architecture is too complex, and each architecture corresponds to an engine. Therefore, during the application startup phase, it is most reasonable to determine whether an engine needs to be downloaded and enter the download waiting page. Otherwise, your desktop app might be very large.

For the mobile side, whether including library files in the app or downloading library files is completed by the developer before building, and the packaging will only include necessary files.

If Prisma provided a dynamic library, this problem would not exist. (But judging from the Prisma roadmap, it is unlikely to be possible for a long time)

MulverineX commented 4 months ago

Flutter requires per arch build regardless, most of the time. What added complexity is there here?

https://github.com/KRTirtho/spotube/releases/tag/v3.6.0

medz commented 4 months ago

@MulverineX Maybe you're right, it seems complex architecture only happens on Linux. macOS/Windows can include binaries directly. It seems that a special flutter.assets converter needs to be written to solve the schema file problem on Linux. Maybe I’m overcomplicating my thoughts😊

medz commented 3 months ago
image

News: Support flutter Android done.

listepo commented 3 months ago

Nice

listepo commented 3 months ago

@medz maybe it makes sense to rename from orm to prisma_client and orm_flutter to prisma_client_flutter?

MulverineX commented 3 months ago

@listepo I think the goal here is to improve this library to the point where it can be the defacto ORM for Flutter. It wasn't already a taken name, and Prisma is generally the best option out there. Obviously, the engine still needs some query crafting work to improve performance down the road. Still, since Prisma has corporate sponsors/investment I'm confident the team will continue to iterate. Also, since this library directly interacts with the query engine, client isn't exactly appropriate. prisma being in the main description is good enough for searchability.

medz commented 3 months ago

@listepo I originally intended to do this, but the names are all taken (and not actually used). I tried to contact the author and the dart team through the pub.dev guide, but no emails were returned.

medz commented 3 months ago

@listepo Another fact is that the prisma marketing team does not want third-party clients to use short prisma-related names. So you will see that the documentation website of prisma orm for dart was updated to Prisma Client Dart not long ago.

listepo commented 3 months ago

@medz how to create and use migrations?

medz commented 3 months ago

@listepo Creating migrations is the same as Prisma, using the prisma migrate dev command.

To apply migrations, call the applyMigrations method on the engine

Documentation is here https://prisma.pub/getting-started/flutter.html#migrations

listepo commented 3 months ago

@medz thanks

MulverineX commented 3 months ago

Really looking forward to desktop platforms here, once they're available I can really begin to iterate on my app, as its targeting desktop first.

listepo commented 3 months ago

internally I'm using Zig. So I may also release a Zig version of Prisma in the future its very intresting