1#![deny(warnings)]
2pub use libsql;
44use async_trait::async_trait;
45use libsql::Connection;
46use std::fmt;
47use std::path::{Path, PathBuf};
48use std::time::Duration;
49
50pub mod errors;
51
52#[derive(Debug, Clone)]
53enum Source {
54 Local(PathBuf),
55 Remote(String, String),
56 LocalReplica(PathBuf),
57 RemoteReplica(PathBuf, String, String, Duration),
58}
59
60pub struct LibsqlConnectionManager { source: Source }
62
63impl fmt::Debug for LibsqlConnectionManager {
64 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65 let mut builder = f.debug_struct("LibsqlConnectionManager");
66 let _ = builder.field("source", &self.source);
67 builder.finish()
68 }
69}
70
71impl LibsqlConnectionManager {
72 pub fn local<P: AsRef<Path>>(path: P) -> Self {
75 Self {
76 source: Source::Local(
77 path.as_ref().to_path_buf()
78 ),
79 }
80 }
81
82 pub fn remote(url: &str, token: &str) -> Self {
85 Self {
86 source: Source::Remote(
87 url.to_string(),
88 token.to_string()
89 ),
90 }
91 }
92
93 pub fn local_replica<P: AsRef<Path>>(path: P) -> Self {
96 Self {
97 source: Source::LocalReplica(
98 path.as_ref().to_path_buf(),
99 ),
100 }
101 }
102
103 pub fn remote_replica<P: AsRef<Path>>(path: P, url: &str, token: &str, sync_interval: Duration) -> Self {
106 Self {
107 source: Source::RemoteReplica(
108 path.as_ref().to_path_buf(),
109 url.to_string(),
110 token.to_string(),
111 sync_interval
112 ),
113 }
114 }
115}
116
117#[async_trait]
118impl bb8::ManageConnection for LibsqlConnectionManager {
119 type Connection = Connection;
120 type Error = errors::ConnectionManagerError;
121
122 async fn connect(&self) -> Result<Connection, errors::ConnectionManagerError> {
123 Ok(match &self.source {
124 Source::Local(ref path) => {
125 libsql::Builder::new_local(path)
126 .build().await
127 .and_then(|builder| builder.connect())
128 },
129 Source::Remote(url, token) => {
130 libsql::Builder::new_remote(url.to_string(), token.to_string())
131 .build().await
132 .and_then(|builder| builder.connect())
133 },
134 Source::LocalReplica(path) => {
135 libsql::Builder::new_local_replica(path)
136 .build().await
137 .and_then(|builder| builder.connect())
138 },
139 Source::RemoteReplica(path, url, token, sync_interval) => {
140 libsql::Builder::new_remote_replica(path, url.to_string(), token.to_string())
141 .sync_interval(sync_interval.clone())
142 .build().await
143 .and_then(|builder| builder.connect())
144 },
145 }?)
146 }
147
148 async fn is_valid(&self, conn: &mut Connection) -> Result<(), errors::ConnectionManagerError> {
149 Ok(conn.execute_batch("SELECT 1;").await.map(|_| ())?)
150 }
151
152 fn has_broken(&self, _: &mut Connection) -> bool { false }
153}