Skip to content

Commit 7eb01e5

Browse files
committed
Use DATABASE_URL for example database tests
1 parent 8a5b47c commit 7eb01e5

1 file changed

Lines changed: 64 additions & 10 deletions

File tree

tests/examples/mod.rs

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,37 @@ async fn smoke_example(example: &ExampleApp, database_url: &str) {
177177
}
178178

179179
async fn prepare_postgres_base_url() -> Option<String> {
180+
if let Some(database_url) = database_url_from_env(&["postgres", "postgresql"]) {
181+
let admin_url = replace_database_name(&database_url, "postgres");
182+
let mut conn = sqlx::PgConnection::connect(&admin_url)
183+
.await
184+
.unwrap_or_else(|err| panic!("DATABASE_URL points to PostgreSQL but connecting to {admin_url} failed: {err:#}"));
185+
conn.execute("SELECT 1").await.unwrap_or_else(|err| {
186+
panic!("DATABASE_URL points to PostgreSQL but validation failed: {err:#}")
187+
});
188+
return Some(replace_database_name(&database_url, "sqlpage_examples"));
189+
}
190+
180191
let admin_url = "postgres://root:Password123!@localhost/postgres";
181192
let mut conn = sqlx::PgConnection::connect(admin_url).await.ok()?;
182193
conn.execute("SELECT 1").await.ok()?;
183194
Some("postgres://root:Password123!@localhost/sqlpage_examples".to_string())
184195
}
185196

186197
async fn prepare_mysql_base_url() -> Option<String> {
198+
if let Some(database_url) = database_url_from_env(&["mysql"]) {
199+
let admin_url = replace_database_name(&database_url, "mysql");
200+
let mut conn = sqlx::MySqlConnection::connect(&admin_url)
201+
.await
202+
.unwrap_or_else(|err| {
203+
panic!("DATABASE_URL points to MySQL but connecting to {admin_url} failed: {err:#}")
204+
});
205+
conn.execute("SELECT 1").await.unwrap_or_else(|err| {
206+
panic!("DATABASE_URL points to MySQL but validation failed: {err:#}")
207+
});
208+
return Some(replace_database_name(&database_url, "sqlpage_examples"));
209+
}
210+
187211
let mut conn = sqlx::MySqlConnection::connect("mysql://root:Password123!@localhost/mysql")
188212
.await
189213
.ok()?;
@@ -195,11 +219,9 @@ async fn prepare_database(database_url: &str, backend: Backend) {
195219
match backend {
196220
Backend::Sqlite => {}
197221
Backend::Postgres => {
198-
let db_name = database_url.rsplit('/').next().unwrap();
199-
let mut conn =
200-
sqlx::PgConnection::connect("postgres://root:Password123!@localhost/postgres")
201-
.await
202-
.unwrap();
222+
let db_name = database_name(database_url);
223+
let admin_url = replace_database_name(database_url, "postgres");
224+
let mut conn = sqlx::PgConnection::connect(&admin_url).await.unwrap();
203225
let _ = conn
204226
.execute(format!("DROP DATABASE IF EXISTS {db_name} WITH (FORCE)").as_str())
205227
.await;
@@ -209,11 +231,9 @@ async fn prepare_database(database_url: &str, backend: Backend) {
209231
tokio::time::sleep(Duration::from_millis(100)).await;
210232
}
211233
Backend::MySql => {
212-
let db_name = database_url.rsplit('/').next().unwrap();
213-
let mut conn =
214-
sqlx::MySqlConnection::connect("mysql://root:Password123!@localhost/mysql")
215-
.await
216-
.unwrap();
234+
let db_name = database_name(database_url);
235+
let admin_url = replace_database_name(database_url, "mysql");
236+
let mut conn = sqlx::MySqlConnection::connect(&admin_url).await.unwrap();
217237
conn.execute(format!("DROP DATABASE IF EXISTS {db_name}").as_str())
218238
.await
219239
.unwrap();
@@ -225,6 +245,40 @@ async fn prepare_database(database_url: &str, backend: Backend) {
225245
}
226246
}
227247

248+
fn database_url_from_env(schemes: &[&str]) -> Option<String> {
249+
let database_url = std::env::var("DATABASE_URL").ok()?;
250+
let scheme = database_url.split_once(':')?.0;
251+
schemes.contains(&scheme).then_some(database_url)
252+
}
253+
254+
fn database_name(database_url: &str) -> &str {
255+
let url_without_query = database_url
256+
.split_once('?')
257+
.map_or(database_url, |(url, _query)| url);
258+
let database_start = url_without_query
259+
.rfind('/')
260+
.unwrap_or_else(|| panic!("database URL has no path: {database_url}"));
261+
&url_without_query[database_start + 1..]
262+
}
263+
264+
fn replace_database_name(database_url: &str, database_name: &str) -> String {
265+
let (url_without_query, query) = database_url
266+
.split_once('?')
267+
.map_or((database_url, ""), |(url, query)| (url, query));
268+
let database_start = url_without_query
269+
.rfind('/')
270+
.unwrap_or_else(|| panic!("database URL has no path: {database_url}"));
271+
let query = if query.is_empty() {
272+
String::new()
273+
} else {
274+
format!("?{query}")
275+
};
276+
format!(
277+
"{}{database_name}{query}",
278+
&url_without_query[..=database_start]
279+
)
280+
}
281+
228282
fn slug(name: &str) -> String {
229283
name.chars()
230284
.filter(|c| c.is_ascii_alphanumeric())

0 commit comments

Comments
 (0)