Skip to content

Commit

Permalink
no breaking changes plz thankyo
Browse files Browse the repository at this point in the history
  • Loading branch information
Brendonovich committed Mar 29, 2023
1 parent de9ae4f commit f71ad91
Show file tree
Hide file tree
Showing 17 changed files with 110 additions and 55 deletions.
4 changes: 2 additions & 2 deletions cli/src/generator/models/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ pub fn create_many_fn(model: &dml::Model) -> Option<TokenStream> {
.unzip();

Some(quote! {
pub fn create_many(self, data: Vec<(#(#types,)* Vec<UncheckedSetParam>)>) -> CreateMany<'a> {
pub fn create_many(self, data: Vec<(#(#types,)* Vec<SetParam>)>) -> CreateMany<'a> {
let data = data.into_iter().map(|(#(#names,)* mut _params)| {
_params.extend([
#(#names::set(#names)),*
Expand Down Expand Up @@ -213,7 +213,7 @@ pub fn struct_definition(model: &dml::Model, args: &GenerateArgs) -> TokenStream
)
}

pub fn update_many(self, _where: Vec<WhereParam>, _params: Vec<UncheckedSetParam>) -> UpdateMany<'a> {
pub fn update_many(self, _where: Vec<WhereParam>, _params: Vec<SetParam>) -> UpdateMany<'a> {
UpdateMany::new(
self.client,
_where,
Expand Down
4 changes: 2 additions & 2 deletions cli/src/generator/models/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ fn create_unchecked(model: &dml::Model) -> Option<TokenStream> {
.unzip();

Some(quote! {
pub fn create_unchecked(#(#names: #types,)* _params: Vec<UncheckedSetParam>)
-> (#(#types,)* Vec<UncheckedSetParam>) {
pub fn create_unchecked(#(#names: #types,)* _params: Vec<SetParam>)
-> (#(#types,)* Vec<SetParam>) {
(#(#names,)* _params)
}
})
Expand Down
2 changes: 1 addition & 1 deletion cli/src/generator/models/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ enum Field<'a> {
Composite(CompositeField<'a>),
}

pub fn struct_definition(model: &dml::Model, module_path: &TokenStream) -> TokenStream {
pub fn struct_definition(model: &dml::Model) -> TokenStream {
let pcr = quote!(::prisma_client_rust);

let fields = model
Expand Down
6 changes: 3 additions & 3 deletions cli/src/generator/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod field;
mod include_select;
mod order_by;
mod pagination;
mod partial;
mod partial_unchecked;
mod set_params;
mod types;
mod where_params;
Expand Down Expand Up @@ -275,7 +275,7 @@ pub fn modules(args: &GenerateArgs, module_path: &TokenStream) -> Vec<TokenStrea
where_params_entries.extend(field_where_param_entries.into_iter().flatten());

let where_params_enums = where_params::collate_entries(where_params_entries);
let data_struct = data::struct_definition(&model, module_path);
let data_struct = data::struct_definition(&model);
let with_params_enum = with_params::enum_definition(&model);
let set_params_enum = set_params::enum_definition(&model, args, module_path);
let order_by_params_enum = order_by::enum_definition(&model);
Expand All @@ -286,7 +286,7 @@ pub fn modules(args: &GenerateArgs, module_path: &TokenStream) -> Vec<TokenStrea
let include_params_enum = include::model_module_enum(&model, &pcr);
let actions_struct = actions::struct_definition(&model, args);
let types_struct = types::struct_definition(&model, module_path);
let partial_macro = partial::model_macro(&model, &module_path);
let partial_macro = partial_unchecked::model_macro(&model, &module_path);

quote! {
pub mod #model_name_snake {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::generator::prelude::*;
pub fn model_macro<'a>(model: &'a dml::Model, module_path: &TokenStream) -> TokenStream {
let model_name_snake = snake_ident(&model.name);
let model_name_snake_raw = snake_ident_raw(&model.name);
let macro_name = format_ident!("_partial_{model_name_snake_raw}");
let macro_name = format_ident!("_partial_unchecked_{model_name_snake_raw}");

let model_module = quote!(#module_path::#model_name_snake);

Expand Down Expand Up @@ -33,7 +33,7 @@ pub fn model_macro<'a>(model: &'a dml::Model, module_path: &TokenStream) -> Toke
($struct_name:ident {
$($scalar_field:ident)+
}) => {
::prisma_client_rust::macros::partial! {
::prisma_client_rust::macros::partial_unchecked! {
#model_module
struct $struct_name {
#(#struct_fields),*
Expand All @@ -43,6 +43,6 @@ pub fn model_macro<'a>(model: &'a dml::Model, module_path: &TokenStream) -> Toke
};
}

pub use #macro_name as partial;
pub use #macro_name as partial_unchecked;
}
}
2 changes: 1 addition & 1 deletion docs/pages/extra/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"batching": "Batching Queries",
"transactions": "Transactions",
"composite-types": "Composite Types",
"partial-types": "Partial Types",
"mocking": "Mocking Queries",
"error-handling": "Error Handling",
"migrations": "Migrations",
"partial-types": "Partial Types",
"rspc": "rspc Integration",
"traits": "Query Traits"
}
2 changes: 2 additions & 0 deletions docs/pages/extra/composite-types.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Composite Types

_Available since v0.6.7_

When using MongoDB you will likely need to use [`embedded documents`](https://www.mongodb.com/docs/manual/core/data-model-design/#std-label-data-modeling-embedding),
which Prisma calls 'Composite Types'.
Prisma Client Rust will generate field & type modules whenever you use composite types,
Expand Down
30 changes: 15 additions & 15 deletions docs/pages/extra/partial-types.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Partial Types
# Partial Types

_Available since v0.6.7_

The `partial!` macro can be found in all model modules,
and allows structs to be defined that have a `to_params` function which converts them for use inside `update` and `upsert` queries.
The `partial_unchecked!` macro can be found in all model modules,
and allows structs to be defined that have a `to_params` function which converts them for use inside `update_unchecked`.
Each field of the generated structs has the same type as the equivalent field in the module's `Data` struct,
just wrapped inside `Option`.

Expand All @@ -12,9 +12,14 @@ This can be useful for thing like web APIs built with
[`rspc`](https://www.rspc.dev/),
where receiving updates is more ergonomic as structs rather than a list of changes.

Currently `partial!` only supports scalar fields.
Support for relations will be considered once [nested writes](https://github.com/Brendonovich/prisma-client-rust/issues/44)
are implemented.
A more general `partial!` does not yet exist,
as supporting relations is not possible until [nested writes](https://github.com/Brendonovich/prisma-client-rust/issues/44)
are supported.

## Setup

Using partial macros requires the same setup as [Select & Include](/reading-data/select-include#setup),
as `module_path` must be provided.

## Example

Expand All @@ -31,7 +36,7 @@ model Post {
An updater function can be written like so:

```rust
post::partial!(PostUpdateData {
post::partial_unchecked!(PostUpdateData {
title
content
})
Expand All @@ -42,13 +47,13 @@ pub async fn update_post(
data: PostUpdateData
) {
db.post()
.update(post::id::equals(id), data.to_params())
.update_unchecked(post::id::equals(id), data.to_params())
.exec()
.await;
}
```

The above use of `partial!` generates the following:
The above use of `partial_unchecked!` generates something like the following:

```rust
pub struct PostUpdateData {
Expand All @@ -57,16 +62,11 @@ pub struct PostUpdateData {
}

impl PostUpdateData {
pub fn to_params(self) -> Vec<WhereParam> {
pub fn to_params(self) -> Vec<post::UncheckedSetParam> {
[
self.title.map(post::title::set),
self.content.map(post::content::set)
].into_iter().flatten().collect()
}
}
```


## Specta


2 changes: 2 additions & 0 deletions docs/pages/extra/raw.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ assert_eq!(count, 1);

## MongoDB

_Available since v0.6.7_

When using MongDB,
the client exposes multiple functions for performing raw queries that use [`serde_json::Value`](https://docs.rs/serde_json/latest/serde_json/value/enum.Value.html)
as arguments.
Expand Down
9 changes: 9 additions & 0 deletions docs/pages/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ as a lot of concepts are shared from them and will not be explained here.

Prisma Client Rust is not an official Prisma product, but has been [generously supported](https://twitter.com/prisma/status/1554855900124438529) as part of their FOSS Fund.

## Examples

- [Actix](https://github.com/Brendonovich/prisma-client-rust/tree/main/examples/actix)
- [Axum](https://github.com/Brendonovich/prisma-client-rust/tree/main/examples/axum-rest)
- [Axum + `async-graphql`](https://github.com/Brendonovich/prisma-client-rust/tree/main/examples/axum-graphql)
- [Rocket](https://github.com/Brendonovich/prisma-client-rust/tree/main/examples/rocket)
- [rspc](https://github.com/Brendonovich/prisma-client-rust/tree/main/examples/rspc)
- [Tauri](https://github.com/Brendonovich/prisma-client-rust/tree/main/examples/tauri)

## In The Wild

- [Spacedrive](https://spacedrive.com) - Prisma Client Rust wouldn't exist without Spacedrive (my employer),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,45 @@ let comment: comment::Data = client
Connecting records like this is equivalent to directly setting the values of the relation's foreign keys, eg.
setting `post_id` from the above example with `comment::post_id::set()`.


## Create Unchecked

_Available since v0.6.7_

`create_unchecked` is similar to `create` but only allows setting scalar fields using `UncheckedSetParam`.
`unchecked` is a Prisma term describing inputs that only accept a model's scalar fields.

```rust
use prisma::{comment, post};

let comment: comment::Data = client
.comment()
.create(
"content".to_string(),
// requires specifying field for postID,
// rather than connecting a relation
0,
vec![]
)
.exec()
.await?;
```

## Create Many

`create_many` can be used to create many records of a single model type.
It accepts a `Vec` of tuples with a similar shape as the arguments to `create`,
except only scalar fields can be provided.
Connecting relations using relation field operations is not possible.
It accepts a `Vec` of tuples with the same shape as `create_unchecked`,
so only scalar fields can be set.

import { Callout } from "nextra-theme-docs";

<Callout type="info">
SQLite support for `create_many` is **UNSTABLE**,
but can be enabled by adding the `sqlite-create-many` feature to `prisma-client-rust` and `prisma-client-rust-cli` in your `Cargo.toml` files.
</Callout>

To assist in constructing tuples of the right shape,
each model module contains a `create_unchecked` function that accepts a model's scalar fields and returns the correct tuple.
`unchecked` is a Prisma term,
describing inputs that only accept a model's scalar fields.

SQLite support for `create_many` is **UNSTABLE**, but can be enabled by adding the `sqlite-create-many` feature to `prisma-client-rust` and `prisma-client-rust-cli` in your `Cargo.toml` files.

The following example iterates an array of titles, turns it into tuples and creates multiple posts.

Expand Down
19 changes: 19 additions & 0 deletions docs/pages/writing-data/update.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,25 @@ let updated_post: post::Data = client
.await?;
```

## Update Unchecked

_Available since v0.6.7_

`update_unchecked` is similar to `update` but only allows setting scalar fields using `UncheckedSetParam`.

```rust
use prisma::{comment, post};

let comment: comment::Data = client
.comment()
.update(
comment::id::equals("some comment id".to_string()),
vec![comment::post_id::set("some post id".to_string())]
)
.exec()
.await?;
```

## Update Many

`update_many` accepts a `Vec` of filters (not just unique filters), and a `Vec` of updates to apply to all records found.
Expand Down
4 changes: 2 additions & 2 deletions integration-tests/tests/partial.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{db::*, utils::*};

user::partial!(UserPartialType {
user::partial_unchecked!(UserPartialType {
name
email
});
Expand All @@ -22,7 +22,7 @@ async fn scalars() -> TestResult {

let updated_user = client
.user()
.update(user::id::equals(user.id), updates.to_params())
.update_unchecked(user::id::equals(user.id), updates.to_params())
.exec()
.await?;

Expand Down
6 changes: 3 additions & 3 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod partial;
mod partial_unchecked;

#[proc_macro]
pub fn to_pascal_case(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
Expand All @@ -7,6 +7,6 @@ pub fn to_pascal_case(input: proc_macro::TokenStream) -> proc_macro::TokenStream
proc_macro::TokenTree::Literal(proc_macro::Literal::string(&converted)).into()
}
#[proc_macro]
pub fn partial(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
partial::proc_macro(input)
pub fn partial_unchecked(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
partial_unchecked::proc_macro(input)
}
10 changes: 5 additions & 5 deletions macros/src/partial.rs → macros/src/partial_unchecked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ use syn::{
bracketed, parse::Parse, parse_macro_input, punctuated::Punctuated, ItemStruct, Path, Token,
};

struct PartialInput {
struct PartialUncheckedInput {
model_module: Path,
data: ItemStruct,
selection: Punctuated<Ident, Token![,]>,
}

impl Parse for PartialInput {
impl Parse for PartialUncheckedInput {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
Ok(Self {
model_module: input.parse()?,
Expand All @@ -25,11 +25,11 @@ impl Parse for PartialInput {
}

pub fn proc_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let PartialInput {
let PartialUncheckedInput {
model_module,
data,
selection,
} = parse_macro_input!(input as PartialInput);
} = parse_macro_input!(input as PartialUncheckedInput);

let fields = data
.fields
Expand Down Expand Up @@ -69,7 +69,7 @@ pub fn proc_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
}

impl #ident {
pub fn to_params(self) -> Vec<#model_module::SetParam> {
pub fn to_params(self) -> Vec<#model_module::UncheckedSetParam> {
[
#(self.#selection.map(#model_module::#selection::set)),*
].into_iter().flatten().collect()
Expand Down
9 changes: 3 additions & 6 deletions src/queries/create_many.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,12 @@ use crate::{

pub struct CreateMany<'a, Actions: ModelTypes> {
client: &'a PrismaClientInternals,
pub set_params: Vec<Vec<Actions::UncheckedSet>>,
pub set_params: Vec<Vec<Actions::Set>>,
pub skip_duplicates: bool,
}

impl<'a, Actions: ModelTypes> CreateMany<'a, Actions> {
pub fn new(
client: &'a PrismaClientInternals,
set_params: Vec<Vec<Actions::UncheckedSet>>,
) -> Self {
pub fn new(client: &'a PrismaClientInternals, set_params: Vec<Vec<Actions::Set>>) -> Self {
Self {
client,
set_params,
Expand All @@ -31,7 +28,7 @@ impl<'a, Actions: ModelTypes> CreateMany<'a, Actions> {
}

fn to_selection(
set_params: Vec<Vec<Actions::UncheckedSet>>,
set_params: Vec<Vec<Actions::Set>>,
_skip_duplicates: bool,
nested_selections: impl IntoIterator<Item = Selection>,
) -> Selection {
Expand Down
Loading

1 comment on commit f71ad91

@vercel
Copy link

@vercel vercel bot commented on f71ad91 Mar 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.