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.

This commit is contained in:
Torsten Schulz (local)
2025-11-24 09:36:32 +01:00
parent 2c547ed495
commit 70ff0bc06c

View File

@@ -1,4 +1,5 @@
use postgres::{Client, NoTls}; use postgres::{Client, NoTls};
use postgres::types::Type;
use postgres::Error as PgError; use postgres::Error as PgError;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
@@ -84,11 +85,53 @@ impl Database {
fn row_to_map(row: postgres::Row) -> Row { fn row_to_map(row: postgres::Row) -> Row {
let mut map = HashMap::with_capacity(row.len()); let mut map = HashMap::with_capacity(row.len());
for (idx, col) in row.columns().iter().enumerate() { for (idx, col) in row.columns().iter().enumerate() {
let name = col.name().to_string(); let name = col.name().to_string();
let value: Option<String> = row.get(idx); let ty = col.type_();
map.insert(name, value.unwrap_or_default());
// 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!("<unsupported type {:?}>", ty))
}),
}
.unwrap_or_default();
map.insert(name, value);
}
map map
} }
} }