sea-orm-spanner 0.1.0

Google Cloud Spanner backend for SeaORM
Documentation
use gcloud_spanner::row::Row as SpannerRow;
use sea_orm::{DbErr, TryGetError};

pub struct SpannerQueryResult {
    row: SpannerRow,
}

impl SpannerQueryResult {
    pub fn new(row: SpannerRow) -> Self {
        Self { row }
    }

    pub fn try_get_by_name<T>(&self, col: &str) -> Result<T, TryGetError>
    where
        T: SpannerTryGet,
    {
        T::try_get_spanner_by_name(&self.row, col)
    }

    pub fn try_get_by_index<T>(&self, idx: usize) -> Result<T, TryGetError>
    where
        T: SpannerTryGet,
    {
        T::try_get_spanner(&self.row, idx)
    }
}

pub trait SpannerTryGet: Sized {
    fn try_get_spanner(row: &SpannerRow, idx: usize) -> Result<Self, TryGetError>;
    fn try_get_spanner_by_name(row: &SpannerRow, name: &str) -> Result<Self, TryGetError>;
}

macro_rules! impl_spanner_try_get {
    ($ty:ty) => {
        impl SpannerTryGet for $ty {
            fn try_get_spanner(row: &SpannerRow, idx: usize) -> Result<Self, TryGetError> {
                row.column::<$ty>(idx)
                    .map_err(|e| TryGetError::DbErr(DbErr::Type(e.to_string())))
            }
            fn try_get_spanner_by_name(row: &SpannerRow, name: &str) -> Result<Self, TryGetError> {
                row.column_by_name::<$ty>(name)
                    .map_err(|e| TryGetError::DbErr(DbErr::Type(e.to_string())))
            }
        }
    };
    ($ty:ty, $spanner_ty:ty) => {
        impl SpannerTryGet for $ty {
            fn try_get_spanner(row: &SpannerRow, idx: usize) -> Result<Self, TryGetError> {
                row.column::<$spanner_ty>(idx)
                    .map(|v| v as $ty)
                    .map_err(|e| TryGetError::DbErr(DbErr::Type(e.to_string())))
            }
            fn try_get_spanner_by_name(row: &SpannerRow, name: &str) -> Result<Self, TryGetError> {
                row.column_by_name::<$spanner_ty>(name)
                    .map(|v| v as $ty)
                    .map_err(|e| TryGetError::DbErr(DbErr::Type(e.to_string())))
            }
        }
    };
}

impl_spanner_try_get!(String);
impl_spanner_try_get!(i64);
impl_spanner_try_get!(i32, i64);
impl_spanner_try_get!(i16, i64);
impl_spanner_try_get!(i8, i64);
impl_spanner_try_get!(f64);
impl_spanner_try_get!(f32, f64);
impl_spanner_try_get!(bool);
impl_spanner_try_get!(Vec<u8>);

impl<T: SpannerTryGet> SpannerTryGet for Option<T> {
    fn try_get_spanner(row: &SpannerRow, idx: usize) -> Result<Self, TryGetError> {
        match T::try_get_spanner(row, idx) {
            Ok(v) => Ok(Some(v)),
            Err(TryGetError::Null(_)) => Ok(None),
            Err(e) => Err(e),
        }
    }
    fn try_get_spanner_by_name(row: &SpannerRow, name: &str) -> Result<Self, TryGetError> {
        match T::try_get_spanner_by_name(row, name) {
            Ok(v) => Ok(Some(v)),
            Err(TryGetError::Null(_)) => Ok(None),
            Err(e) => Err(e),
        }
    }
}