Skip to content

Commit

Permalink
me: pass namespaces to diff in devDiagnostic->diagnoseMigrationHistory (
Browse files Browse the repository at this point in the history
#3481)

The namespaces are from the schema the engine was started with

This should address prisma/prisma#16634 and prisma/prisma#16585
  • Loading branch information
tomhoule committed Dec 9, 2022
1 parent 758a6da commit 07d67d0
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 25 deletions.
8 changes: 7 additions & 1 deletion libs/test-setup/src/lib.rs
Expand Up @@ -5,14 +5,14 @@
//! engines.

pub mod mysql;
pub mod postgres;
/// Tokio test runtime utils.
pub mod runtime;

mod capabilities;
mod diff;
mod logging;
mod mssql;
mod postgres;
mod sqlite;
mod tags;
mod test_api_args;
Expand Down Expand Up @@ -48,6 +48,12 @@ macro_rules! only {

pub struct TestDb(&'static test_api_args::DbUnderTest);

impl TestDb {
pub fn url(&self) -> &'static str {
&self.0.database_url
}
}

#[doc(hidden)]
#[inline(never)]
pub fn only_impl(include_tagged: BitFlags<Tags>, exclude_tags: BitFlags<Tags>) -> (bool, TestDb) {
Expand Down
2 changes: 1 addition & 1 deletion libs/test-setup/src/postgres.rs
Expand Up @@ -44,7 +44,7 @@ pub(crate) fn get_postgres_tags(database_url: &str) -> Result<BitFlags<Tags>, St
tok(fut)
}

pub(crate) async fn create_postgres_database(database_url: &str, db_name: &str) -> Result<(Quaint, String), AnyError> {
pub async fn create_postgres_database(database_url: &str, db_name: &str) -> Result<(Quaint, String), AnyError> {
let mut url: Url = database_url.parse()?;
let mut postgres_db_url = url.clone();

Expand Down
2 changes: 1 addition & 1 deletion libs/test-setup/src/test_api_args.rs
Expand Up @@ -7,7 +7,7 @@ use std::{fmt::Display, io::Write as _};
#[derive(Debug)]
pub(crate) struct DbUnderTest {
pub(crate) capabilities: BitFlags<Capabilities>,
database_url: String,
pub(crate) database_url: String,
shadow_database_url: Option<String>,
provider: &'static str,
pub(crate) tags: BitFlags<Tags>,
Expand Down
5 changes: 3 additions & 2 deletions migration-engine/core/src/commands/dev_diagnostic.rs
Expand Up @@ -3,12 +3,13 @@ use super::{
HistoryDiagnostic,
};
use crate::json_rpc::types::{DevAction, DevActionReset, DevDiagnosticInput, DevDiagnosticOutput};
use migration_connector::{migrations_directory, ConnectorResult, MigrationConnector};
use migration_connector::{migrations_directory, ConnectorResult, MigrationConnector, Namespaces};

/// Method called at the beginning of `migrate dev` to decide the course of
/// action based on the current state of the workspace.
pub async fn dev_diagnostic(
input: DevDiagnosticInput,
namespaces: Option<Namespaces>,
connector: &mut dyn MigrationConnector,
) -> ConnectorResult<DevDiagnosticOutput> {
migrations_directory::error_on_changed_provider(&input.migrations_directory_path, connector.connector_type())?;
Expand All @@ -18,7 +19,7 @@ pub async fn dev_diagnostic(
opt_in_to_shadow_database: true,
};

let diagnose_migration_history_output = diagnose_migration_history(diagnose_input, connector).await?;
let diagnose_migration_history_output = diagnose_migration_history(diagnose_input, namespaces, connector).await?;

check_for_broken_migrations(&diagnose_migration_history_output)?;

Expand Down
@@ -1,6 +1,6 @@
use crate::CoreResult;
use migration_connector::{
migrations_directory::*, ConnectorError, DiffTarget, MigrationConnector, MigrationRecord,
migrations_directory::*, ConnectorError, DiffTarget, MigrationConnector, MigrationRecord, Namespaces,
PersistenceNotInitializedError,
};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -65,6 +65,7 @@ impl DiagnoseMigrationHistoryOutput {
/// reads, it does not write to the dev database nor the migrations directory.
pub async fn diagnose_migration_history(
input: DiagnoseMigrationHistoryInput,
namespaces: Option<Namespaces>,
connector: &mut dyn MigrationConnector,
) -> CoreResult<DiagnoseMigrationHistoryOutput> {
tracing::debug!("Diagnosing migration history");
Expand Down Expand Up @@ -132,10 +133,10 @@ pub async fn diagnose_migration_history(
// TODO(MultiSchema): this should probably fill the following namespaces from the CLI since there is
// no schema to grab the namespaces off, in the case of MultiSchema.
let from = connector
.database_schema_from_diff_target(DiffTarget::Migrations(&applied_migrations), None, None)
.database_schema_from_diff_target(DiffTarget::Migrations(&applied_migrations), None, namespaces.clone())
.await;
let to = connector
.database_schema_from_diff_target(DiffTarget::Database, None, None)
.database_schema_from_diff_target(DiffTarget::Database, None, namespaces)
.await;
let drift = match from.and_then(|from| to.map(|to| connector.diff(from, to))).map(|mig| {
if connector.migration_is_empty(&mig) {
Expand Down
42 changes: 25 additions & 17 deletions migration-engine/core/src/state.rs
Expand Up @@ -52,6 +52,16 @@ impl EngineState {
}
}

fn namespaces(&self) -> Option<Namespaces> {
self.initial_datamodel
.as_ref()
.and_then(|schema| schema.configuration.datasources.first())
.and_then(|ds| {
let mut names = ds.namespaces.iter().map(|(ns, _)| ns.to_owned()).collect();
Namespaces::from_vec(&mut names)
})
}

async fn with_connector_from_schema_path<O: Send + 'static>(
&self,
path: &str,
Expand Down Expand Up @@ -247,8 +257,13 @@ impl GenericApi for EngineState {
}

async fn dev_diagnostic(&self, input: DevDiagnosticInput) -> CoreResult<DevDiagnosticOutput> {
self.with_default_connector(Box::new(|connector| {
Box::pin(commands::dev_diagnostic(input, connector).instrument(tracing::info_span!("DevDiagnostic")))
let namespaces = self.namespaces();
self.with_default_connector(Box::new(move |connector| {
Box::pin(async move {
commands::dev_diagnostic(input, namespaces, connector)
.instrument(tracing::info_span!("DevDiagnostic"))
.await
})
}))
.await
}
Expand All @@ -266,11 +281,13 @@ impl GenericApi for EngineState {
&self,
input: commands::DiagnoseMigrationHistoryInput,
) -> CoreResult<commands::DiagnoseMigrationHistoryOutput> {
self.with_default_connector(Box::new(|connector| {
Box::pin(
commands::diagnose_migration_history(input, connector)
.instrument(tracing::info_span!("DiagnoseMigrationHistory")),
)
let namespaces = self.namespaces();
self.with_default_connector(Box::new(move |connector| {
Box::pin(async move {
commands::diagnose_migration_history(input, namespaces, connector)
.instrument(tracing::info_span!("DiagnoseMigrationHistory"))
.await
})
}))
.await
}
Expand Down Expand Up @@ -368,16 +385,7 @@ impl GenericApi for EngineState {

async fn reset(&self) -> CoreResult<()> {
tracing::debug!("Resetting the database.");

let namespaces: Option<Namespaces> = self
.initial_datamodel
.as_ref()
.and_then(|schema| schema.configuration.datasources.first())
.and_then(|ds| {
let mut names = ds.namespaces.iter().map(|(ns, _)| ns.to_owned()).collect();
Namespaces::from_vec(&mut names)
});

let namespaces = self.namespaces();
self.with_default_connector(Box::new(move |connector| {
Box::pin(MigrationConnector::reset(connector, false, namespaces).instrument(tracing::info_span!("Reset")))
}))
Expand Down
Expand Up @@ -22,6 +22,7 @@ impl<'a> DevDiagnostic<'a> {
DevDiagnosticInput {
migrations_directory_path: self.migrations_directory.path().to_str().unwrap().to_owned(),
},
None,
self.api,
);
let output = test_setup::runtime::run_with_thread_local_runtime(fut)?;
Expand Down
Expand Up @@ -34,6 +34,7 @@ impl<'a> DiagnoseMigrationHistory<'a> {
migrations_directory_path: self.migrations_directory.path().to_str().unwrap().to_owned(),
opt_in_to_shadow_database: self.opt_in_to_shadow_database,
},
None,
self.api,
)
.await?;
Expand Down
Expand Up @@ -768,3 +768,77 @@ fn dev_diagnostic_shadow_database_creation_error_is_special_cased_postgres(api:

//
// }

#[test]
fn dev_diagnostic_multi_schema_does_not_panic() {
let db = test_setup::only!(Postgres);
let (_, url) = tok(test_setup::postgres::create_postgres_database(
db.url(),
"dev_diagnostic_multi_schema",
))
.unwrap();

let schema = format! {r#"
datasource db {{
provider = "postgresql"
url = "{url}"
schemas = ["prisma-tests", "auth"]
}}
generator js {{
provider = "prisma-client-js"
previewFeatures = ["multiSchema"]
}}
model users {{
id String @id @db.Uuid
profiles profiles?
@@schema("auth")
}}
model profiles {{
id String @id @db.Uuid
users users @relation(fields: [id], references: [id], onDelete: NoAction, onUpdate: NoAction)
@@schema("prisma-tests")
}}
"#};

let setup = r#"
-- ./sql/ddl.sql
CREATE SCHEMA auth;
-- auth.users definition
CREATE TABLE auth.users (
id uuid NOT NULL,
CONSTRAINT users_pkey PRIMARY KEY (id)
);
-- "prisma-tests".profiles definition
CREATE TABLE "prisma-tests".profiles (
id uuid NOT NULL,
CONSTRAINT profiles_pkey PRIMARY KEY (id)
);
-- "prisma-tests".profiles foreign keys
ALTER TABLE "prisma-tests".profiles ADD CONSTRAINT profiles_id_fkey FOREIGN KEY (id) REFERENCES auth.users(id);
"#;

let tempdir = tempfile::tempdir().unwrap();
std::fs::write(tempdir.path().join("schema.prisma"), &schema).unwrap();

let api = migration_core::migration_api(Some(schema), None).unwrap();

tok(api.db_execute(DbExecuteParams {
datasource_type: DbExecuteDatasourceType::Url(UrlContainer { url }),
script: setup.to_owned(),
}))
.unwrap();

tok(api.dev_diagnostic(DevDiagnosticInput {
migrations_directory_path: tempdir.path().join("migrations").to_string_lossy().into_owned(),
}))
.unwrap();
}

0 comments on commit 07d67d0

Please sign in to comment.