Repository: diesel-rs/diesel
File: diesel_cli/src/database.rs (Rust)

Code before:
    }
    .map_err(Into::into)
}

pub fn database_url(matches: &ArgMatches) -> Result<String, crate::errors::Error> {
    matches
        .get_one::<String>("DATABASE_URL")
        .cloned()
        .or_else(|| env::var("DATABASE_URL").ok())
        .ok_or(crate::errors::Error::DatabaseUrlMissing)
}

#[cfg(any(feature = "postgres", feature = "mysql"))]
fn change_database_of_url(
    database_url: &str,
    mut default_database: &str,
) -> Result<(String, String), crate::errors::Error> {
    let base = url::Url::parse(database_url)?;
    let database = base
        .path_segments()
        .expect("The database url has at least one path segment")
        .last()
        .expect("The database url has at least one path segment")
        .to_owned();

    if database.eq("postgres") {
        default_database = "template1";
    }

    let mut new_url = base
        .join(default_database)
        .expect("The provided database is always valid");
    new_url.set_query(base.query());
    Ok((database, new_url.into()))
}

#[cfg(feature = "sqlite")]
/// sqlite accepts either file: URLs, or bare paths (the latter of which may be relative).
/// Check for which case we're in and return the path if we can retrieve it.
fn path_from_sqlite_url(database_url: &str) -> Result<std::path::PathBuf, crate::errors::Error> {
    if database_url.starts_with("file:/") {
        // looks like a file URL
        match ::url::Url::parse(database_url) {
            Ok(url) if url.scheme() == "file" => {
                Ok(url
                    .to_file_path()
                    .map_err(|_err| crate::errors::Error::ConnectionError {
                        error: result::ConnectionError::InvalidConnectionUrl(String::from(
                            database_url,
                        )),
                        url: database_url.into(),

Review comment (bug):
I've read the issue and I understand it may be sensible to do this specifically when we are trying to drop a database.
It also sounds likely that at the moment this is the only place at which this function is called.
However the naming of this function  `fn change_database_of_url(` would not let any future code author expect this behavior, so it's likely to introduce a bug.
=> It looks like it would be best to put this logic where the function is called, that is, in a place where the current code path is about removing the database.

Code after:
                    (SELECT 1 \
                     FROM information_schema.tables \
                     WHERE table_name = '__diesel_schema_migrations'
                     AND table_schema = DATABASE())",
        ))
        .get_result(&mut conn),
    }
    .map_err(Into::into)
}

pub fn database_url(matches: &ArgMatches) -> Result<String, crate::errors::Error> {
    matches
        .get_one::<String>("DATABASE_URL")
        .cloned()
        .or_else(|| env::var("DATABASE_URL").ok())
        .ok_or(crate::errors::Error::DatabaseUrlMissing)
}

#[cfg(any(feature = "postgres", feature = "mysql"))]
fn change_database_of_url(
    database_url: &str,
    default_database: &str,
) -> Result<(String, String), crate::errors::Error> {
    let (database, base) = get_database_and_url(database_url)?;
    let mut new_url = base
        .join(default_database)
        .expect("The provided database is always valid");
    new_url.set_query(base.query());
    Ok((database, new_url.into()))
}

#[cfg(any(feature = "postgres", feature = "mysql"))]
fn get_database_and_url(database_url: &str) -> Result<(String, url::Url), crate::errors::Error> {
    let base = url::Url::parse(database_url)?;
    let database = base
        .path_segments()
        .expect("The database url has at least one path segment")
        .last()
        .expect("The database url has at least one path segment")
        .to_owned();
    Ok((database, base))
}

#[cfg(feature = "sqlite")]
/// sqlite accepts either file: URLs, or bare paths (the latter of which may be relative).
/// Check for which case we're in and return the path if we can retrieve it.
fn path_from_sqlite_url(database_url: &str) -> Result<std::path::PathBuf, crate::errors::Error> {
    if database_url.starts_with("file:/") {
        // looks like a file URL
        match ::url::Url::parse(database_url) {
            Ok(url) if url.scheme() == "file" => {