1use async_trait::async_trait;
7use ecat_data::{Dialect, RdbmsClient, RdbmsError, SqlExecutor, Transaction, TransactionInner};
8use std::time::Duration;
9
10use crate::pool::Pool;
11use crate::transaction::{MyTx, PgTx, SqTx};
12use crate::{SqlxClient, db_err, mysql_replica_status_sql, parse_mysql_replica_lag};
13
14#[async_trait]
15impl RdbmsClient for SqlxClient {
16 async fn transaction(&self) -> Result<Transaction, RdbmsError> {
17 let dialect = self.pool.dialect();
18 let query_timeout = self.query_timeout;
21 let inner: Box<dyn TransactionInner> = match &self.pool {
22 Pool::Pg(p) => Box::new(PgTx {
23 inner: Some(p.begin().await.map_err(db_err)?),
24 dialect,
25 query_timeout,
26 }),
27 Pool::My(p) => Box::new(MyTx {
28 inner: Some(p.begin().await.map_err(db_err)?),
29 dialect,
30 query_timeout,
31 }),
32 Pool::Sq(p) => Box::new(SqTx {
33 inner: Some(p.begin().await.map_err(db_err)?),
34 dialect,
35 query_timeout,
36 }),
37 };
38 Ok(Transaction::with_inner(inner))
39 }
40
41 async fn replica_lag(&self) -> Option<Duration> {
43 if self.pool.dialect() != Dialect::MySql {
44 return None;
45 }
46 let version = self.mysql_version().await?;
47 let rows = self.query(mysql_replica_status_sql(&version)).await.ok()?;
48 parse_mysql_replica_lag(&rows)
49 }
50
51 fn pool_size(&self) -> Option<u32> {
54 Some(self.pool.max_connections())
55 }
56}