1use crate::{Driver, Error, Executor, Result, truncate_long};
2use anyhow::Context;
3use std::{
4 borrow::Cow,
5 future::{self, Future},
6};
7use url::Url;
8
9pub trait Connection: Executor {
19 fn sanitize_url(_driver: &Self::Driver, mut url: Cow<'static, str>) -> Result<Url>
21 where
22 Self: Sized,
23 {
24 let mut in_memory = false;
25 if let Some((scheme, host)) = url.split_once("://")
26 && host.starts_with(":memory:")
27 {
28 url = format!("{scheme}://localhost{}", &host[8..]).into();
29 in_memory = true;
30 }
31 let context = || format!("While trying to connect to `{}`", truncate_long!(url));
32 let mut result = Url::parse(&url).with_context(context)?;
33 if in_memory {
34 result.query_pairs_mut().append_pair("mode", "memory");
35 }
36 let names = <Self::Driver as Driver>::NAME;
37 'prefix: {
38 for name in names {
39 let prefix = format!("{}://", name);
40 if url.starts_with(&prefix) {
41 break 'prefix prefix;
42 }
43 }
44 let error = Error::msg(format!(
45 "Connection URL must start with: {}",
46 names.join(", ")
47 ))
48 .context(context());
49 log::error!("{:#}", error);
50 return Err(error);
51 };
52 Ok(result)
53 }
54
55 fn connect(
60 driver: &Self::Driver,
61 url: Cow<'static, str>,
62 ) -> impl Future<Output = Result<<Self::Driver as Driver>::Connection>>
63 where
64 Self: Sized;
65
66 fn begin(&mut self) -> impl Future<Output = Result<<Self::Driver as Driver>::Transaction<'_>>>;
70
71 fn disconnect(self) -> impl Future<Output = Result<()>>
73 where
74 Self: Sized,
75 {
76 future::ready(Ok(()))
77 }
78}