clickhouse_postgres_client/
row.rs

1use sqlx_clickhouse_ext::{
2    sqlx_core::{
3        column::Column as _, column::ColumnIndex, error::Error, postgres::PgRow, row::Row as _,
4        type_info::TypeInfo as _, value::ValueRef as _,
5    },
6    value::ValueRefTryGet as _,
7};
8
9use crate::type_info::{ClickhousePgType, ClickhousePgValue};
10
11pub struct ClickhousePgRow {
12    inner: PgRow,
13}
14impl From<PgRow> for ClickhousePgRow {
15    fn from(row: PgRow) -> Self {
16        Self { inner: row }
17    }
18}
19impl ClickhousePgRow {
20    pub fn try_get_data(&self) -> Result<Vec<(&str, ClickhousePgValue)>, Error> {
21        let mut array = vec![];
22        for (i, column) in self.inner.columns().iter().enumerate() {
23            array.push((column.name(), self.try_get_value(i)?));
24        }
25        Ok(array)
26    }
27
28    pub fn try_get_value<I>(&self, index: I) -> Result<ClickhousePgValue, Error>
29    where
30        I: ColumnIndex<PgRow>,
31    {
32        let index = index.index(&self.inner)?;
33
34        let value = self.inner.try_get_raw(index)?;
35
36        let cpt = ClickhousePgType::try_from((value.type_info().name(), index))?;
37
38        match cpt {
39            ClickhousePgType::Char => (value, index).try_get().map(ClickhousePgValue::Char),
40            ClickhousePgType::Int2 => {
41                // Fix v23
42                if let Ok(bytes) = value.as_bytes() {
43                    match bytes {
44                        b"true" => {
45                            return Ok(ClickhousePgValue::Bool(true));
46                        }
47                        b"false" => {
48                            return Ok(ClickhousePgValue::Bool(false));
49                        }
50                        _ => {}
51                    }
52                }
53                (value, index).try_get().map(ClickhousePgValue::I16)
54            }
55            ClickhousePgType::Int4 => (value, index).try_get().map(ClickhousePgValue::I32),
56            ClickhousePgType::Int8 => (value, index).try_get().map(ClickhousePgValue::I64),
57            ClickhousePgType::Float4 => (value, index).try_get().map(ClickhousePgValue::F32),
58            ClickhousePgType::Float8 => (value, index).try_get().map(ClickhousePgValue::F64),
59            ClickhousePgType::Varchar => (value, index).try_get().map(ClickhousePgValue::String),
60            #[cfg(feature = "chrono")]
61            ClickhousePgType::Date => (value, index).try_get().map(ClickhousePgValue::NaiveDate),
62            #[cfg(feature = "bigdecimal")]
63            ClickhousePgType::Numeric => {
64                (value, index).try_get().map(ClickhousePgValue::BigDecimal)
65            }
66            #[cfg(feature = "uuid")]
67            ClickhousePgType::Uuid => (value, index).try_get().map(ClickhousePgValue::Uuid),
68        }
69    }
70}