Skip to content

Commit

Permalink
fix(provisioner): gracefully handle deletion of non-existent db
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaro00 committed Oct 18, 2023
1 parent dde96a8 commit f2fab05
Showing 1 changed file with 38 additions and 17 deletions.
55 changes: 38 additions & 17 deletions provisioner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use shuttle_proto::provisioner::{Ping, Pong};
use sqlx::{postgres::PgPoolOptions, ConnectOptions, Executor, PgPool};
use tokio::time::sleep;
use tonic::{Request, Response, Status};
use tracing::{debug, info};
use tracing::{debug, info, warn};

mod args;
mod error;
Expand Down Expand Up @@ -353,26 +353,47 @@ impl MyProvisioner {
let database_name = format!("db-{project_name}");
let role_name = format!("user-{project_name}");

// Identifiers cannot be used as query parameters.
let drop_db_query = format!("DROP DATABASE \"{database_name}\" WITH (FORCE);");

// Drop the database with force, which will try to terminate existing connections to the
// database. This can fail if prepared transactions, active logical replication slots or
// subscriptions are present in the database.
sqlx::query(&drop_db_query)
.execute(&self.pool)
if sqlx::query("SELECT 1 FROM pg_database WHERE datname = $1")
.bind(&database_name)
.fetch_optional(&self.pool)
.await
.map_err(|e| Error::DeleteDB(e.to_string()))?;
.map_err(|e| Error::DeleteDB(e.to_string()))?
.is_some()
{
// Identifiers cannot be used as query parameters.
let drop_db_query = format!("DROP DATABASE \"{database_name}\" WITH (FORCE)");

// Drop the database with force, which will try to terminate existing connections to the
// database. This can fail if prepared transactions, active logical replication slots or
// subscriptions are present in the database.
sqlx::query(&drop_db_query)
.execute(&self.pool)
.await
.map_err(|e| Error::DeleteDB(e.to_string()))?;

info!("dropped shared postgres database: {database_name}");
// Drop the role.
let drop_role_query = format!("DROP ROLE IF EXISTS \"{role_name}\"");
sqlx::query(&drop_role_query)
.execute(&self.pool)
info!("dropped shared postgres database: {database_name}");
} else {
warn!("did not drop shared postgres database: {database_name}. Does not exist.");
}

if sqlx::query("SELECT 1 FROM pg_roles WHERE rolname = $1")
.bind(&role_name)
.fetch_optional(&self.pool)
.await
.map_err(|e| Error::DeleteRole(e.to_string()))?;
.map_err(|e| Error::DeleteRole(e.to_string()))?
.is_some()
{
// Drop the role.
let drop_role_query = format!("DROP ROLE IF EXISTS \"{role_name}\"");
sqlx::query(&drop_role_query)
.execute(&self.pool)
.await
.map_err(|e| Error::DeleteRole(e.to_string()))?;

info!("dropped shared postgres role: {role_name}");
info!("dropped shared postgres role: {role_name}");
} else {
warn!("did not drop shared postgres role: {role_name}. Does not exist.");
}

Ok(())
}
Expand Down

0 comments on commit f2fab05

Please sign in to comment.