use std::{collections::HashMap, net::IpAddr};
use serde_json::{Value, json};
use tokio_postgres::{Row, types::Type};
const FMT_DATETIME: &str = "%Y-%m-%d %H:%M:%S";
const FMT_DATE: &str = "%Y-%m-%d";
const FMT_TIME: &str = "%H:%M:%S";
pub fn pg_value_to_json_value(pg_row: &Row) -> HashMap<String, Value> {
let mut hash_map_row = HashMap::new();
for column in pg_row.columns().iter() {
let pg_type = column.type_().clone();
let name = column.name();
let key_name = name.to_string();
match pg_type {
Type::BOOL => {
let value: Option<bool> = pg_row.get(name);
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
Type::CHAR => {
let value: Option<i8> = pg_row.get(name);
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
Type::INT2 => {
let value: Option<i16> = pg_row.get(name);
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
Type::INT4 => {
let value: Option<i32> = pg_row.get(name);
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
Type::INT8 => {
let value: Option<i64> = pg_row.get(name);
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
Type::OID => {
let value: Option<u32> = pg_row.get(name);
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
Type::FLOAT4 => {
let value: Option<f32> = pg_row.get(name);
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
Type::FLOAT8 => {
let value: Option<f64> = pg_row.get(name);
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
Type::VARCHAR | Type::TEXT => {
let opt_value: Option<String> = pg_row.get(name);
let value = match opt_value {
Some(value) => value,
None => "".to_string(),
};
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
Type::BYTEA => {
let value: Option<Vec<u8>> = pg_row.get(name);
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
Type::INET => {
let value: Option<IpAddr> = pg_row.get(name);
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
Type::TIMESTAMP => {
let opt_value: Option<chrono::NaiveDateTime> = pg_row.get(name);
let value_str = match opt_value {
Some(t) => t.format(FMT_DATETIME).to_string(),
None => "".to_string(),
};
let json_value = json!(value_str);
hash_map_row.insert(key_name, json_value);
}
Type::TIMESTAMPTZ => {
let opt_value: Option<chrono::NaiveDateTime> = pg_row.get(name);
let value_str = match opt_value {
Some(t) => t.format(FMT_DATETIME).to_string(),
None => "".to_string(),
};
let json_value = json!(value_str);
hash_map_row.insert(key_name, json_value);
}
Type::DATE => {
let opt_value: Option<chrono::NaiveDate> = pg_row.get(name);
let value_str = match opt_value {
Some(t) => t.format(FMT_DATE).to_string(),
None => "".to_string(),
};
let json_value = json!(value_str);
hash_map_row.insert(key_name, json_value);
}
Type::TIME => {
let opt_value: Option<chrono::NaiveTime> = pg_row.get(name);
let value_str = match opt_value {
Some(t) => t.format(FMT_TIME).to_string(),
None => "".to_string(),
};
let json_value = json!(value_str);
hash_map_row.insert(key_name, json_value);
}
Type::JSON_ARRAY =>{
let value: Option<Value> = pg_row.get(name);
let json_value = json!(value);
hash_map_row.insert(key_name, json_value);
}
_ => {}
}
}
hash_map_row
}