Skip to content

Commit 594892e

Browse files
committed
Fix missing conversions
Signed-off-by: itowlson <[email protected]>
1 parent 940387f commit 594892e

File tree

1 file changed

+61
-2
lines changed

1 file changed

+61
-2
lines changed

crates/factor-outbound-pg/src/client.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,22 +187,25 @@ fn convert_data_type(pg_type: &Type) -> DbDataType {
187187
Type::INT4 => DbDataType::Int32,
188188
Type::INT8 => DbDataType::Int64,
189189
Type::TEXT | Type::VARCHAR | Type::BPCHAR => DbDataType::Str,
190+
Type::TIMESTAMP | Type::TIMESTAMPTZ => DbDataType::Timestamp,
191+
Type::DATE => DbDataType::Date,
192+
Type::TIME => DbDataType::Time,
190193
_ => {
191194
tracing::debug!("Couldn't convert Postgres type {} to WIT", pg_type.name(),);
192195
DbDataType::Other
193196
}
194197
}
195198
}
196199

197-
fn convert_row(row: &Row) -> Result<Vec<DbValue>, tokio_postgres::Error> {
200+
fn convert_row(row: &Row) -> anyhow::Result<Vec<DbValue>> {
198201
let mut result = Vec::with_capacity(row.len());
199202
for index in 0..row.len() {
200203
result.push(convert_entry(row, index)?);
201204
}
202205
Ok(result)
203206
}
204207

205-
fn convert_entry(row: &Row, index: usize) -> Result<DbValue, tokio_postgres::Error> {
208+
fn convert_entry(row: &Row, index: usize) -> anyhow::Result<DbValue> {
206209
let column = &row.columns()[index];
207210
let value = match column.type_() {
208211
&Type::BOOL => {
@@ -261,6 +264,27 @@ fn convert_entry(row: &Row, index: usize) -> Result<DbValue, tokio_postgres::Err
261264
None => DbValue::DbNull,
262265
}
263266
}
267+
&Type::TIMESTAMP | &Type::TIMESTAMPTZ => {
268+
let value: Option<chrono::NaiveDateTime> = row.try_get(index)?;
269+
match value {
270+
Some(v) => DbValue::Datetime(tuplify_date_time(v)?),
271+
None => DbValue::DbNull,
272+
}
273+
}
274+
&Type::DATE => {
275+
let value: Option<chrono::NaiveDate> = row.try_get(index)?;
276+
match value {
277+
Some(v) => DbValue::Date(tuplify_date(v)?),
278+
None => DbValue::DbNull,
279+
}
280+
}
281+
&Type::TIME => {
282+
let value: Option<chrono::NaiveTime> = row.try_get(index)?;
283+
match value {
284+
Some(v) => DbValue::Time(tuplify_time(v)?),
285+
None => DbValue::DbNull,
286+
}
287+
}
264288
t => {
265289
tracing::debug!(
266290
"Couldn't convert Postgres type {} in column {}",
@@ -273,6 +297,41 @@ fn convert_entry(row: &Row, index: usize) -> Result<DbValue, tokio_postgres::Err
273297
Ok(value)
274298
}
275299

300+
// Functions to convert from the chrono types to the WIT interface tuples
301+
fn tuplify_date_time(
302+
value: chrono::NaiveDateTime,
303+
) -> anyhow::Result<(i32, u8, u8, u8, u8, u8, u32)> {
304+
use chrono::{Datelike, Timelike};
305+
Ok((
306+
value.year(),
307+
value.month().try_into()?,
308+
value.day().try_into()?,
309+
value.hour().try_into()?,
310+
value.minute().try_into()?,
311+
value.second().try_into()?,
312+
value.nanosecond(),
313+
))
314+
}
315+
316+
fn tuplify_date(value: chrono::NaiveDate) -> anyhow::Result<(i32, u8, u8)> {
317+
use chrono::Datelike;
318+
Ok((
319+
value.year(),
320+
value.month().try_into()?,
321+
value.day().try_into()?,
322+
))
323+
}
324+
325+
fn tuplify_time(value: chrono::NaiveTime) -> anyhow::Result<(u8, u8, u8, u32)> {
326+
use chrono::Timelike;
327+
Ok((
328+
value.hour().try_into()?,
329+
value.minute().try_into()?,
330+
value.second().try_into()?,
331+
value.nanosecond(),
332+
))
333+
}
334+
276335
/// Although the Postgres crate converts Rust Option::None to Postgres NULL,
277336
/// it enforces the type of the Option as it does so. (For example, trying to
278337
/// pass an Option::<i32>::None to a VARCHAR column fails conversion.) As we

0 commit comments

Comments
 (0)