1use serde_json::Value;
2use sqlx::any::AnyRow;
3use sqlx::{Column, Row, TypeInfo, ValueRef};
4
5pub fn row_to_json(row: &AnyRow) -> Value {
7 let mut obj = serde_json::Map::new();
8
9 for col in row.columns() {
10 let name = col.name().to_string();
11 let ordinal = col.ordinal();
12 let type_name = col.type_info().name().to_uppercase();
13
14 let value = decode_column(row, ordinal, &type_name);
15 obj.insert(name, value);
16 }
17
18 Value::Object(obj)
19}
20
21fn decode_column(row: &AnyRow, ordinal: usize, type_name: &str) -> Value {
22 if let Ok(v) = row.try_get_raw(ordinal) {
24 if v.is_null() {
25 return Value::Null;
26 }
27 }
28
29 match type_name {
30 "BOOL" | "BOOLEAN" => {
32 if let Ok(v) = row.try_get::<bool, _>(ordinal) {
33 return Value::Bool(v);
34 }
35 }
36
37 "INT2" | "SMALLINT" | "TINYINT" => {
39 if let Ok(v) = row.try_get::<i16, _>(ordinal) {
40 return Value::Number(v.into());
41 }
42 }
43 "INT" | "INT4" | "INTEGER" | "MEDIUMINT" => {
44 if let Ok(v) = row.try_get::<i32, _>(ordinal) {
45 return Value::Number(v.into());
46 }
47 }
48 "INT8" | "BIGINT" => {
49 if let Ok(v) = row.try_get::<i64, _>(ordinal) {
50 return Value::Number(v.into());
51 }
52 }
53
54 "FLOAT4" | "REAL" | "FLOAT" => {
56 if let Ok(v) = row.try_get::<f64, _>(ordinal) {
57 return serde_json::Number::from_f64(v)
58 .map(Value::Number)
59 .unwrap_or(Value::Null);
60 }
61 }
62 "FLOAT8" | "DOUBLE" | "DOUBLE PRECISION" | "NUMERIC" | "DECIMAL" => {
63 if let Ok(v) = row.try_get::<f64, _>(ordinal) {
64 return serde_json::Number::from_f64(v)
65 .map(Value::Number)
66 .unwrap_or(Value::Null);
67 }
68 }
69
70 "BYTEA" | "BLOB" | "BINARY" | "VARBINARY" | "LONGBLOB" | "MEDIUMBLOB" | "TINYBLOB" => {
72 if let Ok(v) = row.try_get::<Vec<u8>, _>(ordinal) {
73 return Value::String(format!("(blob: {} bytes)", v.len()));
74 }
75 }
76
77 _ => {}
79 }
80
81 if let Ok(v) = row.try_get::<i64, _>(ordinal) {
83 return Value::Number(v.into());
84 }
85 if let Ok(v) = row.try_get::<f64, _>(ordinal) {
86 if let Some(n) = serde_json::Number::from_f64(v) {
87 return Value::Number(n);
88 }
89 }
90 if let Ok(v) = row.try_get::<bool, _>(ordinal) {
91 return Value::Bool(v);
92 }
93 if let Ok(v) = row.try_get::<String, _>(ordinal) {
94 return Value::String(v);
95 }
96
97 Value::Null
98}