elif_orm/loading/batch_loader/
row_conversion.rs

1use serde_json::Value as JsonValue;
2
3/// Convert a PostgreSQL row to JSON Value (standalone function)
4pub fn convert_row_to_json(row: &sqlx::postgres::PgRow) -> Result<JsonValue, String> {
5    use sqlx::{Column, Row};
6    let mut map = serde_json::Map::new();
7
8    for (i, column) in row.columns().iter().enumerate() {
9        let column_name = column.name();
10
11        // Try to get the value as different PostgreSQL types
12        let json_value = if let Ok(value) = row.try_get::<Option<String>, _>(i) {
13            value.map_or(JsonValue::Null, JsonValue::String)
14        } else if let Ok(value) = row.try_get::<Option<i64>, _>(i) {
15            value.map_or(JsonValue::Null, |v| {
16                JsonValue::Number(serde_json::Number::from(v))
17            })
18        } else if let Ok(value) = row.try_get::<Option<i32>, _>(i) {
19            value.map_or(JsonValue::Null, |v| {
20                JsonValue::Number(serde_json::Number::from(v))
21            })
22        } else if let Ok(value) = row.try_get::<Option<f64>, _>(i) {
23            value.map_or(JsonValue::Null, |v| {
24                JsonValue::Number(
25                    serde_json::Number::from_f64(v).unwrap_or(serde_json::Number::from(0)),
26                )
27            })
28        } else if let Ok(value) = row.try_get::<Option<f32>, _>(i) {
29            value.map_or(JsonValue::Null, |v| {
30                JsonValue::Number(
31                    serde_json::Number::from_f64(v as f64).unwrap_or(serde_json::Number::from(0)),
32                )
33            })
34        } else if let Ok(value) = row.try_get::<Option<bool>, _>(i) {
35            value.map_or(JsonValue::Null, JsonValue::Bool)
36        } else if let Ok(value) = row.try_get::<Option<chrono::DateTime<chrono::Utc>>, _>(i) {
37            value.map_or(JsonValue::Null, |v| JsonValue::String(v.to_rfc3339()))
38        } else if let Ok(value) = row.try_get::<Option<uuid::Uuid>, _>(i) {
39            value.map_or(JsonValue::Null, |v| JsonValue::String(v.to_string()))
40        } else if let Ok(value) = row.try_get::<Option<serde_json::Value>, _>(i) {
41            value.unwrap_or(JsonValue::Null)
42        } else {
43            // Fallback: try to get as string or return null
44            if let Ok(value) = row.try_get::<Option<String>, _>(i) {
45                value.map_or(JsonValue::Null, JsonValue::String)
46            } else {
47                JsonValue::Null
48            }
49        };
50
51        map.insert(column_name.to_string(), json_value);
52    }
53
54    Ok(JsonValue::Object(map))
55}
56
57/// Row to JSON conversion functionality
58impl super::BatchLoader {
59    /// Convert a PostgreSQL row to JSON Value
60    pub(super) fn row_to_json(&self, row: &sqlx::postgres::PgRow) -> Result<JsonValue, String> {
61        use sqlx::{Column, Row};
62        let mut map = serde_json::Map::new();
63
64        for (i, column) in row.columns().iter().enumerate() {
65            let column_name = column.name();
66
67            // Try to get the value as different PostgreSQL types
68            let json_value = if let Ok(value) = row.try_get::<Option<String>, _>(i) {
69                value.map_or(JsonValue::Null, JsonValue::String)
70            } else if let Ok(value) = row.try_get::<Option<i64>, _>(i) {
71                value.map_or(JsonValue::Null, |v| {
72                    JsonValue::Number(serde_json::Number::from(v))
73                })
74            } else if let Ok(value) = row.try_get::<Option<i32>, _>(i) {
75                value.map_or(JsonValue::Null, |v| {
76                    JsonValue::Number(serde_json::Number::from(v))
77                })
78            } else if let Ok(value) = row.try_get::<Option<f64>, _>(i) {
79                value.map_or(JsonValue::Null, |v| {
80                    JsonValue::Number(
81                        serde_json::Number::from_f64(v).unwrap_or(serde_json::Number::from(0)),
82                    )
83                })
84            } else if let Ok(value) = row.try_get::<Option<f32>, _>(i) {
85                value.map_or(JsonValue::Null, |v| {
86                    JsonValue::Number(
87                        serde_json::Number::from_f64(v as f64)
88                            .unwrap_or(serde_json::Number::from(0)),
89                    )
90                })
91            } else if let Ok(value) = row.try_get::<Option<bool>, _>(i) {
92                value.map_or(JsonValue::Null, JsonValue::Bool)
93            } else if let Ok(value) = row.try_get::<Option<chrono::DateTime<chrono::Utc>>, _>(i) {
94                value.map_or(JsonValue::Null, |v| JsonValue::String(v.to_rfc3339()))
95            } else if let Ok(value) = row.try_get::<Option<uuid::Uuid>, _>(i) {
96                value.map_or(JsonValue::Null, |v| JsonValue::String(v.to_string()))
97            } else if let Ok(value) = row.try_get::<Option<serde_json::Value>, _>(i) {
98                value.unwrap_or(JsonValue::Null)
99            } else {
100                // Fallback: try to get as string or return null
101                if let Ok(value) = row.try_get::<Option<String>, _>(i) {
102                    value.map_or(JsonValue::Null, JsonValue::String)
103                } else {
104                    JsonValue::Null
105                }
106            };
107
108            map.insert(column_name.to_string(), json_value);
109        }
110
111        Ok(JsonValue::Object(map))
112    }
113}