Skip to content

Commit

Permalink
feat(dmmf): include primary keys in indexes section
Browse files Browse the repository at this point in the history
  • Loading branch information
aqrln committed Jul 10, 2024
1 parent d45499b commit ac9a360
Show file tree
Hide file tree
Showing 17 changed files with 614 additions and 42 deletions.
24 changes: 24 additions & 0 deletions prisma-fmt/src/get_datamodel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,18 @@ mod tests {
],
"types": [],
"indexes": [
{
"model": "User",
"type": "id",
"isDefinedOnField": true,
"fields": [
{
"path": [
"id"
]
}
]
},
{
"model": "User",
"type": "unique",
Expand All @@ -204,6 +216,18 @@ mod tests {
}
]
},
{
"model": "Post",
"type": "id",
"isDefinedOnField": true,
"fields": [
{
"path": [
"id"
]
}
]
},
{
"model": "Post",
"type": "normal",
Expand Down
24 changes: 24 additions & 0 deletions prisma-fmt/src/get_dmmf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,18 @@ mod tests {
],
"types": [],
"indexes": [
{
"model": "A",
"type": "id",
"isDefinedOnField": true,
"fields": [
{
"path": [
"id"
]
}
]
},
{
"model": "A",
"type": "unique",
Expand All @@ -479,6 +491,18 @@ mod tests {
]
}
]
},
{
"model": "B",
"type": "id",
"isDefinedOnField": true,
"fields": [
{
"path": [
"id"
]
}
]
}
]
},
Expand Down
74 changes: 48 additions & 26 deletions query-engine/dmmf/src/ast_builders/datamodel_ast_builder.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::serialization_ast::{
datamodel_ast::{Datamodel, Enum, EnumValue, Field, Function, Model, PrimaryKey, UniqueIndex},
Index, IndexField,
Index, IndexField, IndexType,
};
use bigdecimal::ToPrimitive;
use itertools::Either;
Expand Down Expand Up @@ -243,34 +243,56 @@ fn relation_field_to_dmmf(field: walkers::RelationFieldWalker<'_>) -> Field {
}

