Skip to content

Commit 6148a21

Browse files
committed
refactor(odbc): implement with_conn helper for OdbcConnection methods
This commit introduces the `with_conn` method to streamline connection handling in various OdbcConnection methods, including `dbms_name`, `ping_blocking`, `begin_blocking`, `commit_blocking`, `rollback_blocking`, `execute_stream`, and `prepare_metadata`. This refactor enhances code readability and reduces duplication by encapsulating the connection locking logic.
1 parent 6e90b48 commit 6148a21

File tree

1 file changed

+37
-51
lines changed
  • sqlx-core/src/odbc/connection

1 file changed

+37
-51
lines changed

sqlx-core/src/odbc/connection/mod.rs

Lines changed: 37 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,22 @@ pub struct OdbcConnection {
5757
}
5858

5959
impl OdbcConnection {
60+
pub(crate) async fn with_conn<R, F, S>(&mut self, operation: S, f: F) -> Result<R, Error>
61+
where
62+
R: Send + 'static,
63+
F: FnOnce(&mut odbc_api::Connection<'static>) -> Result<R, Error> + Send + 'static,
64+
S: std::fmt::Display + Send + 'static,
65+
{
66+
let conn = Arc::clone(&self.conn);
67+
run_blocking(move || {
68+
let mut conn_guard = conn.lock().map_err(|_| {
69+
Error::Protocol(format!("ODBC {}: failed to lock connection", operation))
70+
})?;
71+
f(&mut conn_guard)
72+
})
73+
.await
74+
}
75+
6076
pub(crate) async fn establish(options: &OdbcConnectOptions) -> Result<Self, Error> {
6177
let shared_conn = run_blocking({
6278
let options = options.clone();
@@ -77,63 +93,42 @@ impl OdbcConnection {
7793
/// Returns the name of the actual Database Management System (DBMS) this
7894
/// connection is talking to as reported by the ODBC driver.
7995
pub async fn dbms_name(&mut self) -> Result<String, Error> {
80-
let conn = Arc::clone(&self.conn);
81-
run_blocking(move || {
82-
let conn_guard = conn
83-
.lock()
84-
.map_err(|_| Error::Protocol("Failed to lock connection".into()))?;
85-
conn_guard
86-
.database_management_system_name()
87-
.map_err(Error::from)
96+
self.with_conn("dbms_name", move |conn| {
97+
Ok(conn.database_management_system_name()?)
8898
})
8999
.await
90100
}
91101

92102
pub(crate) async fn ping_blocking(&mut self) -> Result<(), Error> {
93-
let conn = Arc::clone(&self.conn);
94-
run_blocking(move || {
95-
let conn_guard = conn
96-
.lock()
97-
.map_err(|_| Error::Protocol("Failed to lock connection".into()))?;
98-
conn_guard
99-
.execute("SELECT 1", (), None)
100-
.map_err(Error::from)
101-
.map(|_| ())
103+
self.with_conn("ping", move |conn| {
104+
conn.execute("SELECT 1", (), None)?;
105+
Ok(())
102106
})
103107
.await
104108
}
105109

106110
pub(crate) async fn begin_blocking(&mut self) -> Result<(), Error> {
107-
let conn = Arc::clone(&self.conn);
108-
run_blocking(move || {
109-
let conn_guard = conn
110-
.lock()
111-
.map_err(|_| Error::Protocol("Failed to lock connection".into()))?;
112-
conn_guard.set_autocommit(false).map_err(Error::from)
111+
self.with_conn("begin", move |conn| {
112+
conn.set_autocommit(false)?;
113+
Ok(())
113114
})
114115
.await
115116
}
116117

117118
pub(crate) async fn commit_blocking(&mut self) -> Result<(), Error> {
118-
let conn = Arc::clone(&self.conn);
119-
run_blocking(move || {
120-
let conn_guard = conn
121-
.lock()
122-
.map_err(|_| Error::Protocol("Failed to lock connection".into()))?;
123-
conn_guard.commit()?;
124-
conn_guard.set_autocommit(true).map_err(Error::from)
119+
self.with_conn("commit", move |conn| {
120+
conn.commit()?;
121+
conn.set_autocommit(true)?;
122+
Ok(())
125123
})
126124
.await
127125
}
128126

129127
pub(crate) async fn rollback_blocking(&mut self) -> Result<(), Error> {
130-
let conn = Arc::clone(&self.conn);
131-
run_blocking(move || {
132-
let conn_guard = conn
133-
.lock()
134-
.map_err(|_| Error::Protocol("Failed to lock connection".into()))?;
135-
conn_guard.rollback()?;
136-
conn_guard.set_autocommit(true).map_err(Error::from)
128+
self.with_conn("rollback", move |conn| {
129+
conn.rollback()?;
130+
conn.set_autocommit(true)?;
131+
Ok(())
137132
})
138133
.await
139134
}
@@ -146,13 +141,9 @@ impl OdbcConnection {
146141
let (tx, rx) = flume::bounded(64);
147142
let sql = sql.to_string();
148143
let args_move = args;
149-
let conn = Arc::clone(&self.conn);
150144

151-
run_blocking(move || {
152-
let mut conn_guard = conn
153-
.lock()
154-
.map_err(|_| Error::Protocol("Failed to lock connection".into()))?;
155-
if let Err(e) = execute_sql(&mut conn_guard, &sql, args_move, &tx) {
145+
self.with_conn("execute_stream", move |conn| {
146+
if let Err(e) = execute_sql(conn, &sql, args_move, &tx) {
156147
let _ = tx.send(Err(e));
157148
}
158149
Ok(())
@@ -180,16 +171,11 @@ impl OdbcConnection {
180171

181172
// Create new prepared statement to get metadata
182173
let sql = sql.to_string();
183-
let conn = Arc::clone(&self.conn);
184-
185-
run_blocking(move || {
186-
let conn_guard = conn
187-
.lock()
188-
.map_err(|_| Error::Protocol("Failed to lock connection".into()))?;
189-
let mut prepared = conn_guard.prepare(&sql).map_err(Error::from)?;
174+
self.with_conn("prepare_metadata", move |conn| {
175+
let mut prepared = conn.prepare(&sql)?;
190176
let columns = collect_columns(&mut prepared);
191177
let params = usize::from(prepared.num_params().unwrap_or(0));
192-
Ok::<_, Error>((columns, params))
178+
Ok((columns, params))
193179
})
194180
.await
195181
.map(|(columns, params)| {

0 commit comments

Comments
 (0)