prisma / prisma-engines

🚂 Engine components of Prisma ORM
https://www.prisma.io/docs/concepts/components/prisma-engines
Apache License 2.0
1.2k stars 240 forks source link
prisma rust

Prisma Engines

Query Engine Schema Engine + sql_schema_describer Cargo docs

This repository contains a collection of engines that power the core stack for Prisma, most prominently Prisma Client and Prisma Migrate.

If you're looking for how to install Prisma or any of the engines, the Getting Started guide might be useful.

This document describes some of the internals of the engines, and how to build and test them.

What's in this repository

This repository contains four engines:

Additionally, the psl (Prisma Schema Language) is the library that defines how the language looks like, how it's parsed, etc.

You'll also find:

Documentation

The API docs (cargo doc) are published on our fabulous repo page.

Building Prisma Engines

Prerequisites:

Note for nix users: it should be enough to direnv allow. How to build:

To build all engines, simply execute cargo build on the repository root. This builds non-production debug binaries. If you want to build the optimized binaries in release mode, the command is cargo build --release.

Depending on how you invoked cargo in the previous step, you can find the compiled binaries inside the repository root in the target/debug (without --release) or target/release directories (with --release):

Prisma Component Path to Binary
Query Engine ./target/[debug\|release]/query-engine
Schema Engine ./target/[debug\|release]/schema-engine
Prisma Format ./target/[debug\|release]/prisma-fmt

Prisma Schema Language

The Prisma Schema Language is a library which defines the data structures and parsing rules for prisma files, including the available database connectors. For more technical details, please check the library README.

The PSL is used throughout the schema engine, as well as prisma format. The DataModeL (DML), which is an annotated version of the PSL is also used as input for the query engine.

Query Engine

The Query Engine is how Prisma Client queries are executed. Here's a brief description of what it does:

When used through Prisma Client, there are two ways for the Query Engine to be executed:

Usage

You can also run the Query Engine as a stand-alone GraphQL server.

Warning: There is no guaranteed API stability. If using it on production please be aware the api and the query language can change any time.

Notable environment flags:

Starting the Query Engine:

The engine can be started either with using the cargo build tool, or pre-building a binary and running it directly. If using cargo, replace whatever command that starts with ./query-engine with cargo run --bin query-engine --.

You can also pass --help to find out more options to run the engine.

Metrics

Running make show-metrics will start Prometheus and Grafana with a default metrics dashboard. Prometheus will scrape the /metrics endpoint to collect the engine's metrics

Navigate to http://localhost:3000 to view the Grafana dashboard.

Schema Engine

The Schema Engine does a couple of things:

The engine uses:

Prisma format

Prisma format can format prisma schema files. It also comes as a WASM module via a node package. You can read more here.

Debugging

When trying to debug code, here's a few things that might be useful:

Testing

There are two test suites for the engines: Unit tests and integration tests.

Set up & run tests:

Prerequisites:

Setup:

There are helper make commands to set up a test environment for a specific database connector you want to test. The commands set up a container (if needed) and write the .test_config file, which is picked up by the integration tests:

*On windows: If not using WSL, make is not available and you should just see what your command does and do it manually. Basically this means editing the .test_config file and starting the needed Docker containers.

To actually get the tests working, read the contents of .envrc. Then Edit environment variables for your account from Windows settings, and add at least the correct values for the following variables:

Other variables may or may not be useful.

Run:

Run cargo test in the repository root.

Testing driver adapters

Please refer to the Testing driver adapters section in the connector-test-kit-rs README.

ℹ️ Important note on developing features that require changes to the both the query engine, and driver adapters code

As explained in Testing driver adapters, running DRIVER_ADAPTER=$adapter make qe-test will ensure you have prisma checked out in your filesystem in the same directory as prisma-engines. This is needed because the driver adapters code is symlinked in prisma-engines.

When working on a feature or bugfix spanning adapters code and query-engine code, you will need to open sibling PRs in prisma/prisma and prisma/prisma-engines respectively. Locally, each time you run DRIVER_ADAPTER=$adapter make test-qe tests will run using the driver adapters built from the source code in the working copy of prisma/prisma. All good.

In CI, tho', we need to denote which branch of prisma/prisma we want to use for tests. In CI, there's no working copy of prisma/prisma before tests run. The CI jobs clones prisma/prisma main branch by default, which doesn't include your local changes. To test in integration, we can tell CI to use the branch of prisma/prisma containing the changes in adapters. To do it, you can use a simple convention in commit messages. Like this:

git commit -m "DRIVER_ADAPTERS_BRANCH=prisma-branch-with-changes-in-adapters [...]"

GitHub actions will then pick up the branch name and use it to clone that branch's code of prisma/prisma, and build the driver adapters code from there.

When it's time to merge the sibling PRs, you'll need to merge the prisma/prisma PR first, so when merging the engines PR you have the code of the adapters ready in prisma/prisma main branch.

Testing engines in prisma/prisma

You can trigger releases from this repository to npm that can be used for testing the engines in prisma/prisma either automatically or manually:

Automated integration releases from this repository to npm

Any branch name starting with integration/ will, first, run the full test suite in GH Actions and, second, run the release workflow (build and upload engines to S3 & R2). To trigger the release on any other branch, you have two options:

The journey through the pipeline is the same as a commit on the main branch.

This end to end will take minimum ~1h20 to complete, but is completely automated :robot:

Notes:

Manual integration releases from this repository to npm

Additionally to the automated integration release for integration/ branches, you can also trigger a publish manually in the Buildkite [Test] Prisma Engines job if that succeeds for any branch name. Click "🚀 Publish binaries" at the bottom of the test list to unlock the publishing step. When all the jobs in [Release] Prisma Engines succeed, you also have to unlock the next step by clicking "🚀 Publish client". This will then trigger the same journey as described above.

Parallel rust-analyzer builds

When rust-analzyer runs cargo check it will lock the build directory and stop any cargo commands from running until it has completed. This makes the build process feel a lot longer. It is possible to avoid this by setting a different build path for rust-analyzer. To avoid this. Open VSCode settings and search for Check on Save: Extra Args. Look for the Rust-analyzer › Check On Save: Extra Args settings and add a new directory for rust-analyzer. Something like:

--target-dir:/tmp/rust-analyzer-check

Community PRs: create a local branch for a branch coming from a fork

To trigger an Automated integration releases from this repository to npm or Manual integration releases from this repository to npm branches of forks need to be pulled into this repository so the Buildkite job is triggered. You can use these GitHub and git CLI commands to achieve that easily:

gh pr checkout 4375
git checkout -b integration/sql-nested-transactions
git push --set-upstream origin integration/sql-nested-transactions

If there is a need to re-create this branch because it has been updated, deleting it and re-creating will make sure the content is identical and avoid any conflicts.

git branch --delete integration/sql-nested-transactions
gh pr checkout 4375
git checkout -b integration/sql-nested-transactions
git push --set-upstream origin integration/sql-nested-transactions --force

Security

If you have a security issue to report, please contact us at security@prisma.io