use crate::binding::*;
use crate::chkerr;
use crate::Context;
use crate::Result;
use std::fmt;
use std::mem::MaybeUninit;
use std::num::ParseIntError;
use std::result;
use std::str::FromStr;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Version {
major: i32,
minor: i32,
update: i32,
patch: i32,
port_update: i32,
}
impl Version {
pub const fn new(major: i32, minor: i32, update: i32, patch: i32, port_update: i32) -> Version {
Version {
major,
minor,
update,
patch,
port_update,
}
}
pub fn client() -> Result<Version> {
let ctx = Context::new0()?;
let mut ver = MaybeUninit::uninit();
chkerr!(
&ctx,
dpiContext_getClientVersion(ctx.context, ver.as_mut_ptr())
);
Ok(Version::new_from_dpi_ver(unsafe { ver.assume_init() }))
}
pub(crate) fn new_from_dpi_ver(ver: dpiVersionInfo) -> Version {
Version::new(
ver.versionNum,
ver.releaseNum,
ver.updateNum,
ver.portReleaseNum,
ver.portUpdateNum,
)
}
pub fn major(&self) -> i32 {
self.major
}
pub fn minor(&self) -> i32 {
self.minor
}
pub fn update(&self) -> i32 {
self.update
}
pub fn patch(&self) -> i32 {
self.patch
}
pub fn port_update(&self) -> i32 {
self.port_update
}
}
impl fmt::Display for Version {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}.{}.{}.{}.{}",
self.major, self.minor, self.update, self.patch, self.port_update
)
}
}
impl FromStr for Version {
type Err = ParseIntError;
fn from_str(s: &str) -> result::Result<Self, Self::Err> {
let mut iter = s.split('.').fuse();
let major = iter.next().map_or(Ok(0), |s| s.parse::<i32>())?;
let minor = iter.next().map_or(Ok(0), |s| s.parse::<i32>())?;
let update = iter.next().map_or(Ok(0), |s| s.parse::<i32>())?;
let patch = iter.next().map_or(Ok(0), |s| s.parse::<i32>())?;
let port_update = iter.next().map_or(Ok(0), |s| s.parse::<i32>())?;
Ok(Version::new(major, minor, update, patch, port_update))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_util;
#[test]
fn to_string() {
assert_eq!(Version::new(12, 1, 2, 3, 4).to_string(), "12.1.2.3.4");
}
#[test]
fn from_str() {
assert_eq!(
"12".parse::<Version>().unwrap(),
Version::new(12, 0, 0, 0, 0)
);
assert_eq!(
"12.1".parse::<Version>().unwrap(),
Version::new(12, 1, 0, 0, 0)
);
assert_eq!(
"12.1.2".parse::<Version>().unwrap(),
Version::new(12, 1, 2, 0, 0)
);
assert_eq!(
"12.1.2.3".parse::<Version>().unwrap(),
Version::new(12, 1, 2, 3, 0)
);
assert_eq!(
"12.1.2.3.4".parse::<Version>().unwrap(),
Version::new(12, 1, 2, 3, 4)
);
}
#[test]
fn client_version() {
let ver = Version::client().unwrap();
let conn = test_util::connect().unwrap();
let ver_from_query = conn.query_row_as::<String>("SELECT client_version FROM v$session_connect_info WHERE sid = SYS_CONTEXT('USERENV', 'SID')", &[]).unwrap();
assert_eq!(ver.to_string(), ver_from_query);
}
}