use std::convert::TryFrom;
use std::future::Future;
use std::ptr::NonNull;
use crate::future::*;
use crate::{error, Database, FdbError, FdbResult};
use foundationdb_sys as fdb_sys;
#[derive(Clone)]
pub struct Cluster {
inner: NonNull<fdb_sys::FDBCluster>,
}
unsafe impl Send for Cluster {}
unsafe impl Sync for Cluster {}
impl Drop for Cluster {
fn drop(&mut self) {
unsafe {
fdb_sys::fdb_cluster_destroy(self.inner.as_ptr());
}
}
}
impl Cluster {
pub fn new(
path: Option<&str>,
) -> impl Future<Output = FdbResult<Cluster>> + Send + Sync + Unpin {
let path_str = path.map(|path| std::ffi::CString::new(path).unwrap());
let path_ptr = path_str
.as_ref()
.map(|path| path.as_ptr())
.unwrap_or(std::ptr::null());
let f = FdbFuture::new(unsafe { fdb_sys::fdb_create_cluster(path_ptr) });
drop(path_str);
f
}
pub fn from_path(path: &str) -> impl Future<Output = FdbResult<Cluster>> + Send + Sync + Unpin {
Self::new(Some(path))
}
pub fn default() -> impl Future<Output = FdbResult<Cluster>> {
Self::new(None)
}
pub fn create_database(
&self,
) -> impl Future<Output = FdbResult<Database>> + Send + Sync + Unpin {
FdbFuture::new(unsafe {
fdb_sys::fdb_cluster_create_database(self.inner.as_ptr(), b"DB" as *const _, 2)
})
}
}
impl TryFrom<FdbFutureHandle> for Cluster {
type Error = FdbError;
fn try_from(f: FdbFutureHandle) -> FdbResult<Self> {
let mut v: *mut fdb_sys::FDBCluster = std::ptr::null_mut();
error::eval(unsafe { fdb_sys::fdb_future_get_cluster(f.as_ptr(), &mut v) })?;
Ok(Cluster {
inner: NonNull::new(v)
.expect("fdb_future_get_cluster to not return null if there is no error"),
})
}
}
impl TryFrom<FdbFutureHandle> for Database {
type Error = FdbError;
fn try_from(f: FdbFutureHandle) -> FdbResult<Self> {
let mut v: *mut fdb_sys::FDBDatabase = std::ptr::null_mut();
error::eval(unsafe { fdb_sys::fdb_future_get_database(f.as_ptr(), &mut v) })?;
Ok(Database {
inner: NonNull::new(v)
.expect("fdb_future_get_database to not return null if there is no error"),
})
}
}