Skip to main content

ruststream_sqlx/inbox/broker/
describe.rs

1//! What a broker reports of its server to the generated document: the host and port its URL
2//! names, never its credentials.
3
4use ruststream::{DescribeServer, ServerSpec};
5use ruststream_sqlx_dialect::Dialect;
6#[cfg(feature = "any")]
7use sqlx::Any;
8#[cfg(feature = "mysql")]
9use sqlx::MySql;
10#[cfg(feature = "postgres")]
11use sqlx::Postgres;
12#[cfg(feature = "sqlite")]
13use sqlx::Sqlite;
14
15use super::SqlxBroker;
16
17#[cfg(feature = "postgres")]
18impl<D: Dialect + 'static> DescribeServer for SqlxBroker<Postgres, D> {
19    fn describe_server(&self) -> ServerSpec {
20        ServerSpec::from_url(&self.pool.url(), "postgres")
21    }
22}
23
24#[cfg(feature = "mysql")]
25impl<D: Dialect + 'static> DescribeServer for SqlxBroker<MySql, D> {
26    fn describe_server(&self) -> ServerSpec {
27        ServerSpec::from_url(&self.pool.url(), "mysql")
28    }
29}
30
31/// SQLite runs inside the service, on a file or in memory: the description names the protocol and
32/// no host, so it holds neither the database's path nor any other part of its URL, and SQLite takes
33/// no credentials.
34#[cfg(feature = "sqlite")]
35impl<D: Dialect + 'static> DescribeServer for SqlxBroker<Sqlite, D> {
36    fn describe_server(&self) -> ServerSpec {
37        // Why not `from_url`: SQLite's URL holds a path, not a host, and sqlx's `to_url_lossy`
38        // panics on a database named `file:..`, the name `sqlite::memory:` takes.
39        // FIXME(sqlx-sqlite 0.9.0): `SqliteConnectOptions::to_url_lossy` panics with "BUG:
40        // generated un-parseable URL: InvalidPort" on every database named `file:..`. Once sqlx
41        // fixes it, the panic stops ruling out reading the URL here and this note goes; the
42        // description stays in-process, since SQLite has no host either way.
43        ServerSpec::in_process("sqlite")
44    }
45}
46
47/// An `AnyPool` is described by the scheme of its URL, as the broker of that database describes
48/// itself: the host and port of a server, or SQLite with no host.
49#[cfg(feature = "any")]
50impl<D: Dialect + 'static> DescribeServer for SqlxBroker<Any, D> {
51    fn describe_server(&self) -> ServerSpec {
52        // `Any` keeps the URL it was given, so reading it back is free of the SQLite panic above.
53        let url = self.pool.url();
54        let scheme = url.split_once(':').map_or(&*url, |(scheme, _)| scheme);
55        match scheme {
56            "sqlite" => ServerSpec::in_process("sqlite"),
57            "postgres" | "postgresql" => ServerSpec::from_url(&url, "postgres"),
58            "mysql" | "mariadb" => ServerSpec::from_url(&url, "mysql"),
59            scheme => ServerSpec::from_url(&url, scheme),
60        }
61    }
62}