mod index;
mod inner;
mod promise;
mod recv_queue;
mod space;
mod stream;
use std::net::ToSocketAddrs;
use std::rc::Rc;
use std::time::Duration;
use self::promise::Promise;
use super::protocol::codec;
use super::protocol::options::{ConnOptions, Options};
use crate::error::Error;
use crate::tuple::{Decode, ToTupleBuffer, Tuple};
use inner::ConnInner;
pub trait ConnTriggers {
fn on_connect(&self, conn: &Conn) -> Result<(), Error>;
fn on_disconnect(&self);
}
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(codec::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| codec::encode_call(buf, sync, function_name, args),
codec::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(codec::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| codec::encode_eval(buf, sync, expression, args),
codec::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(codec::Eval(expr, args))
}
pub fn execute(
&self,
sql: &str,
bind_params: &impl ToTupleBuffer,
options: &Options,
) -> Result<Vec<Tuple>, Error> {
self.inner.request(
|buf, sync| codec::encode_execute(buf, sync, sql, bind_params),
|buf, _| codec::decode_multiple_rows(buf, None),
options,
)
}
}
impl Drop for Conn {
fn drop(&mut self) {
if self.is_master {
self.close();
}
}
}