rssql/
postgresql.rs

1use anyhow;
2use sqlx::postgres::types::{PgInterval, PgMoney, PgRange, PgTimeTz, PgLTree, PgLQuery};
3use sqlx::types::chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime};
4use sqlx::types::ipnetwork::IpNetwork;
5use sqlx::types::mac_address::MacAddress;
6use sqlx::types::{BigDecimal, BitVec, JsonValue, Uuid};
7use sqlx::{Column, Row, TypeInfo};
8use sqlx::postgres::PgRow;
9use std::collections::HashMap;
10use std::fmt;
11
12use crate::SQLDataTypes;
13use crate::SQLRets;
14use crate::UNKNOWN;
15use crate::BINARY;
16
17
18static PGINTERVAL: &str = "[pginterval]";
19static PGMONEY: &str = "[pgmoney]";
20static PGTIMETZ: &str = "[pgtimetz]";
21
22#[derive(Debug, Clone)]
23pub enum PostgreSQLDataTypes {
24    /// From https://docs.rs/sqlx-postgres/0.7.0/sqlx_postgres/types/index.html
25    Bool(bool),
26    I8(i8),
27    I16(i16),
28    I32(i32),
29    I64(i64),
30    U8(u8),
31    U16(u16),
32    U64(u64),
33    F32(f32),
34    F64(f64),
35    String(String),
36    Binary(Vec<u8>),
37    Void(()),
38    // not impl Display
39    PgInterval(PgInterval),
40    PgRangeBigDecimal(PgRange<BigDecimal>),
41    PgRangeDateTime(PgRange<DateTime<chrono::Utc>>),
42    PgRangeNaiveDate(PgRange<NaiveDate>),
43    PgRangeNaiveDateTime(PgRange<NaiveDateTime>),
44    PgRangeI32(PgRange<i32>),
45    PgRangeI64(PgRange<i64>),
46    PgMoney(PgMoney),
47    PgLTree(PgLTree),
48    PgLQuery(PgLQuery),
49    BigDecimal(BigDecimal),
50    DateTime(DateTime<chrono::Utc>),
51    NaiveDateTime(NaiveDateTime),
52    NaiveDate(NaiveDate),
53    NaiveTime(NaiveTime),
54    PgTimeTz(PgTimeTz),
55    Uuid(Uuid),
56    IpNetwork(IpNetwork),
57    MacAddress(MacAddress),
58    BitVec(BitVec),
59    JsonValue(JsonValue),
60}
61
62impl fmt::Display for PostgreSQLDataTypes {
63    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64        match self {
65            PostgreSQLDataTypes::Bool(v) => write!(f, "{}", v),
66            PostgreSQLDataTypes::I8(v) => write!(f, "{}", v),
67            PostgreSQLDataTypes::I16(v) => write!(f, "{}", v),
68            PostgreSQLDataTypes::I32(v) => write!(f, "{}", v),
69            PostgreSQLDataTypes::I64(v) => write!(f, "{}", v),
70            PostgreSQLDataTypes::U8(v) => write!(f, "{}", v),
71            PostgreSQLDataTypes::U16(v) => write!(f, "{}", v),
72            PostgreSQLDataTypes::U64(v) => write!(f, "{}", v),
73            PostgreSQLDataTypes::F32(v) => write!(f, "{}", v),
74            PostgreSQLDataTypes::F64(v) => write!(f, "{}", v),
75            PostgreSQLDataTypes::String(v) => write!(f, "{}", v),
76            PostgreSQLDataTypes::Binary(_) => write!(f, "{}", BINARY),
77            PostgreSQLDataTypes::Void(_) => write!(f, "()"),
78            PostgreSQLDataTypes::PgInterval(_) => write!(f, "{}", PGINTERVAL),
79            PostgreSQLDataTypes::PgRangeBigDecimal(v) => write!(f, "{}", v),
80            PostgreSQLDataTypes::PgRangeDateTime(v) => write!(f, "{}", v),
81            PostgreSQLDataTypes::PgRangeNaiveDate(v) => write!(f, "{}", v),
82            PostgreSQLDataTypes::PgRangeNaiveDateTime(v) => write!(f, "{}", v),
83            PostgreSQLDataTypes::PgRangeI32(v) => write!(f, "{}", v),
84            PostgreSQLDataTypes::PgRangeI64(v) => write!(f, "{}", v),
85            PostgreSQLDataTypes::PgMoney(_) => write!(f, "{}", PGMONEY),
86            PostgreSQLDataTypes::PgLTree(v) => write!(f, "{}", v),
87            PostgreSQLDataTypes::PgLQuery(v) => write!(f, "{}", v),
88            PostgreSQLDataTypes::BigDecimal(v) => write!(f, "{}", v),
89            PostgreSQLDataTypes::DateTime(v) => write!(f, "{}", v),
90            PostgreSQLDataTypes::NaiveDateTime(v) => write!(f, "{}", v),
91            PostgreSQLDataTypes::NaiveDate(v) => write!(f, "{}", v),
92            PostgreSQLDataTypes::NaiveTime(v) => write!(f, "{}", v),
93            PostgreSQLDataTypes::PgTimeTz(_) => write!(f, "{}", PGTIMETZ),
94            PostgreSQLDataTypes::Uuid(v) => write!(f, "{}", v),
95            PostgreSQLDataTypes::IpNetwork(v) => write!(f, "{}", v),
96            PostgreSQLDataTypes::MacAddress(v) => write!(f, "{}", v),
97            PostgreSQLDataTypes::BitVec(_) => write!(f, "{}", BINARY),
98            PostgreSQLDataTypes::JsonValue(v) => write!(f, "{}", v),
99        }
100    }
101}
102
103pub async fn rows_process(rows: Vec<PgRow>) -> anyhow::Result<SQLRets> {
104    let mut sql_rets = SQLRets::new();
105
106    if rows.len() > 0 {
107        // push all column
108        let pg_row = &rows[0];
109        let mysql_row_len = pg_row.len();
110        for i in 0..mysql_row_len {
111            let col = pg_row.column(i);
112            let col_name = col.name().to_string();
113            sql_rets.push_column_name(&col_name);
114        }
115    }
116
117    for pg_row in &rows {
118        let mut sql_row: HashMap<String, SQLDataTypes> = HashMap::new();
119        let pg_row_len = pg_row.len();
120        for i in 0..pg_row_len {
121            let col = pg_row.column(i);
122            let col_name = col.name().to_string();
123            let type_info = col.type_info();
124            let postgresql_value = match type_info.name() {
125                "BOOL" => {
126                    let value: bool = pg_row.get(i);
127                    PostgreSQLDataTypes::Bool(value)
128                }
129                "CHAR" => {
130                    let value: i8 = pg_row.get(i);
131                    PostgreSQLDataTypes::I8(value)
132                }
133                "SMALLINT" | "SMALLSERIAL" | "INT2" => {
134                    let value: i16 = pg_row.get(i);
135                    PostgreSQLDataTypes::I16(value)
136                }
137                "INT" | "SERIAL" | "INT4" => {
138                    let value: i32 = pg_row.get(i);
139                    PostgreSQLDataTypes::I32(value)
140                }
141                "BIGINT" | "BIGSERIAL" | "INT8" => {
142                    let value: i64 = pg_row.get(i);
143                    PostgreSQLDataTypes::I64(value)
144                }
145                "REAL" | "FLOAT4" => {
146                    let value: f32 = pg_row.get(i);
147                    PostgreSQLDataTypes::F32(value)
148                }
149                "DOUBLE PRECISION" | "FLOAT8" => {
150                    let value: f64 = pg_row.get(i);
151                    PostgreSQLDataTypes::F64(value)
152                }
153                "VARCHAR" | "CHAR(N)" | "TEXT" | "NAME" => {
154                    let value: String = pg_row.get(i);
155                    PostgreSQLDataTypes::String(value)
156                }
157                "BYTEA" => {
158                    let value: Vec<u8> = pg_row.get(i);
159                    PostgreSQLDataTypes::Binary(value)
160                }
161                "VOID" => {
162                    let value = ();
163                    PostgreSQLDataTypes::Void(value)
164                }
165                "INTERVAL" => {
166                    let value: PgInterval = pg_row.get(i);
167                    PostgreSQLDataTypes::PgInterval(value)
168                }
169                "NUMRANGE" => {
170                    let value: PgRange<BigDecimal> = pg_row.get(i);
171                    PostgreSQLDataTypes::PgRangeBigDecimal(value)
172                }
173                "DATERANGE" => {
174                    let value: PgRange<NaiveDate> = pg_row.get(i);
175                    PostgreSQLDataTypes::PgRangeNaiveDate(value)
176                }
177                "TSTZRANGE" => {
178                    let value: PgRange<DateTime<chrono::Utc>> = pg_row.get(i);
179                    PostgreSQLDataTypes::PgRangeDateTime(value)
180                }
181                "TSRANGE" => {
182                    let value: PgRange<NaiveDateTime> = pg_row.get(i);
183                    PostgreSQLDataTypes::PgRangeNaiveDateTime(value)
184                }
185                "INT4RANGE" => {
186                    let value: PgRange<i32> = pg_row.get(i);
187                    PostgreSQLDataTypes::PgRangeI32(value)
188                }
189                "INT8RANGE" => {
190                    let value: PgRange<i64> = pg_row.get(i);
191                    PostgreSQLDataTypes::PgRangeI64(value)
192                }
193                // "INT8RANGE" | "INT4RANGE" | "TSRANGE" | "TSTZRANGE" | "DATERANGE" | "NUMRANGE" => {
194                //     let value: PgRange<i64> = pg_row.get(i);
195                //     PostgreSQLDataType::PgRange(value)
196                // }
197                "MONEY" => {
198                    let value: PgMoney = pg_row.get(i);
199                    PostgreSQLDataTypes::PgMoney(value)
200                }
201                "LTREE" => {
202                    let value: PgLTree = pg_row.get(i);
203                    PostgreSQLDataTypes::PgLTree(value)
204                }
205                "LQUERY" => {
206                    let value: PgLQuery = pg_row.get(i);
207                    PostgreSQLDataTypes::PgLQuery(value)
208                }
209                "NUMERIC" => {
210                    let value: BigDecimal = pg_row.get(i);
211                    PostgreSQLDataTypes::BigDecimal(value)
212                }
213                "TIMESTAMPTZ" => {
214                    let value: DateTime<chrono::Utc> = pg_row.get(i);
215                    PostgreSQLDataTypes::DateTime(value)
216                }
217                "TIMESTAMP" => {
218                    let value: NaiveDateTime = pg_row.get(i);
219                    PostgreSQLDataTypes::NaiveDateTime(value)
220                }
221                "DATE" => {
222                    let value: NaiveDate = pg_row.get(i);
223                    PostgreSQLDataTypes::NaiveDate(value)
224                }
225                "TIME" => {
226                    let value: NaiveTime = pg_row.get(i);
227                    PostgreSQLDataTypes::NaiveTime(value)
228                }
229                "TIMETZ" => {
230                    let value: PgTimeTz = pg_row.get(i);
231                    PostgreSQLDataTypes::PgTimeTz(value)
232                }
233                "UUID" => {
234                    let value: Uuid = pg_row.get(i);
235                    PostgreSQLDataTypes::Uuid(value)
236                }
237                "INET" | "CIDR" => {
238                    let value: IpNetwork = pg_row.get(i);
239                    PostgreSQLDataTypes::IpNetwork(value)
240                }
241                "MACADDR" => {
242                    let value: MacAddress = pg_row.get(i);
243                    PostgreSQLDataTypes::MacAddress(value)
244                }
245                "BIT" | "VARBIT" => {
246                    let value: BitVec = pg_row.get(i);
247                    PostgreSQLDataTypes::BitVec(value)
248                }
249                "JSON" | "JSONB" => {
250                    let value: JsonValue = pg_row.get(i);
251                    PostgreSQLDataTypes::JsonValue(value)
252                }
253                _ => {
254                    PostgreSQLDataTypes::String(UNKNOWN.into())
255                }
256            };
257            let sql_value = SQLDataTypes::PostgreSQLDataTypes(postgresql_value);
258            sql_row.insert(col_name, sql_value);
259        }
260        sql_rets.push_rets(sql_row);
261    }
262    Ok(sql_rets)
263}
264
265