Skip to content

Commit

Permalink
fixes #3126
Browse files Browse the repository at this point in the history
  • Loading branch information
Druue committed Dec 8, 2022
1 parent 904382b commit f7ef931
Show file tree
Hide file tree
Showing 9 changed files with 35 additions and 33 deletions.
38 changes: 20 additions & 18 deletions libs/dml/src/model.rs
Expand Up @@ -244,7 +244,7 @@ impl OperatorClass {
}
}

///A field in an index that optionally defines a sort order and length limit.
/// A field in an index that optionally defines a sort order and length limit.
#[derive(Debug, PartialEq, Clone)]
pub struct IndexField {
pub path: Vec<(String, Option<String>)>,
Expand Down Expand Up @@ -291,7 +291,7 @@ pub struct PrimaryKeyDefinition {
pub clustered: Option<bool>,
}

///A field in a Primary Key that optionally defines a sort order and length limit.
/// A field in a Primary Key that optionally defines a sort order and length limit.
#[derive(Debug, PartialEq, Clone)]
pub struct PrimaryKeyField {
pub name: String,
Expand Down Expand Up @@ -325,15 +325,15 @@ impl AsRef<str> for SortOrder {
}
}

/// A unique criteria is a set of fields through which a record can be uniquely identified.
/// A unique criterion is a set of fields through which a record can be uniquely identified.
#[derive(Debug)]
pub struct UniqueCriteria<'a> {
pub struct UniqueCriterion<'a> {
pub fields: Vec<&'a ScalarField>,
}

