# Prima Client Rust
An ergonomic and autogenerated database client that utilises [Prisma](https://prisma.io) schemas.
## Installation
1. [Create a Prisma schema](https://www.prisma.io/docs/concepts/components/prisma-client) and [migrate your database](https://www.prisma.io/docs/concepts/components/prisma-migrate)
2. Install the `prisma-client-rust` CLI
```
cargo install prisma-client-rust
```
3. Install `prisma-client-rust`
- If you have `cargo-edit` installed, run `cargo add prisma-client-rust`
- If not, add `prisma-client-rust = "0.2.1'` as a dependency in `Cargo.toml`
4. Add `prisma-client-rust` as a generator to your Prisma schema
```
generator client {
provider = "prisma-client-rust"
// The folder that files should be generated to, relative to your schema file
output = "./db"
}
```
5. Generate the rust module by running `prisma-client-rust generate` in a terminal
6. Include the generated module in your code and connect a new Prisma client
```rs
// Name of the module will be the folder specified in the generator's 'output'
pub mod db;
use db::{PrismaClient}
// Any async runtime can be used, tokio is just an example
#[tokio::main]
async fn main() {
let client = PrismaClient::new();
await client.engine.connect();
}
```
## Queries
The following examples use this schema:
```prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-rust"
binaryTargets = ["native"]
output = "../src/db"
}
model User {
username String @id
displayName String
posts Post[]
comments Comment[]
}
model Post {
id String @id
content String
comments Comment[] @relation()
User User? @relation(fields: [userUsername], references: [username])
userUsername String?
}
model Comment {
id String @id
postId String
post Post @relation(fields: [postId], references: [id])
User User? @relation(fields: [userUsername], references: [username])
userUsername String?
}
```
### Find
```rust
pub mod db::{Post};
#[tokio::main]
async fn main() {
let mut client = PrismaClient::new();
client.engine.connect();
// Find a single record using a unique field
let unique_user = client
.user()
.find_unique(User::username().equals("some user".to_string()))
.exec()
.await;
// Find the first record that matches some parameters
let first_user = client
.user()
.find_first(vec![User::username().contains("user".to_string())])
.exec()
.await;
// Find all records that match some parameters
let many_users = client
.user()
.find_many(vec![
// Querying on relations is also supported
User::posts().some(vec![Post::content().contains("content".to_string())]),
])
.exec()
.await;
}
```
### Create
```rust
pub mod db::{PrismaClient, User, Post};
#[tokio::main]
async fn main() {
let mut client = PrismaClient::new();
client.engine.connect();
// Required values are passed in as separate arguments
let user = client
.user()
.create_one(
User::username().set("user0".to_string()),
User::display_name().set("User 0".to_string()),
// Optional arguments can be added in a vector as the last parameter
vec![],
)
.exec()
.await;
let post = client
.post()
.create_one(
Post::id().set("0".to_string()),
Post::content().set("Some post content".to_string()),
// Relations can be linked by specifying a where query
Post::user().link(User::username().equals(user.username.to_string())),
vec![],
)
.exec()
.await;
}
```
### Delete
```rust
pub mod db::{PrismaClient, User, Post};
#[tokio::main]
async fn main() {
let mut client = PrismaClient::new();
client.engine.connect();
// Delete a single record matching a given condition
// (also works with find_unique)
client
.post()
.find_unique(Post::id().equals("0".to_string()))
.delete()
.exec()
.await;
// Delete many records matching given conditions
// (In this case, deletes every user)
client
.user()
.find_many(vec![])
.delete()
.exec()
.await;
}
```