diff --git a/src/database/mod.rs b/src/database/mod.rs index 67a8d7279..7161d150a 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -63,10 +63,15 @@ pub struct ConnectOptions { /// Schema search path (PostgreSQL only) pub(crate) schema_search_path: Option, pub(crate) test_before_acquire: bool, + /// Only establish connections to the DB as needed. If set to `true`, the db connection will + /// be created using SQLx's [connect_lazy](https://docs.rs/sqlx/latest/sqlx/struct.Pool.html#method.connect_lazy) + /// method. + pub(crate) connect_lazy: bool, } impl Database { - /// Method to create a [DatabaseConnection] on a database + /// Method to create a [DatabaseConnection] on a database. This method will return an error + /// if the database is not available. #[instrument(level = "trace", skip(opt))] pub async fn connect(opt: C) -> Result where @@ -157,6 +162,7 @@ impl ConnectOptions { sqlcipher_key: None, schema_search_path: None, test_before_acquire: true, + connect_lazy: false, } } @@ -297,4 +303,16 @@ impl ConnectOptions { self.test_before_acquire = value; self } + + /// If set to `true`, the db connection pool will be created using SQLx's + /// [connect_lazy](https://docs.rs/sqlx/latest/sqlx/struct.Pool.html#method.connect_lazy) method. + pub fn connect_lazy(&mut self, value: bool) -> &mut Self { + self.connect_lazy = value; + self + } + + /// Get whether DB connections will be established when the pool is created or only as needed. + pub fn get_connect_lazy(&self) -> bool { + self.connect_lazy + } } diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs index aa5ee6e00..df9862630 100644 --- a/src/driver/sqlx_mysql.rs +++ b/src/driver/sqlx_mysql.rs @@ -61,15 +61,21 @@ impl SqlxMySqlConnector { ); } } - match options.sqlx_pool_options().connect_with(opt).await { - Ok(pool) => Ok(DatabaseConnection::SqlxMySqlPoolConnection( - SqlxMySqlPoolConnection { - pool, - metric_callback: None, - }, - )), - Err(e) => Err(sqlx_error_to_conn_err(e)), - } + let pool = if options.connect_lazy { + options.sqlx_pool_options().connect_lazy_with(opt) + } else { + options + .sqlx_pool_options() + .connect_with(opt) + .await + .map_err(sqlx_error_to_conn_err)? + }; + Ok(DatabaseConnection::SqlxMySqlPoolConnection( + SqlxMySqlPoolConnection { + pool, + metric_callback: None, + }, + )) } } diff --git a/src/driver/sqlx_postgres.rs b/src/driver/sqlx_postgres.rs index b5deaaff6..6e424a343 100644 --- a/src/driver/sqlx_postgres.rs +++ b/src/driver/sqlx_postgres.rs @@ -65,6 +65,7 @@ impl SqlxPostgresConnector { .schema_search_path .as_ref() .map(|schema| format!("SET search_path = {schema}")); + let lazy = options.connect_lazy; let mut pool_options = options.sqlx_pool_options(); if let Some(sql) = set_search_path_sql { pool_options = pool_options.after_connect(move |conn, _| { @@ -76,15 +77,20 @@ impl SqlxPostgresConnector { }) }); } - match pool_options.connect_with(opt).await { - Ok(pool) => Ok(DatabaseConnection::SqlxPostgresPoolConnection( - SqlxPostgresPoolConnection { - pool, - metric_callback: None, - }, - )), - Err(e) => Err(sqlx_error_to_conn_err(e)), - } + let pool = if lazy { + pool_options.connect_lazy_with(opt) + } else { + pool_options + .connect_with(opt) + .await + .map_err(sqlx_error_to_conn_err)? + }; + Ok(DatabaseConnection::SqlxPostgresPoolConnection( + SqlxPostgresPoolConnection { + pool, + metric_callback: None, + }, + )) } } diff --git a/src/driver/sqlx_sqlite.rs b/src/driver/sqlx_sqlite.rs index ef62bb766..3d5465aa9 100644 --- a/src/driver/sqlx_sqlite.rs +++ b/src/driver/sqlx_sqlite.rs @@ -66,26 +66,33 @@ impl SqlxSqliteConnector { ); } } + if options.get_max_connections().is_none() { options.max_connections(1); } - match options.sqlx_pool_options().connect_with(opt).await { - Ok(pool) => { - let pool = SqlxSqlitePoolConnection { - pool, - metric_callback: None, - }; - - #[cfg(feature = "sqlite-use-returning-for-3_35")] - { - let version = get_version(&pool).await?; - ensure_returning_version(&version)?; - } - - Ok(DatabaseConnection::SqlxSqlitePoolConnection(pool)) - } - Err(e) => Err(sqlx_error_to_conn_err(e)), + + let pool = if options.connect_lazy { + options.sqlx_pool_options().connect_lazy_with(opt) + } else { + options + .sqlx_pool_options() + .connect_with(opt) + .await + .map_err(sqlx_error_to_conn_err)? + }; + + let pool = SqlxSqlitePoolConnection { + pool, + metric_callback: None, + }; + + #[cfg(feature = "sqlite-use-returning-for-3_35")] + { + let version = get_version(&pool).await?; + ensure_returning_version(&version)?; } + + Ok(DatabaseConnection::SqlxSqlitePoolConnection(pool)) } }