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 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 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 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 "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