Skip to content

Commit 2629cf0

Browse files
committed
refactor: Organize ODBC module imports and enhance type information implementations
This commit reorganizes the imports in the ODBC module for better readability and consistency. It also refines the implementation of type information for various data types (i32, i64, f32, f64, String, &str, Vec<u8>) to improve clarity and maintainability. Additionally, it updates the ODBC connection executor and worker to enhance the handling of SQL query results.
1 parent 33a0317 commit 2629cf0

File tree

6 files changed

+172
-80
lines changed

6 files changed

+172
-80
lines changed

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::describe::Describe;
22
use crate::error::Error;
33
use crate::executor::{Execute, Executor};
4-
use crate::odbc::{Odbc, OdbcArgumentValue, OdbcConnection, OdbcQueryResult, OdbcRow, OdbcStatement, OdbcTypeInfo};
4+
use crate::odbc::{
5+
Odbc, OdbcArgumentValue, OdbcConnection, OdbcQueryResult, OdbcRow, OdbcStatement, OdbcTypeInfo,
6+
};
57
use either::Either;
68
use futures_core::future::BoxFuture;
79
use futures_core::stream::BoxStream;
@@ -96,17 +98,23 @@ fn interpolate_sql_with_odbc_args(sql: &str, args: &[OdbcArgumentValue<'_>]) ->
9698
OdbcArgumentValue::Text(s) => {
9799
result.push('\'');
98100
for c in s.chars() {
99-
if c == '\'' { result.push('\''); }
101+
if c == '\'' {
102+
result.push('\'');
103+
}
100104
result.push(c);
101105
}
102106
result.push('\'');
103107
}
104108
OdbcArgumentValue::Bytes(b) => {
105109
result.push_str("X'");
106-
for byte in b { result.push_str(&format!("{:02X}", byte)); }
110+
for byte in b {
111+
result.push_str(&format!("{:02X}", byte));
112+
}
107113
result.push('\'');
108114
}
109-
OdbcArgumentValue::Null | OdbcArgumentValue::Phantom(_) => result.push_str("NULL"),
115+
OdbcArgumentValue::Null | OdbcArgumentValue::Phantom(_) => {
116+
result.push_str("NULL")
117+
}
110118
}
111119
} else {
112120
result.push('?');

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

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use futures_channel::oneshot;
55
use futures_intrusive::sync::Mutex;
66

77
use crate::error::Error;
8-
use crate::odbc::{OdbcArgumentValue, OdbcColumn, OdbcConnectOptions, OdbcQueryResult, OdbcRow, OdbcTypeInfo};
8+
use crate::odbc::{
9+
OdbcArgumentValue, OdbcColumn, OdbcConnectOptions, OdbcQueryResult, OdbcRow, OdbcTypeInfo,
10+
};
911
use either::Either;
1012
use odbc_api::Cursor;
1113

@@ -232,40 +234,70 @@ impl ConnectionWorker {
232234
});
233235
}
234236
}
235-
while let Ok(Some(mut row)) = cursor.next_row() {
237+
while let Ok(Some(mut row)) = cursor.next_row() {
236238
let mut values: Vec<(OdbcTypeInfo, Option<Vec<u8>>)> =
237239
Vec::with_capacity(columns.len());
238240
for i in 1..=columns.len() {
239241
let mut buf = Vec::new();
240-
// Try text first, then fallback to binary, then numeric
241-
if let Ok(true) = row.get_text(i as u16, &mut buf) {
242-
values.push((OdbcTypeInfo { name: "TEXT".into(), is_null: false }, Some(buf)));
243-
} else if let Ok(false) = row.get_text(i as u16, &mut buf) {
244-
values.push((OdbcTypeInfo { name: "TEXT".into(), is_null: true }, None));
245-
} else if let Ok(bytes) = row.get_binary(i as u16) {
246-
values.push((OdbcTypeInfo { name: "BLOB".into(), is_null: false }, Some(bytes.unwrap_or_default())));
247-
} else if let Ok(opt) = row.get_data::<i64>(i as u16) {
248-
if let Some(num) = opt {
249-
values.push((OdbcTypeInfo { name: "INT".into(), is_null: false }, Some(num.to_string().into_bytes())));
250-
} else {
251-
values.push((OdbcTypeInfo { name: "INT".into(), is_null: true }, None));
252-
}
253-
} else if let Ok(opt) = row.get_data::<f64>(i as u16) {
254-
if let Some(num) = opt {
255-
values.push((OdbcTypeInfo { name: "DOUBLE".into(), is_null: false }, Some(num.to_string().into_bytes())));
242+
// Try text first, then fallback to binary, then numeric
243+
if let Ok(true) = row.get_text(i as u16, &mut buf) {
244+
values.push((
245+
OdbcTypeInfo {
246+
name: "TEXT".into(),
247+
is_null: false,
248+
},
249+
Some(buf),
250+
));
251+
} else if let Ok(false) =
252+
row.get_text(i as u16, &mut buf)
253+
{
254+
values.push((
255+
OdbcTypeInfo {
256+
name: "TEXT".into(),
257+
is_null: true,
258+
},
259+
None,
260+
));
256261
} else {
257-
values.push((OdbcTypeInfo { name: "DOUBLE".into(), is_null: true }, None));
262+
let mut bin = Vec::new();
263+
match row.get_binary(i as u16, &mut bin) {
264+
Ok(true) => values.push((
265+
OdbcTypeInfo {
266+
name: "BLOB".into(),
267+
is_null: false,
268+
},
269+
Some(bin),
270+
)),
271+
Ok(false) => values.push((
272+
OdbcTypeInfo {
273+
name: "BLOB".into(),
274+
is_null: true,
275+
},
276+
None,
277+
)),
278+
Err(_) => values.push((
279+
OdbcTypeInfo {
280+
name: "UNKNOWN".into(),
281+
is_null: true,
282+
},
283+
None,
284+
)),
285+
}
258286
}
259-
} else {
260-
values.push((OdbcTypeInfo { name: "UNKNOWN".into(), is_null: true }, None));
261287
}
262-
}
263-
let _ = tx.send(Ok(Either::Right(OdbcRow { columns: columns.clone(), values })));
288+
let _ = tx.send(Ok(Either::Right(OdbcRow {
289+
columns: columns.clone(),
290+
values,
291+
})));
264292
}
265-
let _ = tx.send(Ok(Either::Left(OdbcQueryResult { rows_affected: 0 })));
293+
let _ = tx.send(Ok(Either::Left(OdbcQueryResult {
294+
rows_affected: 0,
295+
})));
266296
}
267297
Ok(None) => {
268-
let _ = tx.send(Ok(Either::Left(OdbcQueryResult { rows_affected: 0 })));
298+
let _ = tx.send(Ok(Either::Left(OdbcQueryResult {
299+
rows_affected: 0,
300+
})));
269301
}
270302
Err(e) => {
271303
let _ = tx.send(Err(Error::from(e)));

sqlx-core/src/odbc/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ mod query_result;
1212
mod row;
1313
mod statement;
1414
mod transaction;
15-
mod type_info;
1615
mod r#type;
16+
mod type_info;
1717
mod value;
1818

1919
pub use arguments::{OdbcArgumentValue, OdbcArguments};

sqlx-core/src/odbc/type.rs

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,89 @@
11
use crate::odbc::Odbc;
2-
use crate::types::Type;
32
use crate::odbc::OdbcTypeInfo;
3+
use crate::types::Type;
44

55
impl Type<Odbc> for i32 {
6-
fn type_info() -> OdbcTypeInfo { OdbcTypeInfo { name: "INT".into(), is_null: false } }
7-
fn compatible(_ty: &OdbcTypeInfo) -> bool { true }
6+
fn type_info() -> OdbcTypeInfo {
7+
OdbcTypeInfo {
8+
name: "INT".into(),
9+
is_null: false,
10+
}
11+
}
12+
fn compatible(_ty: &OdbcTypeInfo) -> bool {
13+
true
14+
}
815
}
916

1017
impl Type<Odbc> for i64 {
11-
fn type_info() -> OdbcTypeInfo { OdbcTypeInfo { name: "BIGINT".into(), is_null: false } }
12-
fn compatible(_ty: &OdbcTypeInfo) -> bool { true }
18+
fn type_info() -> OdbcTypeInfo {
19+
OdbcTypeInfo {
20+
name: "BIGINT".into(),
21+
is_null: false,
22+
}
23+
}
24+
fn compatible(_ty: &OdbcTypeInfo) -> bool {
25+
true
26+
}
1327
}
1428

1529
impl Type<Odbc> for f64 {
16-
fn type_info() -> OdbcTypeInfo { OdbcTypeInfo { name: "DOUBLE".into(), is_null: false } }
17-
fn compatible(_ty: &OdbcTypeInfo) -> bool { true }
30+
fn type_info() -> OdbcTypeInfo {
31+
OdbcTypeInfo {
32+
name: "DOUBLE".into(),
33+
is_null: false,
34+
}
35+
}
36+
fn compatible(_ty: &OdbcTypeInfo) -> bool {
37+
true
38+
}
1839
}
1940

2041
impl Type<Odbc> for f32 {
21-
fn type_info() -> OdbcTypeInfo { OdbcTypeInfo { name: "FLOAT".into(), is_null: false } }
22-
fn compatible(_ty: &OdbcTypeInfo) -> bool { true }
42+
fn type_info() -> OdbcTypeInfo {
43+
OdbcTypeInfo {
44+
name: "FLOAT".into(),
45+
is_null: false,
46+
}
47+
}
48+
fn compatible(_ty: &OdbcTypeInfo) -> bool {
49+
true
50+
}
2351
}
2452

2553
impl Type<Odbc> for String {
26-
fn type_info() -> OdbcTypeInfo { OdbcTypeInfo { name: "TEXT".into(), is_null: false } }
27-
fn compatible(_ty: &OdbcTypeInfo) -> bool { true }
54+
fn type_info() -> OdbcTypeInfo {
55+
OdbcTypeInfo {
56+
name: "TEXT".into(),
57+
is_null: false,
58+
}
59+
}
60+
fn compatible(_ty: &OdbcTypeInfo) -> bool {
61+
true
62+
}
2863
}
2964

3065
impl<'a> Type<Odbc> for &'a str {
31-
fn type_info() -> OdbcTypeInfo { OdbcTypeInfo { name: "TEXT".into(), is_null: false } }
32-
fn compatible(_ty: &OdbcTypeInfo) -> bool { true }
66+
fn type_info() -> OdbcTypeInfo {
67+
OdbcTypeInfo {
68+
name: "TEXT".into(),
69+
is_null: false,
70+
}
71+
}
72+
fn compatible(_ty: &OdbcTypeInfo) -> bool {
73+
true
74+
}
3375
}
3476

3577
impl Type<Odbc> for Vec<u8> {
36-
fn type_info() -> OdbcTypeInfo { OdbcTypeInfo { name: "BLOB".into(), is_null: false } }
37-
fn compatible(_ty: &OdbcTypeInfo) -> bool { true }
78+
fn type_info() -> OdbcTypeInfo {
79+
OdbcTypeInfo {
80+
name: "BLOB".into(),
81+
is_null: false,
82+
}
83+
}
84+
fn compatible(_ty: &OdbcTypeInfo) -> bool {
85+
true
86+
}
3887
}
3988

4089
// Option<T> blanket impl is provided in core types; do not re-implement here.

sqlx-core/src/odbc/value.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use crate::odbc::{Odbc, OdbcTypeInfo};
21
use crate::decode::Decode;
32
use crate::error::BoxDynError;
3+
use crate::odbc::{Odbc, OdbcTypeInfo};
44
use crate::value::{Value, ValueRef};
55
use std::borrow::Cow;
66

@@ -87,7 +87,9 @@ impl<'r> Decode<'r, Odbc> for &'r str {
8787

8888
impl<'r> Decode<'r, Odbc> for i64 {
8989
fn decode(value: OdbcValueRef<'r>) -> Result<Self, BoxDynError> {
90-
if let Some(i) = value.int { return Ok(i); }
90+
if let Some(i) = value.int {
91+
return Ok(i);
92+
}
9193
if let Some(bytes) = value.blob {
9294
let s = std::str::from_utf8(bytes)?;
9395
return Ok(s.trim().parse()?);
@@ -104,7 +106,9 @@ impl<'r> Decode<'r, Odbc> for i32 {
104106

105107
impl<'r> Decode<'r, Odbc> for f64 {
106108
fn decode(value: OdbcValueRef<'r>) -> Result<Self, BoxDynError> {
107-
if let Some(f) = value.float { return Ok(f); }
109+
if let Some(f) = value.float {
110+
return Ok(f);
111+
}
108112
if let Some(bytes) = value.blob {
109113
let s = std::str::from_utf8(bytes)?;
110114
return Ok(s.trim().parse()?);

0 commit comments

Comments
 (0)