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

PSL: Implementing map field for @default attribute on SQL Server #2156

Merged
merged 12 commits into from Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -188,7 +188,7 @@ mod tests {
}),
),
database_name: None,
default_value: Some(DMLDefault::Expression(ValueGenerator::new_autoincrement())),
default_value: Some(DMLDefault::new_expression(ValueGenerator::new_autoincrement())),
documentation: None,
is_generated: false,
is_updated_at: false,
Expand Down Expand Up @@ -262,7 +262,7 @@ mod tests {
}),
),
database_name: None,
default_value: Some(DMLDefault::Expression(ValueGenerator::new_autoincrement())),
default_value: Some(DMLDefault::new_expression(ValueGenerator::new_autoincrement())),
documentation: None,
is_generated: false,
is_updated_at: false,
Expand Down Expand Up @@ -454,7 +454,7 @@ mod tests {
}),
),
database_name: None,
default_value: Some(DMLDefault::Expression(ValueGenerator::new_autoincrement())),
default_value: Some(DMLDefault::new_expression(ValueGenerator::new_autoincrement())),
documentation: None,
is_generated: false,
is_updated_at: false,
Expand Down Expand Up @@ -520,7 +520,7 @@ mod tests {
}),
),
database_name: None,
default_value: Some(DMLDefault::Expression(ValueGenerator::new_autoincrement())),
default_value: Some(DMLDefault::new_expression(ValueGenerator::new_autoincrement())),
documentation: None,
is_generated: false,
is_updated_at: false,
Expand Down Expand Up @@ -722,7 +722,7 @@ mod tests {
}),
),
database_name: None,
default_value: Some(DMLDefault::Expression(ValueGenerator::new_autoincrement())),
default_value: Some(DMLDefault::new_expression(ValueGenerator::new_autoincrement())),
documentation: None,
is_generated: false,
is_updated_at: false,
Expand Down Expand Up @@ -855,7 +855,7 @@ mod tests {
}),
),
database_name: None,
default_value: Some(DMLDefault::Expression(ValueGenerator::new_autoincrement())),
default_value: Some(DMLDefault::new_expression(ValueGenerator::new_autoincrement())),
documentation: None,
is_generated: false,
is_updated_at: false,
Expand Down Expand Up @@ -921,7 +921,7 @@ mod tests {
}),
),
database_name: None,
default_value: Some(DMLDefault::Expression(ValueGenerator::new_autoincrement())),
default_value: Some(DMLDefault::new_expression(ValueGenerator::new_autoincrement())),
documentation: None,
is_generated: false,
is_updated_at: false,
Expand Down
Expand Up @@ -275,18 +275,45 @@ pub(crate) fn calculate_backrelation_field(
pub(crate) fn calculate_default(table: &Table, column: &Column, arity: &FieldArity) -> Option<DMLDef> {
match (column.default.as_ref().map(|d| d.kind()), &column.tpe.family) {
(_, _) if *arity == FieldArity::List => None,
(_, ColumnTypeFamily::Int) if column.auto_increment => Some(DMLDef::Expression(VG::new_autoincrement())),
(_, ColumnTypeFamily::BigInt) if column.auto_increment => Some(DMLDef::Expression(VG::new_autoincrement())),
(_, ColumnTypeFamily::Int) if is_sequence(column, table) => Some(DMLDef::Expression(VG::new_autoincrement())),
(_, ColumnTypeFamily::Int) if column.auto_increment => Some(DMLDef::new_expression(VG::new_autoincrement())),
(_, ColumnTypeFamily::BigInt) if column.auto_increment => Some(DMLDef::new_expression(VG::new_autoincrement())),
(_, ColumnTypeFamily::Int) if is_sequence(column, table) => {
Some(DMLDef::new_expression(VG::new_autoincrement()))
}
(_, ColumnTypeFamily::BigInt) if is_sequence(column, table) => {
Some(DMLDef::Expression(VG::new_autoincrement()))
Some(DMLDef::new_expression(VG::new_autoincrement()))
}
(Some(DefaultKind::Sequence(_)), _) => Some(DMLDef::new_expression(VG::new_autoincrement())),
(Some(DefaultKind::Now), ColumnTypeFamily::DateTime) => {
let mut default = DMLDef::new_expression(VG::new_now());
let db_name = column.default.as_ref().and_then(|df| df.constraint_name());

if let Some(name) = db_name {
default.set_db_name(name);
}

Some(default)
}
(Some(DefaultKind::Sequence(_)), _) => Some(DMLDef::Expression(VG::new_autoincrement())),
(Some(DefaultKind::Now), ColumnTypeFamily::DateTime) => Some(DMLDef::Expression(VG::new_now())),
(Some(DefaultKind::DbGenerated(default_string)), _) => {
Some(DMLDef::Expression(VG::new_dbgenerated(default_string.clone())))
let mut default = DMLDef::new_expression(VG::new_dbgenerated(default_string.clone()));
let db_name = column.default.as_ref().and_then(|df| df.constraint_name());

if let Some(name) = db_name {
default.set_db_name(name);
}

Some(default)
}
(Some(DefaultKind::Value(val)), _) => {
let mut default = DMLDef::new_single(val.clone());
pimeys marked this conversation as resolved.
Show resolved Hide resolved
let db_name = column.default.as_ref().and_then(|df| df.constraint_name());

if let Some(name) = db_name {
default.set_db_name(name);
}

Some(default)
}
(Some(DefaultKind::Value(val)), _) => Some(DMLDef::Single(val.clone())),
_ => None,
}
}
Expand Down
Expand Up @@ -53,10 +53,10 @@ pub fn add_prisma_1_id_defaults(
for (mf, cuid) in needs_to_be_changed {
let field = &mut data_model.find_scalar_field_mut(&mf.model, &mf.field);
if cuid {
field.default_value = Some(dml::DefaultValue::Expression(ValueGenerator::new_cuid()));
field.default_value = Some(dml::DefaultValue::new_expression(ValueGenerator::new_cuid()));
inferred_cuids.push(mf);
} else {
field.default_value = Some(dml::DefaultValue::Expression(ValueGenerator::new_uuid()));
field.default_value = Some(dml::DefaultValue::new_expression(ValueGenerator::new_uuid()));
inferred_uuids.push(mf);
}
}
Expand Down
Expand Up @@ -308,11 +308,13 @@ pub fn enrich(old_data_model: &Datamodel, new_data_model: &mut Datamodel, ctx: &
for field in fields_to_be_changed {
let field = new_data_model.find_scalar_field_mut(&field.0, &field.1);
if field.default_value
== Some(DefaultValue::Single(PrismaValue::Enum(
== Some(DefaultValue::new_single(PrismaValue::Enum(
changed_enum_value.0.value.clone(),
)))
{
field.default_value = Some(DefaultValue::Single(PrismaValue::Enum(changed_enum_value.1.clone())));
field.default_value = Some(DefaultValue::new_single(PrismaValue::Enum(
changed_enum_value.1.clone(),
)));
}
}
}
Expand Down Expand Up @@ -370,11 +372,13 @@ pub fn enrich(old_data_model: &Datamodel, new_data_model: &mut Datamodel, ctx: &
if let Some(old_model) = old_data_model.find_model(&model.name) {
if let Some(old_field) = old_model.find_scalar_field(&field.name) {
if field.default_value.is_none() && field.field_type.is_string() {
if old_field.default_value == Some(DefaultValue::Expression(ValueGenerator::new_cuid())) {
if old_field.default_value == Some(DefaultValue::new_expression(ValueGenerator::new_cuid()))
{
re_introspected_prisma_level_cuids.push(ModelAndField::new(&model.name, &field.name));
}

if old_field.default_value == Some(DefaultValue::Expression(ValueGenerator::new_uuid())) {
if old_field.default_value == Some(DefaultValue::new_expression(ValueGenerator::new_uuid()))
{
re_introspected_prisma_level_uuids.push(ModelAndField::new(&model.name, &field.name));
}
}
Expand All @@ -390,13 +394,13 @@ pub fn enrich(old_data_model: &Datamodel, new_data_model: &mut Datamodel, ctx: &
for cuid in &re_introspected_prisma_level_cuids {
new_data_model
.find_scalar_field_mut(&cuid.model, &cuid.field)
.default_value = Some(DefaultValue::Expression(ValueGenerator::new_cuid()));
.default_value = Some(DefaultValue::new_expression(ValueGenerator::new_cuid()));
}

for uuid in &re_introspected_prisma_level_uuids {
new_data_model
.find_scalar_field_mut(&uuid.model, &uuid.field)
.default_value = Some(DefaultValue::Expression(ValueGenerator::new_uuid()));
.default_value = Some(DefaultValue::new_expression(ValueGenerator::new_uuid()));
}

for updated_at in &re_introspected_updated_at {
Expand Down
@@ -1,7 +1,7 @@
use crate::SqlFamilyTrait;
use datamodel::{
reserved_model_names::is_reserved_type_name, Datamodel, DefaultValue, Field, FieldType, Model, WithDatabaseName,
WithName,
reserved_model_names::is_reserved_type_name, Datamodel, DefaultKind, DefaultValue, Field, FieldType, Model,
ValueGenerator, WithDatabaseName, WithName,
};
use introspection_connector::IntrospectionContext;
use once_cell::sync::Lazy;
Expand Down Expand Up @@ -98,15 +98,19 @@ fn sanitize_models(datamodel: &mut Datamodel, ctx: &IntrospectionContext) -> Has

// If the field also has an associated default enum value, we need to sanitize that enum value.
// The actual enum value renames _in the enum itself_ are done at a later stage.
if let Some(DefaultValue::Single(PrismaValue::Enum(value))) = &mut sf.default_value {
if let Some(DefaultKind::Single(PrismaValue::Enum(value))) =
sf.default_value.as_mut().map(|dv| dv.mut_kind())
{
let new_default = if value.is_empty() {
DefaultValue::Single(PrismaValue::Enum(EMPTY_ENUM_PLACEHOLDER.to_string()))
DefaultValue::new_single(PrismaValue::Enum(EMPTY_ENUM_PLACEHOLDER.to_string()))
} else {
let sanitized_value = sanitize_string(value);

match sanitized_value {
x if x.is_empty() => DefaultValue::new_db_generated(value.clone()),
_ => DefaultValue::Single(PrismaValue::Enum(sanitized_value)),
x if x.is_empty() => {
DefaultValue::new_expression(ValueGenerator::new_dbgenerated(value.clone()))
}
_ => DefaultValue::new_single(PrismaValue::Enum(sanitized_value)),
}
};

Expand Down
Expand Up @@ -5,6 +5,7 @@ use introspection_engine_tests::test_api::TestApi;
use introspection_engine_tests::test_api::*;

use introspection_engine_tests::TestResult;
use quaint::prelude::Queryable;
use test_macros::test_connector;

#[test_connector(preview_features("NamedConstraints"), tags(Mssql, Postgres))]
Expand Down Expand Up @@ -359,3 +360,45 @@ async fn introspecting_custom_fk_names_does_not_return_them_on_sqlite(api: &Test

Ok(())
}

#[test_connector(preview_features("NamedConstraints"), tags(Mssql))]
async fn introspecting_custom_default_names_should_output_to_dml(api: &TestApi) -> TestResult {
let create_table = format!(
"CREATE TABLE [{}].[custom_defaults_test] (id INT CONSTRAINT pk_meow PRIMARY KEY, data NVARCHAR(255) CONSTRAINT meow DEFAULT 'foo')",
api.schema_name()
);

api.database().raw_cmd(&create_table).await?;

let dm = r#"
model custom_defaults_test {
id Int @id(map: "pk_meow")
data String? @default("foo", map: "meow") @db.NVarChar(255)
}
"#;

api.assert_eq_datamodels(&dm, &api.introspect().await?);

Ok(())
}

#[test_connector(preview_features("NamedConstraints"), tags(Mssql))]
async fn introspecting_default_default_names_should_not_output_to_dml(api: &TestApi) -> TestResult {
let create_table = format!(
"CREATE TABLE [{}].[custom_defaults_test] (id INT CONSTRAINT pk_meow PRIMARY KEY, data NVARCHAR(255) CONSTRAINT custom_defaults_test_data_df DEFAULT 'foo')",
api.schema_name()
);

api.database().raw_cmd(&create_table).await?;

let dm = indoc! {r#"
model custom_defaults_test {
id Int @id(map: "pk_meow")
data String? @default("foo") @db.NVarChar(255)
}
"#};

api.assert_eq_datamodels(&dm, &api.introspect().await?);

Ok(())
}
5 changes: 5 additions & 0 deletions libs/datamodel/connectors/datamodel-connector/src/lib.rs
Expand Up @@ -36,6 +36,10 @@ pub trait Connector: Send + Sync {
self.has_capability(ConnectorCapability::NamedForeignKeys)
}

fn supports_named_default_values(&self) -> bool {
self.has_capability(ConnectorCapability::NamedDefaultValues)
}

fn supports_referential_action(&self, action: ReferentialAction) -> bool {
self.referential_actions().contains(action)
}
Expand Down Expand Up @@ -241,6 +245,7 @@ capabilities!(
NamedPrimaryKeys,
NamedForeignKeys,
ReferenceCycleDetection,
NamedDefaultValues,
// Start of query-engine-only Capabilities
InsensitiveFilters,
CreateMany,
Expand Down