#![cfg(feature = "net_box")]
use core::time::Duration;
use std::net::ToSocketAddrs;
use std::rc::Rc;
pub use index::{RemoteIndex, RemoteIndexIterator};
use inner::ConnInner;
pub use options::{ConnOptions, ConnTriggers, Options};
use promise::Promise;
pub(crate) use protocol::ResponseError;
pub use space::RemoteSpace;
use crate::error::Error;
use crate::tuple::{Decode, ToTupleBuffer, Tuple};
mod index;
mod inner;
mod options;
pub mod promise;
mod protocol;
mod recv_queue;
mod schema;
mod send_queue;
mod space;
mod stream;
pub struct Conn {
inner: Rc<ConnInner>,
is_master: bool,
}
impl Conn {
pub fn new(
addr: impl ToSocketAddrs,
options: ConnOptions,
triggers: Option<Rc<dyn ConnTriggers>>,
) -> Result<Self, Error> {
Ok(Conn {
inner: ConnInner::new(addr.to_socket_addrs()?.collect(), options, triggers),
is_master: true,
})
}
fn downgrade(inner: Rc<ConnInner>) -> Self {
Conn {
inner,
is_master: false,
}
}
pub fn wait_connected(&self, timeout: Option<Duration>) -> Result<bool, Error> {
self.inner.wait_connected(timeout)
}
pub fn is_connected(&self) -> bool {
self.inner.is_connected()
}
pub fn close(&self) {
self.inner.close()
}
pub fn ping(&self, options: &Options) -> Result<(), Error> {
self.inner
.request(protocol::encode_ping, |_, _| Ok(()), options)?;
Ok(())
}
pub fn call<T>(
&self,
function_name: &str,
args: &T,
options: &Options,
) -> Result<Option<Tuple>, Error>
where
T: ToTupleBuffer,
T: ?Sized,
{
self.inner.request(
|buf, sync| protocol::encode_call(buf, sync, function_name, args),
protocol::decode_call,
options,
)
}
pub fn call_async<A, R>(&self, func: &str, args: A) -> crate::Result<Promise<R>>
where
A: ToTupleBuffer,
R: for<'de> Decode<'de> + 'static,
{
self.inner.request_async(protocol::Call(func, args))
}
pub fn eval<T>(
&self,
expression: &str,
args: &T,
options: &Options,
) -> Result<Option<Tuple>, Error>
where
T: ToTupleBuffer,
T: ?Sized,
{
self.inner.request(
|buf, sync| protocol::encode_eval(buf, sync, expression, args),
protocol::decode_call,
options,
)
}
pub fn eval_async<A, R>(&self, expr: &str, args: A) -> crate::Result<Promise<R>>
where
A: ToTupleBuffer,
R: for<'de> Decode<'de> + 'static,
{
self.inner.request_async(protocol::Eval(expr, args))
}
pub fn space(&self, name: &str) -> Result<Option<RemoteSpace>, Error> {
Ok(self
.inner
.lookup_space(name)?
.map(|space_id| RemoteSpace::new(self.inner.clone(), space_id)))
}
pub fn execute<P>(
&self,
sql: &str,
bind_params: &P,
options: &Options,
) -> Result<Vec<Tuple>, Error>
where
P: ToTupleBuffer + ?Sized,
{
self.inner.request(
|buf, sync| protocol::encode_execute(buf, sync, sql, bind_params),
|buf, _| protocol::decode_multiple_rows(buf, None),
options,
)
}
}
impl Drop for Conn {
fn drop(&mut self) {
if self.is_master {
self.close();
}
}
}