#![deny(warnings)]
pub use libsql;
use async_trait::async_trait;
use libsql::Connection;
use std::fmt;
use std::path::{Path, PathBuf};
use std::time::Duration;
pub mod errors;
#[derive(Debug, Clone)]
enum Source {
Local(PathBuf),
Remote(String, String),
LocalReplica(PathBuf),
RemoteReplica(PathBuf, String, String, Duration),
}
pub struct LibsqlConnectionManager { source: Source }
impl fmt::Debug for LibsqlConnectionManager {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut builder = f.debug_struct("LibsqlConnectionManager");
let _ = builder.field("source", &self.source);
builder.finish()
}
}
impl LibsqlConnectionManager {
pub fn local<P: AsRef<Path>>(path: P) -> Self {
Self {
source: Source::Local(
path.as_ref().to_path_buf()
),
}
}
pub fn remote(url: &str, token: &str) -> Self {
Self {
source: Source::Remote(
url.to_string(),
token.to_string()
),
}
}
pub fn local_replica<P: AsRef<Path>>(path: P) -> Self {
Self {
source: Source::LocalReplica(
path.as_ref().to_path_buf(),
),
}
}
pub fn remote_replica<P: AsRef<Path>>(path: P, url: &str, token: &str, sync_interval: Duration) -> Self {
Self {
source: Source::RemoteReplica(
path.as_ref().to_path_buf(),
url.to_string(),
token.to_string(),
sync_interval
),
}
}
}
#[async_trait]
impl bb8::ManageConnection for LibsqlConnectionManager {
type Connection = Connection;
type Error = errors::ConnectionManagerError;
async fn connect(&self) -> Result<Connection, errors::ConnectionManagerError> {
Ok(match &self.source {
Source::Local(ref path) => {
libsql::Builder::new_local(path)
.build().await
.and_then(|builder| builder.connect())
},
Source::Remote(url, token) => {
libsql::Builder::new_remote(url.to_string(), token.to_string())
.build().await
.and_then(|builder| builder.connect())
},
Source::LocalReplica(path) => {
libsql::Builder::new_local_replica(path)
.build().await
.and_then(|builder| builder.connect())
},
Source::RemoteReplica(path, url, token, sync_interval) => {
libsql::Builder::new_remote_replica(path, url.to_string(), token.to_string())
.sync_interval(sync_interval.clone())
.build().await
.and_then(|builder| builder.connect())
},
}?)
}
async fn is_valid(&self, conn: &mut Connection) -> Result<(), errors::ConnectionManagerError> {
Ok(conn.execute_batch("SELECT 1;").await.map(|_| ())?)
}
fn has_broken(&self, _: &mut Connection) -> bool { false }
}