Repository: launchbadge/sqlx
File: sqlx-core/src/pool/mod.rs (Rust)

Code before:
    ///
    /// # Ok(())
    /// # }
    /// ```
    pub fn close_event(&self) -> CloseEvent {
        self.0.close_event()
    }

    /// Returns the number of connections currently active. This includes idle connections.
    pub fn size(&self) -> u32 {
        self.0.size()
    }

    /// Returns the number of connections active and idle (not in use).
    ///
    /// As of 0.6.0, this has been fixed to use a separate atomic counter and so should be fine to
    /// call even at high load.
    ///
    /// This previously called [`crossbeam::queue::ArrayQueue::len()`] which waits for the head and
    /// tail pointers to be in a consistent state, which may never happen at high levels of churn.
    pub fn num_idle(&self) -> usize {
        self.0.num_idle()
    }

    /// Get the connection options for this pool
    pub fn connect_options(&self) -> RwLockReadGuard<'_, <DB::Connection as Connection>::Options> {
        self.0
            .connect_options
            .read()
            .expect("external config updater panicked")
    }

    /// Get the connection options for this pool
    pub fn connect_options_mut(
        &self,
    ) -> RwLockWriteGuard<'_, <DB::Connection as Connection>::Options> {
        self.0
            .connect_options
            .write()
            .expect("external config udpater panicked or already locked")
    }

    /// Callback-based updater for this pool's connection options
    pub fn update_connect_options<
        Fn: FnOnce(&mut <DB::Connection as Connection>::Options) -> (),
    >(
        &self,
        callback: Fn,
    ) {
        let mut guard = self
            .0

Review comment (suggestion):
This is technically a breaking change in the interface, but `RwLockReadGuard` implements `Deref` so in practice it shouldn't break much.

Code after:
        // technically write() could also panic if the current thread already holds the lock,
        // but because this method can't be re-entered by the same thread that shouldn't be a problem
        let mut guard = self
            .0
            .connect_options
            .write()
            .expect("write-lock holder panicked");
        *guard = Arc::new(connect_options);
    }

    /// Get the options for this pool
    pub fn options(&self) -> &PoolOptions<DB> {
        &self.0.options
    }
}

#[cfg(all(
    any(
        feature = "postgres",
        feature = "mysql",
        feature = "mssql",
        feature = "sqlite"
    ),
    feature = "any"
))]
impl Pool<Any> {
    /// Returns the database driver currently in-use by this `Pool`.
    ///
    /// Determined by the connection URL.
    pub fn any_kind(&self) -> AnyKind {
        self.0
            .connect_options
            .read()
            .expect("write-lock holder panicked")
            .kind()
    }
}

/// Returns a new [Pool] tied to the same shared connection pool.
impl<DB: Database> Clone for Pool<DB> {
    fn clone(&self) -> Self {
        Self(Arc::clone(&self.0))
    }
}

impl<DB: Database> fmt::Debug for Pool<DB> {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt.debug_struct("Pool")
            .field("size", &self.0.size())
            .field("num_idle", &self.0.num_idle())
            .field("is_closed", &self.0.is_closed())