subgraph/traits/sqlx/postgres_row/
mod.rs

1use bson::Document;
2use log::{debug, error, trace};
3use sqlx::{postgres::PgRow, Column, Row, TypeInfo};
4
5pub trait FromPostgresRow {
6    fn to_document(&self, field_names: Option<Vec<&str>>)
7        -> Result<Document, async_graphql::Error>;
8}
9
10impl FromPostgresRow for PgRow {
11    fn to_document(
12        &self,
13        field_names: Option<Vec<&str>>,
14    ) -> Result<Document, async_graphql::Error> {
15        debug!("Converting Postgres Row to Document");
16        let mut document = Document::new();
17
18        for column in self.columns() {
19            let column_name = column.name();
20
21            if let Some(field_names) = &field_names {
22                if !field_names.contains(&column_name) {
23                    continue;
24                }
25            }
26
27            let column_type = column.type_info().name();
28
29            match column_type {
30                "VARCHAR" => {
31                    let value: Option<&str> = self.try_get(column_name)?;
32                    document.insert(column_name, value);
33                }
34                "CHAR" => {
35                    let value: Option<&str> = self.try_get(column_name)?;
36                    document.insert(column_name, value);
37                }
38                "TEXT" => {
39                    let value: Option<&str> = self.try_get(column_name)?;
40                    document.insert(column_name, value);
41                }
42                "DATETIME" => {
43                    let value: Option<&str> = self.try_get(column_name)?;
44                    document.insert(column_name, value);
45                }
46                "TIMESTAMP" => {
47                    let value: Option<&str> = self.try_get(column_name)?;
48                    document.insert(column_name, value);
49                }
50                "BIGINT" => {
51                    let value: Option<i64> = self.try_get(column_name)?;
52                    document.insert(column_name, value);
53                }
54                "UUID" => {
55                    let value: Option<uuid::Uuid> = self.try_get(column_name)?;
56                    if let Some(value) = value {
57                        document.insert(column_name, value.to_string());
58                    }
59                }
60                "BOOL" => {
61                    let value: Option<bool> = self.try_get(column_name)?;
62                    document.insert(column_name, value);
63                }
64
65                _ => {
66                    error!("Unsupported Column Type: {}", column_type);
67                    return Err(async_graphql::Error::new(format!(
68                        "Unsupported Column Type: {}",
69                        column_type
70                    )));
71                }
72            }
73        }
74
75        trace!("{:?}", document);
76
77        Ok(document)
78    }
79}