feat: improve query return types

This commit is contained in:
Alexander Navarro 2025-01-22 15:56:04 -03:00
parent 5d1b4bdfd8
commit a4fe3808de
3 changed files with 195 additions and 133 deletions

View file

@ -1,116 +1,15 @@
use chrono::Utc;
use sqlx::postgres::PgRow;
use sqlx::Column as _;
use sqlx::Row as _;
use sqlx::TypeInfo;
use crate::error::Result;
use crate::error;
use crate::error::Error;
mod postgres;
#[derive(Debug)]
pub struct Column<T> {
name: String,
sql_type: String,
value: Option<T>,
}
pub async fn handle_query(url: String, query: &String) -> Result<()> {
let connector = postgres::PgConnector::new(url).await?;
#[derive(Debug)]
pub enum ColumnType {
I8(Column<i8>),
String(Column<String>),
Bool(Column<bool>),
I16(Column<i16>),
I32(Column<i32>),
I64(Column<i64>),
F32(Column<f32>),
F64(Column<f64>),
DateTime(Column<chrono::DateTime<Utc>>),
}
let rows = connector.query(query).await?;
impl ColumnType {
pub fn new(row: &PgRow, idx: usize) -> error::Result<Self> {
let column = row
.columns()
.get(idx)
.ok_or_else(|| Error::ColumnParse(String::from("Could not get column")))?;
let sql_type = column.type_info().name();
let name = String::from(column.name());
match sql_type {
"BOOL" => {
let value: Option<bool> = row.try_get(idx)?;
Ok(ColumnType::Bool(Column {
sql_type: String::from(sql_type),
value,
name,
}))
}
"VARCHAR" | "char(n)" | "TEXT" | "NAME" => {
let value: Option<String> = row.try_get(idx)?;
Ok(ColumnType::String(Column {
sql_type: String::from(sql_type),
value,
name,
}))
}
"CHAR" => {
let value: Option<i8> = row.try_get(idx)?;
Ok(ColumnType::I8(Column {
sql_type: String::from(sql_type),
value,
name,
}))
}
"SMALLSERIAL" | "SMALLINT" => {
let value: Option<i16> = row.try_get(idx)?;
Ok(ColumnType::I16(Column {
sql_type: String::from(sql_type),
value,
name,
}))
}
"INT" | "INT4" | "SERIAL" => {
let value: Option<i32> = row.try_get(idx)?;
Ok(ColumnType::I32(Column {
sql_type: String::from(sql_type),
value,
name,
}))
}
"INT8" | "BIGSERIAL" | "BIGINT" => {
let value: Option<i64> = row.try_get(idx)?;
Ok(ColumnType::I64(Column {
sql_type: String::from(sql_type),
value,
name,
}))
}
"FLOAT4" | "REAL" => {
let value: Option<f32> = row.try_get(idx)?;
Ok(ColumnType::F32(Column {
sql_type: String::from(sql_type),
value,
name,
}))
}
"FLOAT8" | "double precision" => {
let value: Option<f64> = row.try_get(idx)?;
Ok(ColumnType::F64(Column {
sql_type: String::from(sql_type),
value,
name,
}))
}
"TIMESTAMP" | "TIMESTAMPTZ" => {
// with-chrono feature is needed for this
let value: Option<chrono::DateTime<Utc>> = row.try_get(idx)?;
Ok(ColumnType::DateTime(Column {
sql_type: String::from(sql_type),
value,
name,
}))
}
&_ => Err(Error::ColumnParse(format!("{} type not found!", sql_type))),
}
for (idx, row) in rows.iter().enumerate() {
println!("Row {}: {:?}", idx, row);
}
return Ok(());
}