fn model_indexes_to_dmmf(model: walkers::ModelWalker<'_>) -> impl Iterator<Item = Index> + '_ {
model.indexes().map(move |index| Index {
model: model.name().to_owned(),
r#type: index.index_type().into(),
is_defined_on_field: index.is_defined_on_field(),
name: index.name().map(ToOwned::to_owned),
mapped_name: index.mapped_name().map(ToOwned::to_owned),
algorithm: index.algorithm().map(|alg| alg.to_string()),
clustered: index.clustered(),
fields: index
.scalar_field_attributes()
.map(|sfa| IndexField {
path: sfa
.as_path_to_indexed_field()
.into_iter()
.map(|(field_name, type_name)| match type_name {
None => field_name.to_owned(),
Some(type_name) => format!("{type_name}.{field_name}"),
})
model
.primary_key()
.into_iter()
.map(move |pk| Index {
model: model.name().to_owned(),
r#type: IndexType::Id,
is_defined_on_field: pk.is_defined_on_field(),
name: pk.name().map(ToOwned::to_owned),
mapped_name: pk.mapped_name().map(ToOwned::to_owned),
algorithm: None,
clustered: pk.clustered(),
fields: pk
.scalar_field_attributes()
.map(scalar_field_attribute_to_dmmf)
.collect(),
})
.chain(model.indexes().map(move |index| {
Index {
model: model.name().to_owned(),
r#type: index.index_type().into(),
is_defined_on_field: index.is_defined_on_field(),
name: index.name().map(ToOwned::to_owned),
mapped_name: index.mapped_name().map(ToOwned::to_owned),
algorithm: index.algorithm().map(|alg| alg.to_string()),
clustered: index.clustered(),
fields: index
.scalar_field_attributes()
.map(scalar_field_attribute_to_dmmf)
.collect(),
sort_order: sfa.sort_order().map(Into::into),
length: sfa.length(),
operator_class: sfa.operator_class().map(|oc| match oc.get() {
Either::Left(oc) => oc.to_string(),
Either::Right(oc) => oc.to_owned(),
}),
}
}))
}

fn scalar_field_attribute_to_dmmf(sfa: walkers::ScalarFieldAttributeWalker<'_>) -> IndexField {
IndexField {
path: sfa
.as_path_to_indexed_field()
.into_iter()
.map(|(field_name, type_name)| match type_name {
None => field_name.to_owned(),
Some(type_name) => format!("{type_name}.{field_name}"),
})
.collect(),
})
sort_order: sfa.sort_order().map(Into::into),
length: sfa.length(),
operator_class: sfa.operator_class().map(|oc| match oc.get() {
Either::Left(oc) => oc.to_string(),
Either::Right(oc) => oc.to_owned(),
}),
}
}

fn default_value_to_serde(dv: &DefaultKind) -> serde_json::Value {
Expand Down
31 changes: 18 additions & 13 deletions query-engine/dmmf/src/serialization_ast/datamodel_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,31 +141,36 @@ pub struct IndexField {
pub operator_class: Option<String>,
}

macro_rules! convert_enum {
( $from:path => $to:ident { $( $variant:ident, )+ } ) => {
#[derive(Debug, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub enum $to {
$( $variant, )+
}

macro_rules! from {
( $from:path => $to:ident { $( $variant:ident ),+ } ) => {
impl From<$from> for $to {
fn from(value: $from) -> Self {
match value {
$( <$from>::$variant => <$to>::$variant, )+
$( <$from>::$variant => <$to>::$variant ),+
}
}
}
};
}

convert_enum!(psl::parser_database::IndexType => IndexType {
#[derive(Debug, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub enum IndexType {
Id,
Normal,
Unique,
Fulltext,
});
}

convert_enum!(psl::parser_database::SortOrder => SortOrder {
// `Id` doesn't exist in `psl::parser_database::IndexType` as primary keys are not represented as
// such on that level, so we only generate the From impl for the other three variants.
from!(psl::parser_database::IndexType => IndexType { Normal, Unique, Fulltext });

#[derive(Debug, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub enum SortOrder {
Asc,
Desc,
});
}

from!(psl::parser_database::SortOrder => SortOrder { Asc, Desc });
Binary file not shown.
12 changes: 12 additions & 0 deletions query-engine/dmmf/test_files/functions.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@
],
"types": [],
"indexes": [
{
"model": "User",
"type": "id",
"isDefinedOnField": true,
"fields": [
{
"path": [
"id"
]
}
]
},
{
"model": "User",
"type": "unique",
Expand Down
121 changes: 121 additions & 0 deletions query-engine/dmmf/test_files/general.json
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,18 @@
],
"types": [],
"indexes": [
{
"model": "User",
"type": "id",
"isDefinedOnField": true,
"fields": [
{
"path": [
"id"
]
}
]
},
{
"model": "User",
"type": "unique",
Expand All @@ -739,6 +751,18 @@
}
]
},
{
"model": "Profile",
"type": "id",
"isDefinedOnField": true,
"fields": [
{
"path": [
"id"
]
}
]
},
{
"model": "Profile",
"type": "unique",
Expand All @@ -751,6 +775,47 @@
}
]
},
{
"model": "Post",
"type": "id",
"isDefinedOnField": false,
"fields": [
{
"path": [
"title"
]
},
{
"path": [
"createdAt"
]
}
]
},
{
"model": "Category",
"type": "id",
"isDefinedOnField": true,
"fields": [
{
"path": [
"id"
]
}
]
},
{
"model": "PostToCategory",
"type": "id",
"isDefinedOnField": true,
"fields": [
{
"path": [
"id"
]
}
]
},
{
"model": "PostToCategory",
"type": "unique",
Expand All @@ -768,6 +833,18 @@
}
]
},
{
"model": "A",
"type": "id",
"isDefinedOnField": true,
"fields": [
{
"path": [
"id"
]
}
]
},
{
"model": "A",
"type": "unique",
Expand All @@ -780,6 +857,37 @@
}
]
},
{
"model": "B",
"type": "id",
"isDefinedOnField": true,
"fields": [
{
"path": [
"id"
]
}
]
},
{
"model": "NamedCompounds",
"type": "id",
"isDefinedOnField": false,
"name": "MyPrimary",
"mappedName": "DbPrimary",
"fields": [
{
"path": [
"a"
]
},
{
"path": [
"b"
]
}
]
},
{
"model": "NamedCompounds",
"type": "unique",
Expand All @@ -799,6 +907,19 @@
}
]
},
{
"model": "MappedSingles",
"type": "id",
"isDefinedOnField": true,
"mappedName": "Primary",
"fields": [
{
"path": [
"a"
]
}
]
},
{
"model": "MappedSingles",
"type": "unique",
Expand Down
Loading

0 comments on commit ac9a360

Please sign in to comment.