use sqlx::PgPool;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PgVersion {
pub version_num: i32,
}
impl PgVersion {
pub fn major(&self) -> i32 {
self.version_num / 10000
}
pub fn supports_grant_with_options(&self) -> bool {
self.major() >= 16
}
}
impl std::fmt::Display for PgVersion {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let major = self.major();
let minor = self.version_num % 10000;
write!(f, "{major}.{minor}")
}
}
pub async fn detect_pg_version(pool: &PgPool) -> Result<PgVersion, sqlx::Error> {
let row: (i32,) = sqlx::query_as("SELECT current_setting('server_version_num')::int")
.fetch_one(pool)
.await?;
Ok(PgVersion { version_num: row.0 })
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pg_version_parsing() {
let v = PgVersion {
version_num: 160004,
};
assert_eq!(v.major(), 16);
assert!(v.supports_grant_with_options());
assert_eq!(v.to_string(), "16.4");
}
#[test]
fn pg15_does_not_support_grant_options() {
let v = PgVersion {
version_num: 150008,
};
assert_eq!(v.major(), 15);
assert!(!v.supports_grant_with_options());
}
#[test]
fn pg14_version() {
let v = PgVersion {
version_num: 140012,
};
assert_eq!(v.major(), 14);
assert!(!v.supports_grant_with_options());
}
}