Skip to content

Commit

Permalink
Add quickfix to migrate SetDefault -> NoAction
Browse files Browse the repository at this point in the history
when using relationMode=foreignkeys on mysql

closes prisma/language-tools#1286
  • Loading branch information
Druue committed Sep 6, 2023
1 parent 7fec122 commit 6f60578
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 1 deletion.
10 changes: 10 additions & 0 deletions prisma-fmt/src/code_actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ pub(crate) fn available_actions(schema: String, params: CodeActionParams) -> Vec
complete_relation.referencing_field(),
);
}

if validated_schema.relation_mode().uses_foreign_keys() {
relation_mode::replace_set_default_mysql(
&mut actions,
&params,
validated_schema.db.source(),
complete_relation,
config,
)
}
}
}

Expand Down
52 changes: 51 additions & 1 deletion prisma-fmt/src/code_actions/relation_mode.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use lsp_types::{CodeAction, CodeActionKind, CodeActionOrCommand};
use psl::schema_ast::ast::SourceConfig;
use psl::{
schema_ast::ast::SourceConfig,
Configuration,
parser_database::walkers::CompleteInlineRelationWalker
};

pub(crate) fn edit_referential_integrity(
actions: &mut Vec<CodeActionOrCommand>,
Expand Down Expand Up @@ -35,3 +39,49 @@ pub(crate) fn edit_referential_integrity(

actions.push(CodeActionOrCommand::CodeAction(action))
}

pub(crate) fn replace_set_default_mysql(
actions: &mut Vec<CodeActionOrCommand>,
params: &lsp_types::CodeActionParams,
schema: &str,
relation: CompleteInlineRelationWalker<'_>,
config: &Configuration,
) {
let datasource = match config.datasources.first() {
Some(ds) => ds,
None => return,
};

if datasource.active_connector.provider_name() != "mysql" {
return;
}

let span = match relation.on_update_span() {
Some(span) => span,
None => return,
};

let span_diagnostics = match super::diagnostics_for_span(schema, &params.context.diagnostics, span) {
Some(sd) => sd,
None => return,
};

let diagnostics =
match super::filter_diagnostics(span_diagnostics, "MySQL does not actually support the `SetDefault` referential action, so using it may result in unexpected errors.") {
Some(value) => value,
None => return,
};

let edit = super::create_text_edit(schema, "NoAction".to_owned(), false, span, params);

let action = CodeAction {
title: r#"Replace SetDefault with NoAction"#.to_owned(),

kind: Some(CodeActionKind::QUICKFIX),
edit: Some(edit),
diagnostics: Some(diagnostics),
..Default::default()
};

actions.push(CodeActionOrCommand::CodeAction(action))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[
{
"title": "Replace SetDefault with NoAction",
"kind": "quickfix",
"diagnostics": [
{
"range": {
"start": {
"line": 14,
"character": 62
},
"end": {
"line": 14,
"character": 82
}
},
"severity": 2,
"message": "MySQL does not actually support the `SetDefault` referential action, so using it may result in unexpected errors. Read more at https://pris.ly/d/mysql-set-default "
}
],
"edit": {
"changes": {
"file:///path/to/schema.prisma": [
{
"range": {
"start": {
"line": 14,
"character": 72
},
"end": {
"line": 14,
"character": 82
}
},
"newText": "NoAction"
}
]
}
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "foreignKeys"
}

/// multi line
/// commennttt
model Foo {
id Int @id
bar Bar @relation(fields: [bar_id], references: [id], onUpdate: SetDefault)
bar_id Int @unique
t Test
}

model Bar {
id Int @id
foo Foo?
}

// This is a test enum.
enum Test {
TestUno
TestDue
}
1 change: 1 addition & 0 deletions prisma-fmt/tests/code_actions/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ scenarios! {
one_to_one_referencing_side_misses_unique_compound_field_indentation_four_spaces
relation_mode_prisma_missing_index
relation_mode_referential_integrity
relation_mode_mysql_foreign_keys_set_default
multi_schema_one_model
multi_schema_one_model_one_enum
multi_schema_two_models
Expand Down
5 changes: 5 additions & 0 deletions psl/parser-database/src/walkers/relation/inline/complete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
walkers::{ModelWalker, RelationFieldId, RelationFieldWalker, ScalarFieldWalker},
ParserDatabase, ReferentialAction,
};
use diagnostics::Span;
use schema_ast::ast;

/// Represents a relation that has fields and references defined in one of the
Expand Down Expand Up @@ -65,6 +66,10 @@ impl<'db> CompleteInlineRelationWalker<'db> {
.unwrap_or(Cascade)
}

pub fn on_update_span(self) -> Option<Span> {
self.referencing_field().attributes().on_update.map(|(_, span)| span)
}

/// Prisma allows setting the relation field as optional, even if one of the
/// underlying scalar fields is required. For the purpose of referential
/// actions, we count the relation field required if any of the underlying
Expand Down

0 comments on commit 6f60578

Please sign in to comment.