graphile_worker_database 0.1.5

Database driver abstraction for graphile_worker
Documentation
use std::collections::HashMap;

use chrono::{DateTime, Utc};
use serde_json::Value;
use sqlx::postgres::PgRow;
use sqlx::{Column, Row, TypeInfo};

use crate::{DbCell, DbError, DbRow};

pub(super) fn sqlx_row_to_db_row(row: PgRow) -> Result<DbRow, DbError> {
    let mut cells = HashMap::with_capacity(row.columns().len());

    for (index, column) in row.columns().iter().enumerate() {
        let name = column.name().to_string();
        let type_name = column.type_info().name();
        let cell = match type_name {
            "BOOL" => row
                .try_get::<Option<bool>, _>(index)?
                .map(DbCell::Bool)
                .unwrap_or(DbCell::Null),
            "INT2" => row
                .try_get::<Option<i16>, _>(index)?
                .map(DbCell::I16)
                .unwrap_or(DbCell::Null),
            "INT4" => row
                .try_get::<Option<i32>, _>(index)?
                .map(DbCell::I32)
                .unwrap_or(DbCell::Null),
            "INT8" => row
                .try_get::<Option<i64>, _>(index)?
                .map(DbCell::I64)
                .unwrap_or(DbCell::Null),
            "JSON" | "JSONB" => row
                .try_get::<Option<Value>, _>(index)?
                .map(DbCell::Json)
                .unwrap_or(DbCell::Null),
            "TEXT" | "VARCHAR" | "BPCHAR" | "NAME" => row
                .try_get::<Option<String>, _>(index)?
                .map(DbCell::Text)
                .unwrap_or(DbCell::Null),
            "TIMESTAMPTZ" => row
                .try_get::<Option<DateTime<Utc>>, _>(index)?
                .map(DbCell::TimestampTz)
                .unwrap_or(DbCell::Null),
            other => {
                return Err(DbError::new(format!(
                    "unsupported PostgreSQL result type `{other}` for column `{name}`"
                )));
            }
        };
        cells.insert(name, cell);
    }

    Ok(DbRow::new(cells))
}