Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: re-introspection with @@map and relationMode #3335

Merged
merged 12 commits into from
Oct 27, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use crate::{
SqlFamilyTrait,
};
use introspection_connector::Warning;
use psl::dml::{self, Datamodel, DefaultValue, Field, FieldType, Ignorable, PrismaValue, ValueGenerator, WithName};
use psl::dml::{
self, Datamodel, DefaultValue, Field, FieldType, Ignorable, PrismaValue, ValueGenerator, WithDatabaseName, WithName,
};
use std::collections::{BTreeSet, HashMap};

pub(crate) fn enrich(
Expand Down Expand Up @@ -127,10 +129,28 @@ fn keep_index_ordering(old_data_model: &Datamodel, new_data_model: &mut Datamode
fn merge_relation_fields(old_data_model: &Datamodel, new_data_model: &mut Datamodel, warnings: &mut Vec<Warning>) {
let mut changed_models = BTreeSet::new();

// Maps a model name to the table name it was introspected to. This is helpful when @@map is used.
// E.g., for
//
// ```prisma
// model Foo {
// id Int @id
// bar Bar @relation(fields: [bar_id], references: [id])
// bar_id Int @unique
// @@map("foo_table")
// }
//
// the map would be {"Foo" -> "foo_table"}.
// ```
let old_model_name_to_final_database_name: HashMap<String, String> = old_data_model
.models()
.map(|m| (m.name.clone(), String::from(m.final_database_name())))
.collect();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Any suggestion on how to avoid these clones while still being able to use the function in the following closures is well accepted.

Copy link
Contributor

Choose a reason for hiding this comment

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

I wouldn't worry about it here, but you can change line 147 to .map(|m| (m.name.as_str(), m.final_database_name())) and the type ascription to HashMap<&str, &str>. To optimize further, you could make the HashMap potentially a lot smaller if you .filter() for only the models with a mapped name first — then a model missing in the map would mean the model is not remapped, which would be handled with the existing code lower down.

But we shouldn't worry too much here, we're in the process of rewriting this file and the string comparisons will go away, we'll have a big map of integer identifiers for these lookups, since they happen repeatedly during introspection and reintrospection.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I have simply got rid of .clone() in favor of .as_str(). I will skip other optimizations for now, as we expect this file to change significantly already


for old_model in old_data_model.models() {
let modifications = new_data_model
.models()
.find(|m| m.name == *old_model.name())
.find(|m| *m.final_database_name() == *old_model.final_database_name())
.map(|new_model| {
let mut ordering: HashMap<String, usize> = old_model
.fields()
Expand All @@ -147,10 +167,12 @@ fn merge_relation_fields(old_data_model: &Datamodel, new_data_model: &mut Datamo
let mut fields = Vec::new();

for field in old_model.relation_fields() {
if new_data_model
.models()
.any(|m| m.name == field.relation_info.referenced_model)
{
if new_data_model.models().any(|m| {
m.name
== *old_model_name_to_final_database_name
.get(&field.relation_info.referenced_model)
.unwrap() // as the old datamodel is guaranteed to be valid at this point, this unwrap is safe
}) {
fields.push(Field::RelationField(field.clone()));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod mssql;
mod mysql;
mod relation_mode;
mod sqlite;
mod vitess;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod mssql;
mod mysql;
mod postgres;
mod sqlite;