Skip to main content

rbdc_pg/
row.rs

1use crate::column::PgColumn;
2use crate::message::DataRow;
3use crate::meta_data::PgMetaData;
4use crate::statement::PgStatementMetadata;
5use crate::types::decode::Decode;
6use crate::value::{PgValueFormat, PgValueRef};
7use rbdc::db::MetaData;
8use rbdc::Error;
9use rbs::Value;
10use std::sync::Arc;
11
12/// Implementation of [`Row`] for PostgreSQL.
13#[derive(Debug)]
14pub struct PgRow {
15    pub(crate) data: DataRow,
16    pub(crate) format: PgValueFormat,
17    pub(crate) metadata: Arc<PgStatementMetadata>,
18    /// Session timezone offset in seconds from UTC, used for TIMESTAMPTZ decoding
19    pub(crate) timezone_sec: Option<i32>,
20}
21
22impl PgRow {
23    pub fn columns(&self) -> &[PgColumn] {
24        &self.metadata.columns
25    }
26
27    pub fn try_get_raw(&self, index: &str) -> Result<PgValueRef<'_>, Error> {
28        let index = self.index(index)?;
29        let column = &self.metadata.columns[index];
30        let value = self.data.get(index);
31
32        Ok(PgValueRef {
33            format: self.format,
34            type_info: column.type_info.clone(),
35            value,
36            timezone_sec: self.timezone_sec,
37        })
38    }
39
40    pub fn try_get(&mut self, index: usize) -> Result<PgValueRef, Error> {
41        if (index + 1) > self.metadata.column_names.len() {
42            return Err(Error::from(format!("ColumnNotFound={}", index)));
43        }
44        let column = &self.metadata.columns[index];
45        let value = self.data.get(index);
46        Ok(PgValueRef {
47            value: value,
48            type_info: column.type_info.clone(),
49            format: self.format,
50            timezone_sec: self.timezone_sec,
51        })
52    }
53}
54
55impl PgRow {
56    pub fn index(&self, idx: &str) -> Result<usize, Error> {
57        self.metadata
58            .column_names
59            .get(idx)
60            .ok_or_else(|| Error::from("ColumnNotFound=".to_string() + idx))
61            .map(|v| *v)
62    }
63}
64
65impl rbdc::db::Row for PgRow {
66    fn meta_data(&self) -> Box<dyn MetaData> {
67        Box::new(PgMetaData {
68            metadata: self.metadata.clone(),
69        })
70    }
71
72    fn get(&mut self, i: usize) -> Result<Value, Error> {
73        match self.try_get(i) {
74            Err(e) => Err(Error::from(format!("get error  index:{},error:{}", i, e))),
75            Ok(v) => Value::decode(v),
76        }
77    }
78}