include column name in TryGetError::Null (#853)

* include column name in TryGetError::Null

* remove prefix
This commit is contained in:
kyoto7250 2022-07-12 00:16:03 +09:00 committed by GitHub
parent c5aa63e282
commit 23ac958142
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -33,14 +33,16 @@ pub enum TryGetError {
/// A database error was encountered as defined in [crate::DbErr] /// A database error was encountered as defined in [crate::DbErr]
DbErr(DbErr), DbErr(DbErr),
/// A null value was encountered /// A null value was encountered
Null, Null(String),
} }
impl From<TryGetError> for DbErr { impl From<TryGetError> for DbErr {
fn from(e: TryGetError) -> DbErr { fn from(e: TryGetError) -> DbErr {
match e { match e {
TryGetError::DbErr(e) => e, TryGetError::DbErr(e) => e,
TryGetError::Null => DbErr::Query("error occurred while decoding: Null".to_owned()), TryGetError::Null(s) => DbErr::Query(
format!("error occurred while decoding {}: Null", s)
),
} }
} }
} }
@ -89,7 +91,7 @@ impl<T: TryGetable> TryGetable for Option<T> {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> { fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
match T::try_get(res, pre, col) { match T::try_get(res, pre, col) {
Ok(v) => Ok(Some(v)), Ok(v) => Ok(Some(v)),
Err(TryGetError::Null) => Ok(None), Err(TryGetError::Null(_)) => Ok(None),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@ -107,27 +109,27 @@ macro_rules! try_getable_all {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<$type>, _>(column.as_str()) row.try_get::<Option<$type>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(row) => { QueryResultRow::SqlxPostgres(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<$type>, _>(column.as_str()) row.try_get::<Option<$type>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-sqlite")] #[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(row) => { QueryResultRow::SqlxSqlite(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<$type>, _>(column.as_str()) row.try_get::<Option<$type>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
#[allow(unused_variables)] #[allow(unused_variables)]
QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
TryGetError::Null TryGetError::Null(column)
}), }),
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
_ => unreachable!(), _ => unreachable!(),
@ -141,14 +143,15 @@ macro_rules! try_getable_unsigned {
( $type: ty ) => { ( $type: ty ) => {
impl TryGetable for $type { impl TryGetable for $type {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> { fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
let _column = format!("{}{}", pre, col); #[allow(unused_variables)]
let column = format!("{}{}", pre, col);
match &res.row { match &res.row {
#[cfg(feature = "sqlx-mysql")] #[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(row) => { QueryResultRow::SqlxMySql(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<$type>, _>(_column.as_str()) row.try_get::<Option<$type>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(_) => { QueryResultRow::SqlxPostgres(_) => {
@ -157,15 +160,15 @@ macro_rules! try_getable_unsigned {
#[cfg(feature = "sqlx-sqlite")] #[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(row) => { QueryResultRow::SqlxSqlite(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<$type>, _>(_column.as_str()) row.try_get::<Option<$type>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
#[allow(unused_variables)] #[allow(unused_variables)]
QueryResultRow::Mock(row) => row.try_get(_column.as_str()).map_err(|e| { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
TryGetError::Null TryGetError::Null(column)
}), }),
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
_ => unreachable!(), _ => unreachable!(),
@ -179,14 +182,15 @@ macro_rules! try_getable_mysql {
( $type: ty ) => { ( $type: ty ) => {
impl TryGetable for $type { impl TryGetable for $type {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> { fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
let _column = format!("{}{}", pre, col); #[allow(unused_variables)]
let column = format!("{}{}", pre, col);
match &res.row { match &res.row {
#[cfg(feature = "sqlx-mysql")] #[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(row) => { QueryResultRow::SqlxMySql(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<$type>, _>(_column.as_str()) row.try_get::<Option<$type>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(_) => { QueryResultRow::SqlxPostgres(_) => {
@ -198,9 +202,9 @@ macro_rules! try_getable_mysql {
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
#[allow(unused_variables)] #[allow(unused_variables)]
QueryResultRow::Mock(row) => row.try_get(_column.as_str()).map_err(|e| { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
TryGetError::Null TryGetError::Null(column)
}), }),
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
_ => unreachable!(), _ => unreachable!(),
@ -215,38 +219,39 @@ macro_rules! try_getable_date_time {
( $type: ty ) => { ( $type: ty ) => {
impl TryGetable for $type { impl TryGetable for $type {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> { fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
let _column = format!("{}{}", pre, col); #[allow(unused_variables)]
let column = format!("{}{}", pre, col);
match &res.row { match &res.row {
#[cfg(feature = "sqlx-mysql")] #[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(row) => { QueryResultRow::SqlxMySql(row) => {
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<DateTime<Utc>>, _>(_column.as_str()) row.try_get::<Option<DateTime<Utc>>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
.map(|v| v.into()) .map(|v| v.into())
} }
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(row) => { QueryResultRow::SqlxPostgres(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<$type>, _>(_column.as_str()) row.try_get::<Option<$type>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-sqlite")] #[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(row) => { QueryResultRow::SqlxSqlite(row) => {
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<DateTime<Utc>>, _>(_column.as_str()) row.try_get::<Option<DateTime<Utc>>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
.map(|v| v.into()) .map(|v| v.into())
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
#[allow(unused_variables)] #[allow(unused_variables)]
QueryResultRow::Mock(row) => row.try_get(_column.as_str()).map_err(|e| { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
TryGetError::Null TryGetError::Null(column)
}), }),
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
_ => unreachable!(), _ => unreachable!(),
@ -269,14 +274,14 @@ macro_rules! try_getable_time {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<$type>, _>(column.as_str()) row.try_get::<Option<$type>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(row) => { QueryResultRow::SqlxPostgres(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<$type>, _>(column.as_str()) row.try_get::<Option<$type>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-sqlite")] #[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(_) => { QueryResultRow::SqlxSqlite(_) => {
@ -286,7 +291,7 @@ macro_rules! try_getable_time {
#[allow(unused_variables)] #[allow(unused_variables)]
QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
TryGetError::Null TryGetError::Null(column)
}), }),
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
_ => unreachable!(), _ => unreachable!(),
@ -356,14 +361,14 @@ impl TryGetable for Decimal {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<Decimal>, _>(column.as_str()) row.try_get::<Option<Decimal>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(row) => { QueryResultRow::SqlxPostgres(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<Decimal>, _>(column.as_str()) row.try_get::<Option<Decimal>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-sqlite")] #[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(row) => { QueryResultRow::SqlxSqlite(row) => {
@ -378,14 +383,14 @@ impl TryGetable for Decimal {
"Failed to convert f64 into Decimal".to_owned(), "Failed to convert f64 into Decimal".to_owned(),
)) ))
}), }),
None => Err(TryGetError::Null), None => Err(TryGetError::Null(column)),
} }
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
#[allow(unused_variables)] #[allow(unused_variables)]
QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
TryGetError::Null TryGetError::Null(column)
}), }),
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
_ => unreachable!(), _ => unreachable!(),
@ -398,14 +403,15 @@ try_getable_all!(uuid::Uuid);
impl TryGetable for u32 { impl TryGetable for u32 {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> { fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
let _column = format!("{}{}", pre, col); #[allow(unused_variables)]
let column = format!("{}{}", pre, col);
match &res.row { match &res.row {
#[cfg(feature = "sqlx-mysql")] #[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(row) => { QueryResultRow::SqlxMySql(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<u32>, _>(_column.as_str()) row.try_get::<Option<u32>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(row) => { QueryResultRow::SqlxPostgres(row) => {
@ -413,23 +419,23 @@ impl TryGetable for u32 {
// Since 0.6.0, SQLx has dropped direct mapping from PostgreSQL's OID to Rust's `u32`; // Since 0.6.0, SQLx has dropped direct mapping from PostgreSQL's OID to Rust's `u32`;
// Instead, `u32` was wrapped by a `sqlx::Oid`. // Instead, `u32` was wrapped by a `sqlx::Oid`.
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<Oid>, _>(_column.as_str()) row.try_get::<Option<Oid>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
.map(|oid| oid.0) .map(|oid| oid.0)
} }
#[cfg(feature = "sqlx-sqlite")] #[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(row) => { QueryResultRow::SqlxSqlite(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<u32>, _>(_column.as_str()) row.try_get::<Option<u32>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
#[allow(unused_variables)] #[allow(unused_variables)]
QueryResultRow::Mock(row) => row.try_get(_column.as_str()).map_err(|e| { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
TryGetError::Null TryGetError::Null(column)
}), }),
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
_ => unreachable!(), _ => unreachable!(),
@ -648,28 +654,28 @@ where
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<serde_json::Value>, _>(column.as_str()) row.try_get::<Option<serde_json::Value>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(row) => { QueryResultRow::SqlxPostgres(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<serde_json::Value>, _>(column.as_str()) row.try_get::<Option<serde_json::Value>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "sqlx-sqlite")] #[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(row) => { QueryResultRow::SqlxSqlite(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get::<Option<serde_json::Value>, _>(column.as_str()) row.try_get::<Option<serde_json::Value>, _>(column.as_str())
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e))) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null)) .and_then(|opt| opt.ok_or(TryGetError::Null(column)))
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
QueryResultRow::Mock(row) => { QueryResultRow::Mock(row) => {
row.try_get::<serde_json::Value>(column.as_str()) row.try_get::<serde_json::Value>(column.as_str())
.map_err(|e| { .map_err(|e| {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
TryGetError::Null TryGetError::Null(column)
}) })
} }
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
@ -813,3 +819,22 @@ try_from_u64_err!(rust_decimal::Decimal);
#[cfg(feature = "with-uuid")] #[cfg(feature = "with-uuid")]
try_from_u64_err!(uuid::Uuid); try_from_u64_err!(uuid::Uuid);
#[cfg(test)]
mod tests {
use super::{TryGetError};
use crate::error::DbErr;
#[test]
fn from_try_get_error() {
// TryGetError::DbErr
let expected = DbErr::Query("expected error message".to_owned());
let try_get_error = TryGetError::DbErr(expected.clone());
assert_eq!(DbErr::from(try_get_error), expected);
// TryGetError::Null
let try_get_error = TryGetError::Null("column".to_owned());
let expected = "error occurred while decoding column: Null".to_owned();
assert_eq!(DbErr::from(try_get_error), DbErr::Query(expected));
}
}