Merge branch 'master' into ss/rocket-example

This commit is contained in:
Billy Chan 2021-08-30 18:43:28 +08:00 committed by GitHub
commit 3b21b999a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 203 deletions

View File

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/) The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## 0.1.3 - 2021-08-30
- [[#108]] Remove impl TryGetable for Option<T>
[#108]: https://github.com/SeaQL/sea-orm/issues/108
## 0.1.2 - 2021-08-23 ## 0.1.2 - 2021-08-23
- [[#68]] Added `DateTimeWithTimeZone` as supported attribute type - [[#68]] Added `DateTimeWithTimeZone` as supported attribute type

View File

@ -3,7 +3,7 @@ members = [".", "sea-orm-macros", "sea-orm-codegen"]
[package] [package]
name = "sea-orm" name = "sea-orm"
version = "0.1.2" version = "0.1.3"
authors = ["Chris Tsang <tyt2y7@gmail.com>"] authors = ["Chris Tsang <tyt2y7@gmail.com>"]
edition = "2018" edition = "2018"
description = "🐚 An async & dynamic ORM for Rust" description = "🐚 An async & dynamic ORM for Rust"

View File

@ -17,8 +17,22 @@ pub(crate) enum QueryResultRow {
Mock(crate::MockRow), Mock(crate::MockRow),
} }
pub enum TryGetError {
DbErr(DbErr),
Null,
}
impl From<TryGetError> for DbErr {
fn from(e: TryGetError) -> DbErr {
match e {
TryGetError::DbErr(e) => e,
TryGetError::Null => DbErr::Query("error occurred while decoding: Null".to_owned()),
}
}
}
pub trait TryGetable { pub trait TryGetable {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, DbErr> fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError>
where where
Self: Sized; Self: Sized;
} }
@ -30,7 +44,7 @@ impl QueryResult {
where where
T: TryGetable, T: TryGetable,
{ {
T::try_get(self, pre, col) Ok(T::try_get(self, pre, col)?)
} }
} }
@ -51,66 +65,48 @@ impl fmt::Debug for QueryResultRow {
// TryGetable // // TryGetable //
macro_rules! try_getable_all { impl<T: TryGetable> TryGetable for Option<T> {
( $type: ty ) => { fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
impl TryGetable for $type { match T::try_get(res, pre, col) {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, DbErr> { Ok(v) => Ok(Some(v)),
let column = format!("{}{}", pre, col); Err(TryGetError::Null) => Ok(None),
match &res.row { Err(e) => Err(e),
#[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(row) => {
use sqlx::Row;
row.try_get(column.as_str())
.map_err(crate::sqlx_error_to_query_err)
}
#[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(row) => {
use sqlx::Row;
row.try_get(column.as_str())
.map_err(crate::sqlx_error_to_query_err)
}
#[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(row) => {
use sqlx::Row;
row.try_get(column.as_str())
.map_err(crate::sqlx_error_to_query_err)
}
#[cfg(feature = "mock")]
QueryResultRow::Mock(row) => Ok(row.try_get(column.as_str())?),
} }
} }
} }
impl TryGetable for Option<$type> { macro_rules! try_getable_all {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, DbErr> { ( $type: ty ) => {
impl TryGetable for $type {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
let column = format!("{}{}", pre, col); 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(crate::sqlx_error_to_query_err) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null))
} }
#[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(crate::sqlx_error_to_query_err) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null))
} }
#[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(crate::sqlx_error_to_query_err) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null))
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
QueryResultRow::Mock(row) => match row.try_get(column.as_str()) { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
Ok(v) => Ok(Some(v)),
Err(e) => {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
Ok(None) TryGetError::Null
} }),
},
} }
} }
} }
@ -120,40 +116,15 @@ macro_rules! try_getable_all {
macro_rules! try_getable_unsigned { 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, DbErr> { fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
let column = format!("{}{}", pre, col);
match &res.row {
#[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(row) => {
use sqlx::Row;
row.try_get(column.as_str())
.map_err(crate::sqlx_error_to_query_err)
}
#[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(_) => {
panic!("{} unsupported by sqlx-postgres", stringify!($type))
}
#[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(row) => {
use sqlx::Row;
row.try_get(column.as_str())
.map_err(crate::sqlx_error_to_query_err)
}
#[cfg(feature = "mock")]
QueryResultRow::Mock(row) => Ok(row.try_get(column.as_str())?),
}
}
}
impl TryGetable for Option<$type> {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, DbErr> {
let column = format!("{}{}", pre, col); 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(crate::sqlx_error_to_query_err) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null))
} }
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(_) => { QueryResultRow::SqlxPostgres(_) => {
@ -163,16 +134,14 @@ macro_rules! try_getable_unsigned {
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(crate::sqlx_error_to_query_err) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null))
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
QueryResultRow::Mock(row) => match row.try_get(column.as_str()) { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
Ok(v) => Ok(Some(v)),
Err(e) => {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
Ok(None) TryGetError::Null
} }),
},
} }
} }
} }
@ -182,38 +151,15 @@ macro_rules! try_getable_unsigned {
macro_rules! try_getable_mysql { 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, DbErr> { fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
let column = format!("{}{}", pre, col);
match &res.row {
#[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(row) => {
use sqlx::Row;
row.try_get(column.as_str())
.map_err(crate::sqlx_error_to_query_err)
}
#[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(_) => {
panic!("{} unsupported by sqlx-postgres", stringify!($type))
}
#[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(_) => {
panic!("{} unsupported by sqlx-sqlite", stringify!($type))
}
#[cfg(feature = "mock")]
QueryResultRow::Mock(row) => Ok(row.try_get(column.as_str())?),
}
}
}
impl TryGetable for Option<$type> {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, DbErr> {
let column = format!("{}{}", pre, col); 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(crate::sqlx_error_to_query_err) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null))
} }
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(_) => { QueryResultRow::SqlxPostgres(_) => {
@ -224,13 +170,10 @@ macro_rules! try_getable_mysql {
panic!("{} unsupported by sqlx-sqlite", stringify!($type)) panic!("{} unsupported by sqlx-sqlite", stringify!($type))
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
QueryResultRow::Mock(row) => match row.try_get(column.as_str()) { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
Ok(v) => Ok(Some(v)),
Err(e) => {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
Ok(None) TryGetError::Null
} }),
},
} }
} }
} }
@ -240,31 +183,7 @@ macro_rules! try_getable_mysql {
macro_rules! try_getable_postgres { macro_rules! try_getable_postgres {
( $type: ty ) => { ( $type: ty ) => {
impl TryGetable for $type { impl TryGetable for $type {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, DbErr> { fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
let column = format!("{}{}", pre, col);
match &res.row {
#[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(_) => {
panic!("{} unsupported by sqlx-mysql", stringify!($type))
}
#[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(row) => {
use sqlx::Row;
row.try_get(column.as_str())
.map_err(crate::sqlx_error_to_query_err)
}
#[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(_) => {
panic!("{} unsupported by sqlx-sqlite", stringify!($type))
}
#[cfg(feature = "mock")]
QueryResultRow::Mock(row) => Ok(row.try_get(column.as_str())?),
}
}
}
impl TryGetable for Option<$type> {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, DbErr> {
let column = format!("{}{}", pre, col); let column = format!("{}{}", pre, col);
match &res.row { match &res.row {
#[cfg(feature = "sqlx-mysql")] #[cfg(feature = "sqlx-mysql")]
@ -275,20 +194,18 @@ macro_rules! try_getable_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(crate::sqlx_error_to_query_err) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null))
} }
#[cfg(feature = "sqlx-sqlite")] #[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(_) => { QueryResultRow::SqlxSqlite(_) => {
panic!("{} unsupported by sqlx-sqlite", stringify!($type)) panic!("{} unsupported by sqlx-sqlite", stringify!($type))
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
QueryResultRow::Mock(row) => match row.try_get(column.as_str()) { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
Ok(v) => Ok(Some(v)),
Err(e) => {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
Ok(None) TryGetError::Null
} }),
},
} }
} }
} }
@ -322,83 +239,41 @@ use rust_decimal::Decimal;
#[cfg(feature = "with-rust_decimal")] #[cfg(feature = "with-rust_decimal")]
impl TryGetable for Decimal { impl TryGetable for Decimal {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, DbErr> { fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
let column = format!("{}{}", pre, col); 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(column.as_str()) row.try_get::<Option<Decimal>, _>(column.as_str())
.map_err(crate::sqlx_error_to_query_err) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null))
} }
#[cfg(feature = "sqlx-postgres")] #[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(row) => { QueryResultRow::SqlxPostgres(row) => {
use sqlx::Row; use sqlx::Row;
row.try_get(column.as_str()) row.try_get::<Option<Decimal>, _>(column.as_str())
.map_err(crate::sqlx_error_to_query_err) .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
.and_then(|opt| opt.ok_or(TryGetError::Null))
} }
#[cfg(feature = "sqlx-sqlite")] #[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(row) => { QueryResultRow::SqlxSqlite(row) => {
use sqlx::Row; use sqlx::Row;
let val: f64 = row let val: Option<f64> = row
.try_get(column.as_str()) .try_get(column.as_str())
.map_err(crate::sqlx_error_to_query_err)?; .map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))?;
use rust_decimal::prelude::FromPrimitive; use rust_decimal::prelude::FromPrimitive;
Decimal::from_f64(val) match val {
.ok_or_else(|| DbErr::Query("Failed to convert f64 into Decimal".to_owned())) Some(v) => Decimal::from_f64(v)
} .ok_or_else(|| TryGetError::DbErr(DbErr::Query("Failed to convert f64 into Decimal".to_owned()))),
#[cfg(feature = "mock")] None => Err(TryGetError::Null)
QueryResultRow::Mock(row) => Ok(row.try_get(column.as_str())?),
}
}
}
#[cfg(feature = "with-rust_decimal")]
impl TryGetable for Option<Decimal> {
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, DbErr> {
let column = format!("{}{}", pre, col);
match &res.row {
#[cfg(feature = "sqlx-mysql")]
QueryResultRow::SqlxMySql(row) => {
use sqlx::Row;
match row.try_get(column.as_str()) {
Ok(v) => Ok(Some(v)),
Err(e) => {
debug_print!("{:#?}", e.to_string());
Ok(None)
}
}
}
#[cfg(feature = "sqlx-postgres")]
QueryResultRow::SqlxPostgres(row) => {
use sqlx::Row;
match row.try_get(column.as_str()) {
Ok(v) => Ok(Some(v)),
Err(e) => {
debug_print!("{:#?}", e.to_string());
Ok(None)
}
}
}
#[cfg(feature = "sqlx-sqlite")]
QueryResultRow::SqlxSqlite(_) => {
let result: Result<Decimal, _> = TryGetable::try_get(res, pre, col);
match result {
Ok(v) => Ok(Some(v)),
Err(e) => {
debug_print!("{:#?}", e.to_string());
Ok(None)
}
} }
} }
#[cfg(feature = "mock")] #[cfg(feature = "mock")]
QueryResultRow::Mock(row) => match row.try_get(column.as_str()) { QueryResultRow::Mock(row) => row.try_get(column.as_str()).map_err(|e| {
Ok(v) => Ok(Some(v)),
Err(e) => {
debug_print!("{:#?}", e.to_string()); debug_print!("{:#?}", e.to_string());
Ok(None) TryGetError::Null
} }),
},
} }
} }
} }