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

me: pass namespaces to diff in devDiagnostic->diagnoseMigrationHistory #3481

Merged
merged 1 commit into from
Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 7 additions & 1 deletion libs/test-setup/src/lib.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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();
}