impl<'a> UniqueCriteria<'a> {
pub fn new(fields: Vec<&'a ScalarField>) -> UniqueCriteria<'a> {
UniqueCriteria { fields }
impl<'a> UniqueCriterion<'a> {
pub fn new(fields: Vec<&'a ScalarField>) -> UniqueCriterion<'a> {
UniqueCriterion { fields }
}
}

Expand Down Expand Up @@ -452,20 +452,22 @@ impl Model {
}
}

/// optional unique fields are NOT considered a unique criteria
/// used for: A Model must have at least one STRICT unique criteria.
pub fn strict_unique_criterias(&self) -> Vec<UniqueCriteria> {
/// Optional unique fields are NOT considered a unique criterion.
///
/// Used for: A Model must have at least one STRICT unique criteria.
pub fn strict_unique_criterias(&self) -> Vec<UniqueCriterion> {
self.unique_criterias(false)
}

/// optional unique fields are considered a unique criteria
/// used for: A relation must reference one LOOSE unique criteria. (optional fields are okay in this case)
pub fn loose_unique_criterias(&self) -> Vec<UniqueCriteria> {
/// Optional unique fields are considered a unique criterion
///
/// Used for: A relation must reference one LOOSE unique criteria. (optional fields are okay in this case)
pub fn loose_unique_criterias(&self) -> Vec<UniqueCriterion> {
self.unique_criterias(true)
}

/// returns the order of unique criterias ordered based on their precedence
fn unique_criterias(&self, allow_optional: bool) -> Vec<UniqueCriteria> {
/// Returns the order of unique criterias ordered based on their precedence
fn unique_criterias(&self, allow_optional: bool) -> Vec<UniqueCriterion> {
let mut result = Vec::new();

// first candidate: primary key
Expand Down Expand Up @@ -500,14 +502,14 @@ impl Model {
.iter()
.any(|f| f.is_commented_out || (f.is_optional() && !allow_optional))
{
result.push(UniqueCriteria::new(id_fields));
result.push(UniqueCriterion::new(id_fields));
}
}
}

// second candidate: any unique constraint where all fields are required
{
let mut unique_field_combi: Vec<UniqueCriteria> = self
let mut unique_field_combi: Vec<UniqueCriterion> = self
.indices
.iter()
.filter(|id| id.is_unique())
Expand All @@ -523,7 +525,7 @@ impl Model {
let no_fields_are_ineligible = !fields.iter().any(|f| f.is_commented_out);
let all_fields_are_required = fields.iter().all(|f| f.is_required());
((all_fields_are_required || allow_optional) && no_fields_are_ineligible)
.then(|| UniqueCriteria::new(fields))
.then(|| UniqueCriterion::new(fields))
})
.collect();

Expand Down
Expand Up @@ -10,7 +10,7 @@ use crate::{
use parser_database::walkers::{ModelWalker, PrimaryKeyWalker};
use std::{borrow::Cow, collections::HashMap};

/// A model must have either a primary key, or a unique criteria
/// A model must have either a primary key, or a unique criterion
/// with no optional, commented-out or unsupported fields.
pub(super) fn has_a_strict_unique_criteria(model: ModelWalker<'_>, ctx: &mut Context<'_>) {
if model.is_ignored() {
Expand Down
Expand Up @@ -146,9 +146,9 @@ pub(super) fn references_unique_fields(relation: InlineRelationWalker<'_>, ctx:
let model = relation.referenced_model().name();

let message = if fields.len() == 1 {
format!("The argument `references` must refer to a unique criteria in the related model. Consider adding an `@unique` attribute to the field `{}` in the model `{}`.", fields.join(", "), model)
format!("The argument `references` must refer to a unique criterion in the related model. Consider adding an `@unique` attribute to the field `{}` in the model `{}`.", fields.join(", "), model)
} else {
format!("The argument `references` must refer to a unique criteria in the related model. Consider adding an `@@unique([{}])` attribute to the model `{}`.", fields.join(", "), model)
format!("The argument `references` must refer to a unique criterion in the related model. Consider adding an `@@unique([{}])` attribute to the model `{}`.", fields.join(", "), model)
};

ctx.push_error(DatamodelError::new_attribute_validation_error(
Expand Down Expand Up @@ -200,7 +200,7 @@ fn referencing_fields_in_correct_order(relation: InlineRelationWalker<'_>, ctx:

ctx.push_error(DatamodelError::new_validation_error(
&format!(
"The argument `references` must refer to a unique criteria in the related model `{}` using the same order of fields. Please check the ordering in the following fields: `{}`.",
"The argument `references` must refer to a unique criterion in the related model `{}` using the same order of fields. Please check the ordering in the following fields: `{}`.",
relation.referenced_model().name(),
relation.referenced_fields().map(|f| f.name()).join(", ")
),
Expand Down
6 changes: 3 additions & 3 deletions psl/psl/tests/attributes/relations/relations_negative.rs
Expand Up @@ -1029,7 +1029,7 @@ fn should_fail_if_not_using_unique_constraint_with_single_one_to_many() {
"#};

let expect = expect![[r#"
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criteria in the related model. Consider adding an `@unique` attribute to the field `custom_id` in the model `A`.[0m
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criterion in the related model. Consider adding an `@unique` attribute to the field `custom_id` in the model `A`.[0m
--> schema.prisma:22
 | 
21 |  a_id String
Expand Down Expand Up @@ -1087,14 +1087,14 @@ fn multiple_relation_validation_errors_do_not_prevent_each_other_across_models()
"#;

let expected_error = expect![[r#"
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criteria in the related model. Consider adding an `@unique` attribute to the field `USER_NON_UNIQUE_ID` in the model `User`.[0m
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criterion in the related model. Consider adding an `@unique` attribute to the field `USER_NON_UNIQUE_ID` in the model `User`.[0m
--> schema.prisma:15
 | 
14 |  USER_NON_UNIQUE_ID Int @db.UnsignedInt
15 |  User User @relation(fields: [USER_NON_UNIQUE_ID], references: [USER_NON_UNIQUE_ID], onUpdate: Restrict, map: "FK_USER_NON_UNIQUE_ID")
16 | 
 | 
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criteria in the related model. Consider adding an `@unique` attribute to the field `STOCK_NON_UNIQUE_ID` in the model `stock`.[0m
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criterion in the related model. Consider adding an `@unique` attribute to the field `STOCK_NON_UNIQUE_ID` in the model `stock`.[0m
--> schema.prisma:38
 | 
37 |  STOCK_ID Int @id @db.UnsignedInt
Expand Down
6 changes: 3 additions & 3 deletions psl/psl/tests/attributes/relations/relations_new.rs
Expand Up @@ -326,7 +326,7 @@ fn relation_must_error_when_referenced_fields_are_not_a_unique_criteria() {
"#;

let expect = expect![[r#"
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criteria in the related model. Consider adding an `@unique` attribute to the field `firstName` in the model `User`.[0m
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criterion in the related model. Consider adding an `@unique` attribute to the field `firstName` in the model `User`.[0m
--> schema.prisma:12
 | 
11 |  userName String
Expand Down Expand Up @@ -358,7 +358,7 @@ fn relation_must_error_when_referenced_compound_fields_are_not_a_unique_criteria
"#};

let expect = expect![[r#"
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criteria in the related model. Consider adding an `@@unique([firstName, lastName])` attribute to the model `User`.[0m
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criterion in the related model. Consider adding an `@@unique([firstName, lastName])` attribute to the model `User`.[0m
--> schema.prisma:13
 | 
12 |  lastName String
Expand Down Expand Up @@ -412,7 +412,7 @@ fn relation_must_error_when_referenced_fields_are_multiple_uniques() {
"#;

let expect = expect![[r#"
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criteria in the related model. Consider adding an `@@unique([id, firstName])` attribute to the model `User`.[0m
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criterion in the related model. Consider adding an `@@unique([id, firstName])` attribute to the model `User`.[0m
--> schema.prisma:14
 | 
13 |  // the relation is referencing two uniques. That is too much.
Expand Down
2 changes: 1 addition & 1 deletion psl/psl/tests/capabilities/cockroachdb.rs
Expand Up @@ -81,7 +81,7 @@ fn non_unique_relation_criteria_support() {
let error = parse_unwrap_err(dml);

let expectation = expect![[r#"
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criteria in the related model. Consider adding an `@unique` attribute to the field `name` in the model `User`.[0m
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criterion in the related model. Consider adding an `@unique` attribute to the field `name` in the model `User`.[0m
--> schema.prisma:9
 | 
 8 |  assigneeName String
Expand Down
2 changes: 1 addition & 1 deletion psl/psl/tests/capabilities/postgres.rs
Expand Up @@ -123,7 +123,7 @@ fn non_unique_relation_criteria_support() {
let error = parse_unwrap_err(dml);

let expectation = expect![[r#"
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criteria in the related model. Consider adding an `@unique` attribute to the field `name` in the model `User`.[0m
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criterion in the related model. Consider adding an `@unique` attribute to the field `name` in the model `User`.[0m
--> schema.prisma:9
 | 
 8 |  assigneeName String
Expand Down
2 changes: 1 addition & 1 deletion psl/psl/tests/capabilities/sqlite.rs
Expand Up @@ -161,7 +161,7 @@ fn non_unique_relation_criteria_support() {
let error = parse_unwrap_err(dml);

let expectation = expect![[r#"
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criteria in the related model. Consider adding an `@unique` attribute to the field `name` in the model `User`.[0m
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criterion in the related model. Consider adding an `@unique` attribute to the field `name` in the model `User`.[0m
--> schema.prisma:9
 | 
 8 |  assigneeName String
Expand Down
4 changes: 2 additions & 2 deletions psl/psl/tests/capabilities/sqlserver.rs
Expand Up @@ -145,7 +145,7 @@ fn non_unique_relation_criteria_support() {
let error = parse_unwrap_err(dml);

let expectation = expect![[r#"
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criteria in the related model. Consider adding an `@unique` attribute to the field `name` in the model `User`.[0m
[1;91merror[0m: [1mError parsing attribute "@relation": The argument `references` must refer to a unique criterion in the related model. Consider adding an `@unique` attribute to the field `name` in the model `User`.[0m
--> schema.prisma:9
 | 
 8 |  assigneeName String
Expand Down Expand Up @@ -202,7 +202,7 @@ fn key_order_enforcement_support() {
let error = parse_unwrap_err(dml);

let expectation = expect![[r#"
[1;91merror[0m: [1mError validating: The argument `references` must refer to a unique criteria in the related model `Todo` using the same order of fields. Please check the ordering in the following fields: `id2, id1`.[0m
[1;91merror[0m: [1mError validating: The argument `references` must refer to a unique criterion in the related model `Todo` using the same order of fields. Please check the ordering in the following fields: `id2, id1`.[0m
--> schema.prisma:19
 | 
18 | 
Expand Down

0 comments on commit f7ef931

Please sign in to comment.