Skip to content

Commit

Permalink
For Prisma 5: refactor(introspection): remove version checker (prisma…
Browse files Browse the repository at this point in the history
  • Loading branch information
Jolg42 authored Jun 23, 2023
1 parent a7956df commit 0de06ae
Show file tree
Hide file tree
Showing 25 changed files with 25 additions and 902 deletions.
2 changes: 0 additions & 2 deletions query-engine/schema/test-schemas/noalyss_folder.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -1009,5 +1009,3 @@ model version {
}


// introspectionSchemaVersion: NonPrisma

2 changes: 0 additions & 2 deletions query-engine/schema/test-schemas/odoo.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -3562,6 +3562,4 @@ model wizard_ir_model_menu_create {
}


// introspectionSchemaVersion: NonPrisma


2 changes: 0 additions & 2 deletions query-engine/schema/test-schemas/standupbot.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -156,5 +156,3 @@ enum team_status {
}


// introspectionSchemaVersion: NonPrisma

4 changes: 2 additions & 2 deletions schema-engine/cli/tests/cli_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ fn introspect_postgres(api: TestApi) {
stdout.read_line(&mut response).unwrap();

let expected = expect![[r#"
{"jsonrpc":"2.0","result":{"datamodel":"generator js {\n provider = \"prisma-client-js\"\n previewFeatures = [\"views\"]\n}\n\ndatasource db {\n provider = \"postgres\"\n url = env(\"TEST_DATABASE_URL\")\n}\n\nmodel A {\n id Int @id @default(autoincrement())\n data String?\n}\n\n/// The underlying view does not contain a valid unique identifier and can therefore currently not be handled by Prisma Client.\nview B {\n col Int?\n\n @@ignore\n}\n","version":"NonPrisma","views":[{"definition":"SELECT\n 1 AS col;","name":"B","schema":"public"}],"warnings":"*** WARNING ***\n\nThe following views were ignored as they do not have a valid unique identifier or id. This is currently not supported by Prisma Client. Please refer to the documentation on defining unique identifiers in views: https://pris.ly/d/view-identifiers\n - \"B\"\n"},"id":1}
{"jsonrpc":"2.0","result":{"datamodel":"generator js {\n provider = \"prisma-client-js\"\n previewFeatures = [\"views\"]\n}\n\ndatasource db {\n provider = \"postgres\"\n url = env(\"TEST_DATABASE_URL\")\n}\n\nmodel A {\n id Int @id @default(autoincrement())\n data String?\n}\n\n/// The underlying view does not contain a valid unique identifier and can therefore currently not be handled by Prisma Client.\nview B {\n col Int?\n\n @@ignore\n}\n","views":[{"definition":"SELECT\n 1 AS col;","name":"B","schema":"public"}],"warnings":"*** WARNING ***\n\nThe following views were ignored as they do not have a valid unique identifier or id. This is currently not supported by Prisma Client. Please refer to the documentation on defining unique identifiers in views: https://pris.ly/d/view-identifiers\n - \"B\"\n"},"id":1}
"#]];

expected.assert_eq(&response);
Expand Down Expand Up @@ -629,6 +629,6 @@ fn introspect_e2e() {

dbg!("response: {:?}", &response);

assert!(response.starts_with(r##"{"jsonrpc":"2.0","result":{"datamodel":"datasource db {\n provider = \"sqlite\"\n url = env(\"TEST_DATABASE_URL\")\n}\n","version":"NonPrisma","warnings":[]},"##));
assert!(response.starts_with(r##"{"jsonrpc":"2.0","result":{"datamodel":"datasource db {\n provider = \"sqlite\"\n url = env(\"TEST_DATABASE_URL\")\n}\n","warnings":[]},"##));
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use mongodb::{
Database,
};
use mongodb_schema_describer::MongoSchema;
use schema_connector::{warnings::Model, IntrospectionContext, IntrospectionResult, Version, Warnings};
use schema_connector::{warnings::Model, IntrospectionContext, IntrospectionResult, Warnings};
use statistics::*;

/// From the given database, lists all collections as models, and samples
Expand Down Expand Up @@ -81,6 +81,5 @@ pub(super) async fn sample(
is_empty: data_model.is_empty(),
warnings,
views: None,
version: Version::NonPrisma,
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ pub struct IntrospectionResult {
pub is_empty: bool,
/// Introspection warnings
pub warnings: Option<String>,
/// Inferred Prisma version
pub version: Version,
/// The database view definitions. None if preview feature
/// is not enabled.
pub views: Option<Vec<ViewDefinition>>,
Expand All @@ -34,28 +32,6 @@ pub struct IntrospectionResultOutput {
pub datamodel: String,
/// warnings
pub warnings: Option<String>,
/// version
pub version: Version,
/// views
pub views: Option<Vec<ViewDefinition>>,
}

/// The inferred Prisma version.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
pub enum Version {
/// Not a Prisma database.
NonPrisma,
/// Maybe a Prisma 1.0 database.
Prisma1,
/// Maybe a Prisma 1.1 database.
Prisma11,
/// Maybe a Prisma 2 database.
Prisma2,
}

impl Version {
/// Is the database a Prisma 1.0 or 1.1 database.
pub fn is_prisma1(self) -> bool {
matches!(self, Self::Prisma1 | Self::Prisma11)
}
}
2 changes: 1 addition & 1 deletion schema-engine/connectors/schema-connector/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub use destructive_change_checker::{
pub use diff::DiffTarget;
pub use error::{ConnectorError, ConnectorResult};
pub use introspection_context::{CompositeTypeDepth, IntrospectionContext};
pub use introspection_result::{IntrospectionResult, IntrospectionResultOutput, Version, ViewDefinition};
pub use introspection_result::{IntrospectionResult, IntrospectionResultOutput, ViewDefinition};
pub use migration::Migration;
pub use migration_persistence::{MigrationPersistence, MigrationRecord, PersistenceNotInitializedError, Timestamp};
pub use warnings::Warnings;
Expand Down
21 changes: 0 additions & 21 deletions schema-engine/connectors/schema-connector/src/warnings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ fn display_list<T: Ord>(
/// the user.
#[derive(Debug, Default, PartialEq)]
pub struct Warnings {
/// Fields that are using Prisma 1 UUID defaults.
pub prisma_1_uuid_defaults: Vec<ModelAndField>,
/// Fields that are using Prisma 1 CUID defaults.
pub prisma_1_cuid_defaults: Vec<ModelAndField>,
/// Fields having an empty name.
pub fields_with_empty_names_in_model: Vec<ModelAndField>,
/// Fields having an empty name.
Expand Down Expand Up @@ -150,11 +146,6 @@ impl Warnings {
pub fn is_empty(&self) -> bool {
self == &Self::default()
}

/// True, if the datamodel has Prisma 1 style defaults
pub fn uses_prisma_1_defaults(&self) -> bool {
!self.prisma_1_uuid_defaults.is_empty() || !self.prisma_1_cuid_defaults.is_empty()
}
}

impl fmt::Display for Warnings {
Expand Down Expand Up @@ -192,18 +183,6 @@ impl fmt::Display for Warnings {
fmt::Display::fmt(&GroupBy(items), f)
}

render_warnings(
"These id fields had a `@default(uuid())` added because we believe the schema was created by Prisma 1:",
&self.prisma_1_uuid_defaults,
f,
)?;

render_warnings(
"These id fields had a `@default(cuid())` added because we believe the schema was created by Prisma 1:",
&self.prisma_1_cuid_defaults,
f,
)?;

render_warnings_grouped(
"These fields were commented out because their names are currently not supported by Prisma. Please provide valid ones that match [a-zA-Z][a-zA-Z0-9_]* using the `@map` attribute:",
&self.fields_with_empty_names_in_model,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ mod introspection_map;
mod introspection_pair;
mod rendering;
mod sanitize_datamodel_names;
mod version_checker;
mod warnings;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub(crate) use context::DatamodelCalculatorContext;

use crate::introspection::{rendering, warnings};
use psl::PreviewFeature;
use schema_connector::{IntrospectionContext, IntrospectionResult, Version};
use schema_connector::{IntrospectionContext, IntrospectionResult};
use sql_schema_describer as sql;

/// Calculate a data model from a database schema.
Expand All @@ -18,12 +18,6 @@ pub fn calculate(schema: &sql::SqlSchema, ctx: &IntrospectionContext, search_pat

let empty_warnings = warnings.is_empty();

let version = if !empty_warnings && !warnings.uses_prisma_1_defaults() {
Version::NonPrisma
} else {
ctx.version
};

let views = if ctx.config.preview_features().contains(PreviewFeature::Views) {
Some(views)
} else {
Expand All @@ -39,7 +33,6 @@ pub fn calculate(schema: &sql::SqlSchema, ctx: &IntrospectionContext, search_pat
IntrospectionResult {
data_model: schema_string,
is_empty,
version,
warnings,
views,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
mod flavour;

use crate::introspection::{
introspection_helpers::{is_new_migration_table, is_old_migration_table, is_prisma_join_table, is_relay_table},
introspection_helpers::{
is_new_migration_table, is_old_migration_table, is_prisma_m_to_n_relation, is_relay_table,
},
introspection_map::{IntrospectionMap, RelationName},
introspection_pair::{EnumPair, ModelPair, RelationFieldDirection, ViewPair},
sanitize_datamodel_names::{EnumVariantName, IntrospectedName, ModelName},
version_checker,
};
use psl::{
builtin_connectors::*,
Expand All @@ -14,7 +15,7 @@ use psl::{
Configuration, PreviewFeature,
};
use quaint::prelude::SqlFamily;
use schema_connector::{IntrospectionContext, Version};
use schema_connector::IntrospectionContext;
use sql_schema_describer as sql;
use std::borrow::Cow;

Expand All @@ -25,7 +26,6 @@ pub(crate) struct DatamodelCalculatorContext<'a> {
pub(crate) render_config: bool,
pub(crate) sql_schema: &'a sql::SqlSchema,
pub(crate) sql_family: SqlFamily,
pub(crate) version: Version,
pub(crate) previous_schema: &'a psl::ValidatedSchema,
pub(crate) introspection_map: IntrospectionMap<'a>,
pub(crate) force_namespaces: Option<&'a [String]>,
Expand All @@ -43,7 +43,6 @@ impl<'a> DatamodelCalculatorContext<'a> {
};

let mut ctx = DatamodelCalculatorContext {
version: Version::NonPrisma,
config: ctx.configuration(),
render_config: ctx.render_config,
sql_schema,
Expand All @@ -56,7 +55,6 @@ impl<'a> DatamodelCalculatorContext<'a> {
};

ctx.introspection_map = IntrospectionMap::new(&ctx);
ctx.version = version_checker::check_prisma_version(&ctx);

ctx
}
Expand Down Expand Up @@ -110,7 +108,7 @@ impl<'a> DatamodelCalculatorContext<'a> {
.table_walkers()
.filter(|table| !is_old_migration_table(*table))
.filter(|table| !is_new_migration_table(*table))
.filter(|table| !is_prisma_join_table(*table))
.filter(|table| !is_prisma_m_to_n_relation(*table))
.filter(|table| !is_relay_table(*table))
.map(move |next| {
let previous = self.existing_model(next.id);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Small utility functions.
use sql::walkers::TableWalker;
use sql_schema_describer::{self as sql, ColumnTypeFamily, IndexType};
use sql_schema_describer::{self as sql, IndexType};
use std::cmp;

/// This function implements the reverse behaviour of the `Ord` implementation for `Option`: it
Expand Down Expand Up @@ -55,47 +55,8 @@ pub(crate) fn is_relay_table(table: TableWalker<'_>) -> bool {
.any(|col| col.name().eq_ignore_ascii_case("stablemodelidentifier"))
}

/// If the table has `createdAt` and `updatedAt` fields.
pub(crate) fn has_created_at_and_updated_at(table: TableWalker<'_>) -> bool {
let has_created_at = table.columns().any(|col| {
col.name().eq_ignore_ascii_case("createdat") && col.column_type().family == ColumnTypeFamily::DateTime
});

let has_updated_at = table.columns().any(|col| {
col.name().eq_ignore_ascii_case("updatedat") && col.column_type().family == ColumnTypeFamily::DateTime
});

has_created_at && has_updated_at
}

/// A special table to handle many to many relations in Prisma.
pub(crate) fn is_prisma_join_table(t: TableWalker<'_>) -> bool {
is_prisma_1_point_0_join_table(t) || is_prisma_1_point_1_or_2_join_table(t)
}

/// A legacy Prisma 1 list table.
pub(crate) fn is_prisma_1_or_11_list_table(table: TableWalker<'_>) -> bool {
table.columns().len() == 3
&& table.columns().any(|col| col.name().eq_ignore_ascii_case("nodeid"))
&& table.column("position").is_some()
&& table.column("value").is_some()
}

/// A special legacy join table, seen in Prisma 1.1 and 1.2.
pub(crate) fn is_prisma_1_point_1_or_2_join_table(table: TableWalker<'_>) -> bool {
table.columns().len() == 2 && table.indexes().len() >= 2 && common_prisma_m_to_n_relation_conditions(table)
}

/// A special legacy join table, seen in Prisma 1.0.
pub(crate) fn is_prisma_1_point_0_join_table(table: TableWalker<'_>) -> bool {
table.columns().len() == 3
&& table.indexes().len() >= 2
&& table.columns().any(|c| c.name() == "id")
&& common_prisma_m_to_n_relation_conditions(table)
}

/// If a relation defines a Prisma many to many relation.
fn common_prisma_m_to_n_relation_conditions(table: TableWalker<'_>) -> bool {
pub(crate) fn is_prisma_m_to_n_relation(table: TableWalker<'_>) -> bool {
fn is_a(column: &str) -> bool {
column.eq_ignore_ascii_case("a")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ fn populate_top_level_names<'a>(
) {
for table in sql_schema
.table_walkers()
.filter(|t| !helpers::is_prisma_join_table(*t))
.filter(|t| !helpers::is_prisma_m_to_n_relation(*t))
{
let name = map
.existing_models
Expand Down Expand Up @@ -118,7 +118,7 @@ fn populate_top_level_names<'a>(
fn position_inline_relation_fields(sql_schema: &sql::SqlSchema, map: &mut IntrospectionMap<'_>) {
for table in sql_schema
.table_walkers()
.filter(|t| !helpers::is_prisma_join_table(*t))
.filter(|t| !helpers::is_prisma_m_to_n_relation(*t))
{
for fk in table.foreign_keys() {
map.inline_relation_positions
Expand All @@ -134,7 +134,10 @@ fn position_inline_relation_fields(sql_schema: &sql::SqlSchema, map: &mut Intros
/// join table) are sorted in a specific way. We handle the sorting
/// here.
fn position_m2m_relation_fields(sql_schema: &sql::SqlSchema, map: &mut IntrospectionMap<'_>) {
for table in sql_schema.table_walkers().filter(|t| helpers::is_prisma_join_table(*t)) {
for table in sql_schema
.table_walkers()
.filter(|t| helpers::is_prisma_m_to_n_relation(*t))
{
let mut fks = table.foreign_keys();

if let (Some(first_fk), Some(second_fk)) = (fks.next(), fks.next()) {
Expand Down Expand Up @@ -314,7 +317,7 @@ fn match_existing_m2m_relations(
) {
map.existing_m2m_relations = sql_schema
.table_walkers()
.filter(|t| helpers::is_prisma_join_table(*t))
.filter(|t| helpers::is_prisma_m_to_n_relation(*t))
.filter_map(|table| {
prisma_schema
.db
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! introspected schema with as much clarity and as little ambiguity as possible.
use crate::introspection::{
datamodel_calculator::DatamodelCalculatorContext, introspection_helpers::is_prisma_join_table,
datamodel_calculator::DatamodelCalculatorContext, introspection_helpers::is_prisma_m_to_n_relation,
};
use sql_schema_describer as sql;
use std::{
Expand Down Expand Up @@ -74,7 +74,7 @@ pub(super) fn introspect<'a>(ctx: &DatamodelCalculatorContext<'a>, map: &mut sup
let ambiguous_relations = find_ambiguous_relations(ctx);

for table in ctx.sql_schema.table_walkers() {
if is_prisma_join_table(table) {
if is_prisma_m_to_n_relation(table) {
let name = prisma_m2m_relation_name(table, &ambiguous_relations, ctx);
names.m2m_relation_names.insert(table.id, name);
} else {
Expand Down Expand Up @@ -175,7 +175,7 @@ fn find_ambiguous_relations(ctx: &DatamodelCalculatorContext<'_>) -> HashSet<[sq
let mut ambiguous_relations = HashSet::new();

for table in ctx.sql_schema.table_walkers() {
if is_prisma_join_table(table) {
if is_prisma_m_to_n_relation(table) {
m2m_relation_ambiguousness(table, &mut ambiguous_relations)
} else {
for fk in table.foreign_keys() {
Expand Down Expand Up @@ -205,7 +205,7 @@ fn m2m_relation_ambiguousness(table: sql::TableWalker<'_>, ambiguous_relations:
}

// Check for conflicts with another m2m relation.
for other_m2m in table.schema.table_walkers().filter(|t| is_prisma_join_table(*t)) {
for other_m2m in table.schema.table_walkers().filter(|t| is_prisma_m_to_n_relation(*t)) {
if other_m2m.id != table.id && table_ids_for_m2m_relation_table(other_m2m) == tables {
ambiguous_relations.insert(tables);
}
Expand Down
Loading

0 comments on commit 0de06ae

Please sign in to comment.