mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-21 08:13:34 +00:00
fix: preserve bigint precision for values exceeding JS safe integer range
Closes #137
This commit is contained in:
@@ -40,6 +40,24 @@ pub fn connection_timeout() -> Duration {
|
||||
Duration::from_secs(CONNECTION_TIMEOUT_SECS)
|
||||
}
|
||||
|
||||
const JS_MAX_SAFE_INTEGER: i64 = 9_007_199_254_740_991;
|
||||
|
||||
pub fn safe_i64_to_json(v: i64) -> serde_json::Value {
|
||||
if v > JS_MAX_SAFE_INTEGER || v < -JS_MAX_SAFE_INTEGER {
|
||||
serde_json::Value::String(v.to_string())
|
||||
} else {
|
||||
serde_json::Value::Number(v.into())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn safe_u64_to_json(v: u64) -> serde_json::Value {
|
||||
if v > JS_MAX_SAFE_INTEGER as u64 {
|
||||
serde_json::Value::String(v.to_string())
|
||||
} else {
|
||||
serde_json::Value::Number(v.into())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tcp_probe_timeout() -> Duration {
|
||||
Duration::from_secs(TCP_PROBE_TIMEOUT_SECS)
|
||||
}
|
||||
|
||||
@@ -130,8 +130,8 @@ fn mysql_value_to_json(row: &MySqlRow, idx: usize, type_name: &str) -> serde_jso
|
||||
|
||||
row.try_get::<String, _>(idx)
|
||||
.map(serde_json::Value::String)
|
||||
.or_else(|_| row.try_get::<i64, _>(idx).map(|v| serde_json::Value::Number(v.into())))
|
||||
.or_else(|_| row.try_get::<u64, _>(idx).map(|v| serde_json::Value::Number(v.into())))
|
||||
.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::<f64, _>(idx).map(|v| {
|
||||
serde_json::Number::from_f64(v).map(serde_json::Value::Number).unwrap_or(serde_json::Value::Null)
|
||||
|
||||
@@ -72,7 +72,7 @@ fn pg_value_to_json(row: &PgRow, idx: usize, type_name: &str) -> serde_json::Val
|
||||
|
||||
row.try_get::<String, _>(idx)
|
||||
.map(serde_json::Value::String)
|
||||
.or_else(|_| row.try_get::<i64, _>(idx).map(|v| serde_json::Value::Number(v.into())))
|
||||
.or_else(|_| row.try_get::<i64, _>(idx).map(super::safe_i64_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(|_| {
|
||||
|
||||
@@ -180,7 +180,7 @@ pub async fn execute_query(pool: &SqlitePool, sql: &str) -> Result<QueryResult,
|
||||
.map(|i| {
|
||||
row.try_get::<String, _>(i)
|
||||
.map(serde_json::Value::String)
|
||||
.or_else(|_| row.try_get::<i64, _>(i).map(|v| serde_json::Value::Number(v.into())))
|
||||
.or_else(|_| row.try_get::<i64, _>(i).map(super::safe_i64_to_json))
|
||||
.or_else(|_| {
|
||||
row.try_get::<f64, _>(i).map(|v| {
|
||||
serde_json::Number::from_f64(v)
|
||||
|
||||
@@ -62,7 +62,7 @@ fn row_to_json(row: &tiberius::Row) -> Vec<serde_json::Value> {
|
||||
} else if let Some(v) = row.try_get::<i32, _>(i).ok().flatten() {
|
||||
serde_json::Value::Number(v.into())
|
||||
} else if let Some(v) = row.try_get::<i64, _>(i).ok().flatten() {
|
||||
serde_json::Value::Number(v.into())
|
||||
super::safe_i64_to_json(v)
|
||||
} else if let Some(v) = row.try_get::<f64, _>(i).ok().flatten() {
|
||||
serde_json::Number::from_f64(v).map(serde_json::Value::Number).unwrap_or(serde_json::Value::Null)
|
||||
} else if let Some(v) = row.try_get::<bool, _>(i).ok().flatten() {
|
||||
|
||||
Reference in New Issue
Block a user