Skip to content

Commit

Permalink
Use the new renderer in intro
Browse files Browse the repository at this point in the history
  • Loading branch information
Julius de Bruijn committed Oct 27, 2022
1 parent 151905f commit 3153c83
Show file tree
Hide file tree
Showing 42 changed files with 1,010 additions and 1,783 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,12 @@ pub(super) async fn sample(

let data_model = if ctx.render_config {
format!(
"{}\n{}\n{}",
"{}\n{}",
render::Configuration::from_psl(ctx.configuration()),
render::Datamodel::from_dml(ctx.datasource(), &data_model),
psl::render_datamodel_to_string(&data_model, Some(ctx.configuration())),
)
} else {
format!(
"{}\n{}",
render::Datamodel::from_dml(ctx.datasource(), &data_model),
psl::render_datamodel_to_string(&data_model, Some(ctx.configuration())),
)
render::Datamodel::from_dml(ctx.datasource(), &data_model).to_string()
};

Ok(IntrospectionResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
use datamodel_renderer as render;
use introspection_connector::Version;
use psl::{
datamodel_connector::constraint_names::ConstraintNames,
dml::{self, Datamodel, Field, Model, PrimaryKeyDefinition, PrimaryKeyField, RelationField, SortOrder},
parser_database::{ast, walkers},
Configuration,
Expand Down Expand Up @@ -91,9 +92,8 @@ pub(crate) fn introspect(ctx: &mut Context) -> Result<(Version, String, bool), S
};

let rendered = format!(
"{}\n{}\n{}",
"{}\n{}",
config,
psl::render_datamodel_to_string(&datamodel, Some(ctx.config)),
render::Datamodel::from_dml(&ctx.config.datasources[0], &datamodel),
);

Expand Down Expand Up @@ -273,7 +273,12 @@ fn introspect_models(datamodel: &mut Datamodel, ctx: &Context) {
.foreign_keys()
.filter(|fk| !duplicated_foreign_keys.contains(&fk.id))
{
let mut relation_field = calculate_relation_field(foreign_key, &m2m_tables, &duplicated_foreign_keys);
let mut relation_field = calculate_relation_field(
ctx.active_connector(),
foreign_key,
&m2m_tables,
&duplicated_foreign_keys,
);

relation_field.supports_restrict_action(!ctx.sql_family().is_mssql());

Expand All @@ -289,15 +294,21 @@ fn introspect_models(datamodel: &mut Datamodel, ctx: &Context) {
if let Some(pk) = table.primary_key() {
let clustered = primary_key_is_clustered(pk.id, ctx);

let db_name = if pk.name() == &ConstraintNames::primary_key_name(table.name(), ctx.active_connector()) {
None
} else {
Some(pk.name().to_owned())
};

model.primary_key = Some(PrimaryKeyDefinition {
name: None,
db_name: Some(pk.name().to_owned()),
db_name,
fields: pk
.columns()
.map(|c| {
let sort_order = c.sort_order().map(|sort| match sort {
SQLSortOrder::Asc => SortOrder::Asc,
SQLSortOrder::Desc => SortOrder::Desc,
let sort_order = c.sort_order().and_then(|sort| match sort {
SQLSortOrder::Asc => None,
SQLSortOrder::Desc => Some(SortOrder::Desc),
});

PrimaryKeyField {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::{calculate_datamodel::CalculateDatamodelContext as Context, SqlError, SqlFamilyTrait};
use psl::{
datamodel_connector::{constraint_names::ConstraintNames, Connector},
dml::{
Datamodel, FieldArity, FieldType, IndexAlgorithm, IndexDefinition, IndexField, Model, OperatorClass,
PrimaryKeyField, ReferentialAction, RelationField, RelationInfo, ScalarField, ScalarType, SortOrder,
},
PreviewFeature, RelationNames,
parser_database as db, PreviewFeature, RelationNames,
};
use sql::walkers::{ColumnWalker, ForeignKeyWalker, TableWalker};
use sql_schema_describer::{
Expand Down Expand Up @@ -174,20 +175,37 @@ pub(crate) fn calculate_index(index: sql::walkers::IndexWalker<'_>, ctx: &Contex
IndexType::PrimaryKey => return None,
};

let default_constraint_name = match index.index_type() {
IndexType::Unique => {
let columns = index.column_names().collect::<Vec<_>>();
ConstraintNames::unique_index_name(index.table().name(), &columns, ctx.active_connector())
}
_ => {
let columns = index.column_names().collect::<Vec<_>>();
ConstraintNames::non_unique_index_name(index.table().name(), &columns, ctx.active_connector())
}
};

let db_name = if index.name() == default_constraint_name {
None
} else {
Some(index.name().to_owned())
};

// We do not populate name in client by default. It increases datamodel noise, and we would
// need to sanitize it. Users can give their own names if they want and re-introspection will
// keep them. This is a change in introspection behaviour, but due to re-introspection previous
// datamodels and clients should keep working as before.

Some(IndexDefinition {
name: None,
db_name: Some(index.name().to_owned()),
db_name,
fields: index
.columns()
.map(|c| {
let sort_order = c.sort_order().map(|sort| match sort {
SQLSortOrder::Asc => SortOrder::Asc,
SQLSortOrder::Desc => SortOrder::Desc,
let sort_order = c.sort_order().and_then(|sort| match sort {
SQLSortOrder::Asc => None,
SQLSortOrder::Desc => Some(SortOrder::Desc),
});

let operator_class = get_opclass(c.id, index.schema, ctx);
Expand Down Expand Up @@ -230,6 +248,7 @@ pub(crate) fn calculate_scalar_field(column: ColumnWalker<'_>, ctx: &Context) ->
}

pub(crate) fn calculate_relation_field(
connector: &dyn Connector,
foreign_key: ForeignKeyWalker<'_>,
m2m_table_names: &[String],
duplicated_foreign_keys: &HashSet<sql::ForeignKeyId>,
Expand All @@ -244,14 +263,25 @@ pub(crate) fn calculate_relation_field(
ForeignKeyAction::SetDefault => ReferentialAction::SetDefault,
};

let cols: Vec<_> = foreign_key.constrained_columns().map(|c| c.name()).collect();
let default_constraint_name =
ConstraintNames::foreign_key_constraint_name(foreign_key.table().name(), &cols, connector);

// destroy this when removing dml
let fk_name = if foreign_key.constraint_name() == Some(default_constraint_name.as_str()) {
None
} else {
foreign_key.constraint_name().map(String::from)
};

let relation_info = RelationInfo {
name: calculate_relation_name(foreign_key, m2m_table_names, duplicated_foreign_keys),
fk_name: foreign_key.constraint_name().map(String::from),
fk_name,
fields: foreign_key.constrained_columns().map(|c| c.name().to_owned()).collect(),
referenced_model: foreign_key.referenced_table().name().to_owned(),
references: foreign_key.referenced_columns().map(|c| c.name().to_owned()).collect(),
on_delete: Some(map_action(foreign_key.on_delete_action())),
on_update: Some(map_action(foreign_key.on_update_action())),
on_delete: None,
on_update: None,
};

let arity = match foreign_key.constrained_columns().any(|c| !c.arity().is_required()) {
Expand All @@ -264,12 +294,25 @@ pub(crate) fn calculate_relation_field(
false => arity,
};

RelationField::new(
let mut rf = RelationField::new(
foreign_key.referenced_table().name(),
arity,
calculated_arity,
relation_info,
)
);

let on_delete = map_action(foreign_key.on_delete_action());
let on_update = map_action(foreign_key.on_update_action());

if rf.default_on_delete_action() != on_delete {
rf.relation_info.on_delete = Some(on_delete);
}

if rf.default_on_update_action() != on_update {
rf.relation_info.on_update = Some(on_update);
}

rf
}

pub(crate) fn calculate_backrelation_field(
Expand Down Expand Up @@ -387,18 +430,39 @@ pub(crate) fn calculate_scalar_field_type_with_native_types(column: sql::ColumnW
match scalar_type {
FieldType::Scalar(scal_type, _) => match &column.column_type().native_type {
None => scalar_type,
Some(native_type) => FieldType::Scalar(
scal_type,
Some(psl::dml::NativeTypeInstance::new(
native_type.clone(),
ctx.active_connector(),
)),
),
Some(native_type) => {
let is_default = ctx.active_connector().native_type_is_default_for_scalar_type(
native_type,
&dml_scalar_type_to_parser_database_scalar_type(scal_type),
);

if is_default {
FieldType::Scalar(scal_type, None)
} else {
let instance = psl::dml::NativeTypeInstance::new(native_type.clone(), ctx.active_connector());

FieldType::Scalar(scal_type, Some(instance))
}
}
},
field_type => field_type,
}
}

fn dml_scalar_type_to_parser_database_scalar_type(st: ScalarType) -> db::ScalarType {
match st {
ScalarType::Int => db::ScalarType::Int,
ScalarType::BigInt => db::ScalarType::BigInt,
ScalarType::Float => db::ScalarType::Float,
ScalarType::Boolean => db::ScalarType::Boolean,
ScalarType::String => db::ScalarType::String,
ScalarType::DateTime => db::ScalarType::DateTime,
ScalarType::Json => db::ScalarType::Json,
ScalarType::Bytes => db::ScalarType::Bytes,
ScalarType::Decimal => db::ScalarType::Decimal,
}
}

// misc

pub fn deduplicate_relation_field_names(datamodel: &mut Datamodel) {
Expand Down Expand Up @@ -455,14 +519,14 @@ fn index_algorithm(index: sql::walkers::IndexWalker<'_>, ctx: &Context) -> Optio

let data: &PostgresSchemaExt = index.schema.downcast_connector_data();

Some(match data.index_algorithm(index.id) {
sql::postgres::SqlIndexAlgorithm::BTree => IndexAlgorithm::BTree,
sql::postgres::SqlIndexAlgorithm::Hash => IndexAlgorithm::Hash,
sql::postgres::SqlIndexAlgorithm::Gist => IndexAlgorithm::Gist,
sql::postgres::SqlIndexAlgorithm::Gin => IndexAlgorithm::Gin,
sql::postgres::SqlIndexAlgorithm::SpGist => IndexAlgorithm::SpGist,
sql::postgres::SqlIndexAlgorithm::Brin => IndexAlgorithm::Brin,
})
match data.index_algorithm(index.id) {
sql::postgres::SqlIndexAlgorithm::BTree => None,
sql::postgres::SqlIndexAlgorithm::Hash => Some(IndexAlgorithm::Hash),
sql::postgres::SqlIndexAlgorithm::Gist => Some(IndexAlgorithm::Gist),
sql::postgres::SqlIndexAlgorithm::Gin => Some(IndexAlgorithm::Gin),
sql::postgres::SqlIndexAlgorithm::SpGist => Some(IndexAlgorithm::SpGist),
sql::postgres::SqlIndexAlgorithm::Brin => Some(IndexAlgorithm::Brin),
}
}

fn index_is_clustered(index_id: sql::IndexId, schema: &SqlSchema, ctx: &Context) -> Option<bool> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,9 @@ fn merge_pre_3_0_index_names(old_data_model: &Datamodel, new_data_model: &mut Da
.map(|f| &f.path.first().unwrap().0)
.collect::<Vec<_>>()
}) {
retained_legacy_index_name_args
.push(ModelAndIndex::new(&model.name, old_index.name.as_ref().unwrap()))
if let Some(ref old_name) = old_index.name {
retained_legacy_index_name_args.push(ModelAndIndex::new(&model.name, old_name))
}
}
}
}
Expand Down Expand Up @@ -395,12 +396,15 @@ fn merge_changed_relation_field_names(old_data_model: &Datamodel, new_data_model

let mf = ModelAndField::new(&new_model.name, &new_field.name);

if match_as_inline
|| (is_many_to_many
//For many to many the relation infos always look the same, here we have to look at the relation name,
//which translates to the join table name. But in case of self relations we cannot correctly infer the old name
&& (old_field.relation_info.name == new_field.relation_info.name && !is_self_relation))
{
//For many to many the relation infos always look the same, here we have to look at the relation name,
//which translates to the join table name. But in case of self relations we cannot correctly infer the old name
//
// ugh :(
let match_relation_names = &old_field.relation_info.name == &new_field.relation_info.name;

let match_as_many_to_many = is_many_to_many && (match_relation_names && !is_self_relation);

if match_as_inline || match_as_many_to_many {
changed_relation_field_names.push((mf.clone(), old_field.name.clone()));
}
}
Expand Down

0 comments on commit 3153c83

Please sign in to comment.