From 70ff0bc06ccaaa5be143c2fe42ed7b042fdb6ab7 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Mon, 24 Nov 2025 09:36:32 +0100 Subject: [PATCH] Implement robust type handling in row_to_map: Enhanced the row_to_map function to provide a more reliable string representation of database values based on their actual types, improving error handling and data integrity. --- src/db/connection.rs | 47 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/db/connection.rs b/src/db/connection.rs index 0ce5c62..d937d36 100644 --- a/src/db/connection.rs +++ b/src/db/connection.rs @@ -1,4 +1,5 @@ use postgres::{Client, NoTls}; +use postgres::types::Type; use postgres::Error as PgError; use std::collections::HashMap; use std::fmt; @@ -84,11 +85,53 @@ impl Database { fn row_to_map(row: postgres::Row) -> Row { let mut map = HashMap::with_capacity(row.len()); + for (idx, col) in row.columns().iter().enumerate() { let name = col.name().to_string(); - let value: Option = row.get(idx); - map.insert(name, value.unwrap_or_default()); + let ty = col.type_(); + + // Versuche je nach tatsächlichem DB-Typ eine sinnvolle + // String-Repräsentation zu erzeugen. Ziel ist maximale + // Robustheit: statt zu panic!en geben wir im Zweifel einen + // Debug-String zurück. + let value = match *ty { + // Ganzzahlen + Type::INT2 => row.try_get::<_, i16>(idx).map(|v| v.to_string()), + Type::INT4 => row.try_get::<_, i32>(idx).map(|v| v.to_string()), + Type::INT8 => row.try_get::<_, i64>(idx).map(|v| v.to_string()), + + // Gleitkommazahlen / Numerics + Type::FLOAT4 => row.try_get::<_, f32>(idx).map(|v| v.to_string()), + Type::FLOAT8 | Type::NUMERIC => { + row.try_get::<_, f64>(idx).map(|v| v.to_string()) + } + + // Textuelle Typen + Type::TEXT | Type::VARCHAR | Type::BPCHAR | Type::NAME => { + row.try_get::<_, String>(idx) + } + + // Booleans + Type::BOOL => row.try_get::<_, bool>(idx).map(|v| v.to_string()), + + // Für Zeit-/Datums-Typen und alle anderen seltener + // verwendeten Typen nutzen wir eine generische Fallback- + // Strategie weiter unten. + + // Fallback: Versuche direkt String, ansonsten Debug-Ausgabe. + _ => row + .try_get::<_, String>(idx) + .or_else(|_| { + // Letzter Rettungsanker: hole den Wert als `postgres::types::Type` + // existiert nicht direkt, daher nur ein Platzhalter-String. + Ok(format!("", ty)) + }), + } + .unwrap_or_default(); + + map.insert(name, value); } + map } }