Skip to content

Commit

Permalink
findOne deprecation (prisma#1487)
Browse files Browse the repository at this point in the history
* Add deprecation mechanism to DMMF fields.

* Deprecate `findOne`.

* Deprecate with 2.15
  • Loading branch information
dpetrick authored Dec 31, 2020
1 parent 5d49126 commit 77c6676
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 2 deletions.
16 changes: 16 additions & 0 deletions query-engine/core/src/schema/input_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ impl InputObjectType {
pub struct InputField {
pub name: String,
pub default_value: Option<dml::DefaultValue>,
pub deprecation: Option<Deprecation>,

/// Possible field types, represented as a union of input types, but only one can be provided at any time.
pub field_types: Vec<InputType>,
Expand Down Expand Up @@ -125,6 +126,21 @@ impl InputField {
self.field_types.push(typ);
self
}

pub fn deprecate<T, S, U>(mut self, reason: T, since_version: S, planned_removal_version: Option<U>) -> Self
where
T: Into<String>,
S: Into<String>,
U: Into<String>,
{
self.deprecation = Some(Deprecation {
reason: reason.into(),
since_version: since_version.into(),
planned_removal_version: planned_removal_version.map(Into::into),
});

self
}
}

#[derive(Clone)]
Expand Down
7 changes: 7 additions & 0 deletions query-engine/core/src/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,10 @@ impl<T> IntoArc<T> for Weak<T> {
self.upgrade().expect("Expected weak reference to be valid.")
}
}

#[derive(Debug, PartialEq)]
pub struct Deprecation {
pub since_version: String,
pub planned_removal_version: Option<String>,
pub reason: String,
}
15 changes: 15 additions & 0 deletions query-engine/core/src/schema/output_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ impl ObjectType {
pub struct OutputField {
pub name: String,
pub field_type: OutputTypeRef,
pub deprecation: Option<Deprecation>,

/// Arguments are input fields, but positioned in context of an output field
/// instead of being attached to an input object.
Expand All @@ -168,4 +169,18 @@ impl OutputField {
self
}
}

pub fn deprecate<T, S>(mut self, reason: T, since_version: S, planned_removal_version: Option<String>) -> Self
where
T: Into<String>,
S: Into<String>,
{
self.deprecation = Some(Deprecation {
reason: reason.into(),
since_version: since_version.into(),
planned_removal_version,
});

self
}
}
2 changes: 2 additions & 0 deletions query-engine/core/src/schema/query_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ pub struct QueryInfo {
#[derive(Debug, Clone, PartialEq)]
pub enum QueryTag {
FindOne,
FindUnique,
FindFirst,
FindMany,
CreateOne,
Expand All @@ -107,6 +108,7 @@ impl fmt::Display for QueryTag {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self {
Self::FindOne => "findOne",
Self::FindUnique => "findUnique",
Self::FindFirst => "findFirst",
Self::FindMany => "findMany",
Self::CreateOne => "createOne",
Expand Down
28 changes: 26 additions & 2 deletions query-engine/core/src/schema_builder/output_types/query_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub(crate) fn build(ctx: &mut BuilderContext) -> (OutputType, ObjectTypeStrongRe
}

append_opt(&mut vec, find_one_field(ctx, &model));
append_opt(&mut vec, find_unique_field(ctx, &model));
vec
})
.flatten()
Expand All @@ -28,8 +29,7 @@ pub(crate) fn build(ctx: &mut BuilderContext) -> (OutputType, ObjectTypeStrongRe
(OutputType::Object(Arc::downgrade(&strong_ref)), strong_ref)
}

/// Builds a "single" query arity item field (e.g. "user", "post" ...) for given model.
/// Find one unique semantics.
/// Deprecated field. Semantics are identical to `findUnique`.
fn find_one_field(ctx: &mut BuilderContext, model: &ModelRef) -> Option<OutputField> {
arguments::where_unique_argument(ctx, model).map(|arg| {
let field_name = ctx.pluralize_internal(camel_case(&model.name), format!("findOne{}", model.name));
Expand All @@ -44,6 +44,30 @@ fn find_one_field(ctx: &mut BuilderContext, model: &ModelRef) -> Option<OutputFi
}),
)
.optional()
.deprecate(
"The `findOne` query has been deprecated and replaced with `findUnique`.",
"2.14",
Some("2.15".to_owned()),
)
})
}

/// Builds a "single" query arity item field (e.g. "user", "post" ...) for given model.
/// Find one unique semantics.
fn find_unique_field(ctx: &mut BuilderContext, model: &ModelRef) -> Option<OutputField> {
arguments::where_unique_argument(ctx, model).map(|arg| {
let field_name = ctx.pluralize_internal(camel_case(&model.name), format!("findUnique{}", model.name));

field(
field_name,
vec![arg],
OutputType::object(output_objects::map_model_object_type(ctx, &model)),
Some(QueryInfo {
model: Some(Arc::clone(&model)),
tag: QueryTag::FindUnique,
}),
)
.optional()
})
}

Expand Down
2 changes: 2 additions & 0 deletions query-engine/core/src/schema_builder/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ where
field_type: Arc::new(field_type),
query_info,
is_required: true,
deprecation: None,
}
}

Expand All @@ -71,6 +72,7 @@ where
field_types: field_types.into(),
default_value,
is_required: true,
deprecation: None,
}
}

Expand Down
27 changes: 27 additions & 0 deletions query-engine/query-engine/src/dmmf/schema/ast.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::HashMap;

use query_core::Deprecation;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Default)]
Expand All @@ -18,6 +19,9 @@ pub struct DmmfOutputField {
pub is_required: bool,
pub is_nullable: bool,
pub output_type: DmmfTypeReference,

#[serde(skip_serializing_if = "Option::is_none")]
pub deprecation: Option<DmmfDeprecation>,
}

#[derive(Debug, Serialize, Deserialize)]
Expand Down Expand Up @@ -49,6 +53,9 @@ pub struct DmmfInputField {
pub is_required: bool,
pub is_nullable: bool,
pub input_types: Vec<DmmfTypeReference>,

#[serde(skip_serializing_if = "Option::is_none")]
pub deprecation: Option<DmmfDeprecation>,
}

#[derive(Debug, Serialize, Deserialize)]
Expand Down Expand Up @@ -78,3 +85,23 @@ pub struct DmmfEnum {
pub name: String,
pub values: Vec<String>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DmmfDeprecation {
pub since_version: String,
pub reason: String,

#[serde(skip_serializing_if = "Option::is_none")]
pub planned_removal_version: Option<String>,
}

impl From<&Deprecation> for DmmfDeprecation {
fn from(deprecation: &Deprecation) -> Self {
Self {
since_version: deprecation.since_version.clone(),
planned_removal_version: deprecation.planned_removal_version.clone(),
reason: deprecation.reason.clone(),
}
}
}
2 changes: 2 additions & 0 deletions query-engine/query-engine/src/dmmf/schema/field_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub(super) fn render_input_field(input_field: &InputFieldRef, ctx: &mut RenderCo
input_types: type_references,
is_required: input_field.is_required,
is_nullable: nullable,
deprecation: input_field.deprecation.as_ref().map(Into::into),
};

field
Expand All @@ -31,6 +32,7 @@ pub(super) fn render_output_field(field: &OutputFieldRef, ctx: &mut RenderContex
output_type,
is_required: field.is_required,
is_nullable: !field.is_required,
deprecation: field.deprecation.as_ref().map(Into::into),
};

ctx.add_mapping(field.name.clone(), field.query_info.as_ref());
Expand Down

0 comments on commit 77c6676

Please sign in to comment.