mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-28 00:06:50 +00:00
fix: add type fallback for MySQL to prevent all-NULL display (#40)
Add i32/i16 type decoding and try_get_unchecked fallback to mysql_value_to_json(), fixing all columns showing NULL on older MySQL versions (e.g. 5.6) where sqlx type-checked decoding fails.
This commit is contained in:
@@ -132,6 +132,8 @@ fn mysql_value_to_json(row: &MySqlRow, idx: usize, type_name: &str) -> serde_jso
|
||||
.map(serde_json::Value::String)
|
||||
.or_else(|_| row.try_get::<i64, _>(idx).map(super::safe_i64_to_json))
|
||||
.or_else(|_| row.try_get::<u64, _>(idx).map(super::safe_u64_to_json))
|
||||
.or_else(|_| row.try_get::<i32, _>(idx).map(|v| serde_json::Value::Number(v.into())))
|
||||
.or_else(|_| row.try_get::<i16, _>(idx).map(|v| serde_json::Value::Number(v.into())))
|
||||
.or_else(|_| {
|
||||
row.try_get::<f64, _>(idx).map(|v| {
|
||||
serde_json::Number::from_f64(v).map(serde_json::Value::Number).unwrap_or(serde_json::Value::Null)
|
||||
@@ -142,6 +144,11 @@ fn mysql_value_to_json(row: &MySqlRow, idx: usize, type_name: &str) -> serde_jso
|
||||
row.try_get::<Vec<u8>, _>(idx).map(|b| serde_json::Value::String(String::from_utf8_lossy(&b).to_string()))
|
||||
})
|
||||
.or_else(|e| mysql_temporal_to_json_value(row, idx).ok_or(e))
|
||||
.or_else(|_| row.try_get_unchecked::<String, _>(idx).map(serde_json::Value::String))
|
||||
.or_else(|_| {
|
||||
row.try_get_unchecked::<Vec<u8>, _>(idx)
|
||||
.map(|b| serde_json::Value::String(String::from_utf8_lossy(&b).to_string()))
|
||||
})
|
||||
.unwrap_or(serde_json::Value::Null)
|
||||
}
|
||||
|
||||
|
||||
@@ -22,16 +22,6 @@ pub async fn connect(
|
||||
.map_err(|_| format!("Oracle connection timed out ({CONNECTION_TIMEOUT_SECS}s)"))?
|
||||
.map_err(|e| format!("Oracle connection failed: {e}"))?;
|
||||
|
||||
// Verify connection works with a simple query
|
||||
log::info!("[oracle] connect: verifying with SELECT 1 FROM DUAL...");
|
||||
conn.query("SELECT 1 FROM DUAL", &[]).await.map_err(|e| format!("Oracle connection verification failed: {e}"))?;
|
||||
log::info!("[oracle] connect: verification OK, testing multi-row...");
|
||||
let r = conn
|
||||
.query("SELECT username FROM all_users ORDER BY username", &[])
|
||||
.await
|
||||
.map_err(|e| format!("Oracle multi-row test failed: {e}"))?;
|
||||
log::info!("[oracle] connect: multi-row OK, {} rows", r.rows.len());
|
||||
|
||||
Ok(conn)
|
||||
}
|
||||
|
||||
@@ -270,6 +260,11 @@ pub async fn list_triggers(conn: &OracleClient, schema: &str, table: &str) -> Re
|
||||
pub async fn execute_query(conn: &OracleClient, sql: &str) -> Result<QueryResult, String> {
|
||||
let start = Instant::now();
|
||||
let sql = sql.trim().trim_end_matches(';');
|
||||
|
||||
// Rewrite FETCH FIRST N ROWS ONLY → ROWNUM for Oracle 11g compatibility
|
||||
let sql = rewrite_fetch_first(sql);
|
||||
let sql = sql.as_ref();
|
||||
|
||||
let trimmed = sql.to_uppercase();
|
||||
log::debug!("[oracle] execute_query: sql={}", &sql[..sql.len().min(200)]);
|
||||
|
||||
@@ -324,3 +319,17 @@ pub async fn execute_query(conn: &OracleClient, sql: &str) -> Result<QueryResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn rewrite_fetch_first(sql: &str) -> std::borrow::Cow<'_, str> {
|
||||
let upper = sql.to_uppercase();
|
||||
if let Some(pos) = upper.find("FETCH FIRST") {
|
||||
if let Some(end) = upper[pos..].find("ROWS ONLY") {
|
||||
let between = sql[pos + 11..pos + end].trim();
|
||||
if let Ok(n) = between.parse::<u64>() {
|
||||
let base = sql[..pos].trim_end();
|
||||
return std::borrow::Cow::Owned(format!("SELECT * FROM ({base}) WHERE ROWNUM <= {n}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
std::borrow::Cow::Borrowed(sql)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user