Select into tuple
This commit is contained in:
parent
5b9c49a9a0
commit
70c4a3a23e
@ -356,6 +356,11 @@ impl ActiveEnum {
|
|||||||
let value = <<Self as sea_orm::ActiveEnum>::Value as sea_orm::TryGetable>::try_get(res, pre, col)?;
|
let value = <<Self as sea_orm::ActiveEnum>::Value as sea_orm::TryGetable>::try_get(res, pre, col)?;
|
||||||
<Self as sea_orm::ActiveEnum>::try_from_value(&value).map_err(sea_orm::TryGetError::DbErr)
|
<Self as sea_orm::ActiveEnum>::try_from_value(&value).map_err(sea_orm::TryGetError::DbErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &sea_orm::QueryResult, idx: usize) -> std::result::Result<Self, sea_orm::TryGetError> {
|
||||||
|
let value = <<Self as sea_orm::ActiveEnum>::Value as sea_orm::TryGetable>::try_get_by_index(res, idx)?;
|
||||||
|
<Self as sea_orm::ActiveEnum>::try_from_value(&value).map_err(sea_orm::TryGetError::DbErr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
|
@ -211,6 +211,21 @@ impl MockRow {
|
|||||||
T::try_from(self.values.get(col).unwrap().clone()).map_err(|e| DbErr::Type(e.to_string()))
|
T::try_from(self.values.get(col).unwrap().clone()).map_err(|e| DbErr::Type(e.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn try_get_by_index<T>(&self, idx: usize) -> Result<T, DbErr>
|
||||||
|
where
|
||||||
|
T: ValueType,
|
||||||
|
{
|
||||||
|
let (_, value) = self
|
||||||
|
.values
|
||||||
|
.iter()
|
||||||
|
.nth(idx)
|
||||||
|
.ok_or(DbErr::Query(RuntimeErr::Internal(format!(
|
||||||
|
"Column at index {} not found",
|
||||||
|
idx
|
||||||
|
))))?;
|
||||||
|
T::try_from(value.clone()).map_err(|e| DbErr::Type(e.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator over the keys and values of a mock row
|
/// An iterator over the keys and values of a mock row
|
||||||
pub fn into_column_value_tuples(self) -> impl Iterator<Item = (String, Value)> {
|
pub fn into_column_value_tuples(self) -> impl Iterator<Item = (String, Value)> {
|
||||||
self.values.into_iter()
|
self.values.into_iter()
|
||||||
|
@ -158,6 +158,13 @@ where
|
|||||||
.map(|value| T::try_from_value(&value).map_err(TryGetError::DbErr))
|
.map(|value| T::try_from_value(&value).map_err(TryGetError::DbErr))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
<T::ValueVec as TryGetable>::try_get_by_index(res, idx)?
|
||||||
|
.into_iter()
|
||||||
|
.map(|value| T::try_from_value(&value).map_err(TryGetError::DbErr))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -21,10 +21,13 @@ pub(crate) enum QueryResultRow {
|
|||||||
Mock(crate::MockRow),
|
Mock(crate::MockRow),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constrain any type trying to get a Row in a database
|
/// An interface to get a value from the query result
|
||||||
pub trait TryGetable: Sized {
|
pub trait TryGetable: Sized {
|
||||||
/// Ensure the type implements this method
|
/// Get a value from the query result with prefixed column name
|
||||||
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError>;
|
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError>;
|
||||||
|
|
||||||
|
/// Get a value from the query result based on the order in the select expressions
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An error from trying to get a row from a Model
|
/// An error from trying to get a row from a Model
|
||||||
@ -58,6 +61,13 @@ impl QueryResult {
|
|||||||
Ok(T::try_get(self, pre, col)?)
|
Ok(T::try_get(self, pre, col)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn try_get_by_index<T>(&self, idx: usize) -> Result<T, DbErr>
|
||||||
|
where
|
||||||
|
T: TryGetable,
|
||||||
|
{
|
||||||
|
Ok(T::try_get_by_index(self, idx)?)
|
||||||
|
}
|
||||||
|
|
||||||
/// Perform query operations on multiple Columns
|
/// Perform query operations on multiple Columns
|
||||||
pub fn try_get_many<T>(&self, pre: &str, cols: &[String]) -> Result<T, DbErr>
|
pub fn try_get_many<T>(&self, pre: &str, cols: &[String]) -> Result<T, DbErr>
|
||||||
where
|
where
|
||||||
@ -65,6 +75,13 @@ impl QueryResult {
|
|||||||
{
|
{
|
||||||
Ok(T::try_get_many(self, pre, cols)?)
|
Ok(T::try_get_many(self, pre, cols)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn try_get_many_by_index<T>(&self) -> Result<T, DbErr>
|
||||||
|
where
|
||||||
|
T: TryGetableMany,
|
||||||
|
{
|
||||||
|
Ok(T::try_get_many_by_index(self)?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
@ -95,6 +112,14 @@ impl<T: TryGetable> TryGetable for Option<T> {
|
|||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
match T::try_get_by_index(res, idx) {
|
||||||
|
Ok(v) => Ok(Some(v)),
|
||||||
|
Err(TryGetError::Null(_)) => Ok(None),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! try_getable_all {
|
macro_rules! try_getable_all {
|
||||||
@ -135,6 +160,40 @@ macro_rules! try_getable_all {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
match &res.row {
|
||||||
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
|
QueryResultRow::SqlxMySql(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<$type>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
|
QueryResultRow::SqlxPostgres(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<$type>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<$type>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
QueryResultRow::Mock(row) => row.try_get_by_index(idx).map_err(|e| {
|
||||||
|
debug_print!("{:#?}", e.to_string());
|
||||||
|
TryGetError::Null(idx.to_string())
|
||||||
|
}),
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -174,6 +233,37 @@ macro_rules! try_getable_unsigned {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
match &res.row {
|
||||||
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
|
QueryResultRow::SqlxMySql(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<$type>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[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::<Option<$type>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
QueryResultRow::Mock(row) => row.try_get_by_index(idx).map_err(|e| {
|
||||||
|
debug_print!("{:#?}", e.to_string());
|
||||||
|
err_null_idx_col(idx)
|
||||||
|
}),
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -210,6 +300,34 @@ macro_rules! try_getable_mysql {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
match &res.row {
|
||||||
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
|
QueryResultRow::SqlxMySql(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<$type>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[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")]
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
QueryResultRow::Mock(row) => row.try_get_by_index(idx).map_err(|e| {
|
||||||
|
debug_print!("{:#?}", e.to_string());
|
||||||
|
err_null_idx_col(idx)
|
||||||
|
}),
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -257,6 +375,44 @@ macro_rules! try_getable_date_time {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
match &res.row {
|
||||||
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
|
QueryResultRow::SqlxMySql(row) => {
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<DateTime<Utc>>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
.map(|v| v.into())
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
|
QueryResultRow::SqlxPostgres(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<$type>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(row) => {
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<DateTime<Utc>>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
.map(|v| v.into())
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
QueryResultRow::Mock(row) => row.try_get_by_index(idx).map_err(|e| {
|
||||||
|
debug_print!("{:#?}", e.to_string());
|
||||||
|
err_null_idx_col(idx)
|
||||||
|
}),
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -357,6 +513,50 @@ impl TryGetable for Decimal {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
match &res.row {
|
||||||
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
|
QueryResultRow::SqlxMySql(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<Decimal>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
|
QueryResultRow::SqlxPostgres(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<Decimal>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
let val: Option<f64> = row
|
||||||
|
.try_get(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))?;
|
||||||
|
match val {
|
||||||
|
Some(v) => Decimal::try_from(v).map_err(|e| {
|
||||||
|
TryGetError::DbErr(DbErr::TryIntoErr {
|
||||||
|
from: "f64",
|
||||||
|
into: "Decimal",
|
||||||
|
source: Box::new(e),
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
None => Err(err_null_idx_col(idx)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
QueryResultRow::Mock(row) => row.try_get_by_index(idx).map_err(|e| {
|
||||||
|
debug_print!("{:#?}", e.to_string());
|
||||||
|
err_null_idx_col(idx)
|
||||||
|
}),
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "with-bigdecimal")]
|
#[cfg(feature = "with-bigdecimal")]
|
||||||
@ -409,6 +609,50 @@ impl TryGetable for BigDecimal {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
match &res.row {
|
||||||
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
|
QueryResultRow::SqlxMySql(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<BigDecimal>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
|
QueryResultRow::SqlxPostgres(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<BigDecimal>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
let val: Option<f64> = row
|
||||||
|
.try_get(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))?;
|
||||||
|
match val {
|
||||||
|
Some(v) => BigDecimal::try_from(v).map_err(|e| {
|
||||||
|
TryGetError::DbErr(DbErr::TryIntoErr {
|
||||||
|
from: "f64",
|
||||||
|
into: "BigDecimal",
|
||||||
|
source: Box::new(e),
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
None => Err(err_null_idx_col(idx)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
QueryResultRow::Mock(row) => row.try_get_by_index(idx).map_err(|e| {
|
||||||
|
debug_print!("{:#?}", e.to_string());
|
||||||
|
err_null_idx_col(idx)
|
||||||
|
}),
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "with-uuid")]
|
#[cfg(feature = "with-uuid")]
|
||||||
@ -454,6 +698,48 @@ impl TryGetable for u32 {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
match &res.row {
|
||||||
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
|
QueryResultRow::SqlxMySql(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<u32>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
|
QueryResultRow::SqlxPostgres(row) => {
|
||||||
|
use sqlx::postgres::types::Oid;
|
||||||
|
// 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`.
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<Oid>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
.map(|oid| oid.0)
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<u32>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
QueryResultRow::Mock(row) => row.try_get_by_index(idx).map_err(|e| {
|
||||||
|
debug_print!("{:#?}", e.to_string());
|
||||||
|
err_null_idx_col(idx)
|
||||||
|
}),
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn err_null_idx_col(idx: usize) -> TryGetError {
|
||||||
|
TryGetError::Null(format!("column at index {}", idx))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "postgres-array")]
|
#[cfg(feature = "postgres-array")]
|
||||||
@ -469,7 +755,7 @@ mod postgres_array {
|
|||||||
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(_) => {
|
||||||
panic!("{} unsupported by sqlx-mysql", stringify!($type))
|
panic!("{} unsupported by sqlx-mysql", stringify!($type))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "sqlx-postgres")]
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
@ -492,6 +778,33 @@ mod postgres_array {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
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::<Option<Vec<$type>>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(_) => {
|
||||||
|
panic!("{} unsupported by sqlx-sqlite", stringify!($type))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
QueryResultRow::Mock(row) => row.try_get_by_index(idx).map_err(|e| {
|
||||||
|
debug_print!("{:#?}", e.to_string());
|
||||||
|
err_null_idx_col(idx)
|
||||||
|
}),
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -553,7 +866,7 @@ mod postgres_array {
|
|||||||
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(_) => {
|
||||||
panic!("{} unsupported by sqlx-mysql", stringify!($type))
|
panic!("{} unsupported by sqlx-mysql", stringify!($type))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "sqlx-postgres")]
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
@ -580,16 +893,50 @@ mod postgres_array {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
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::postgres::types::Oid;
|
||||||
|
// 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`.
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<Vec<Oid>>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)))
|
||||||
|
.map(|oids| oids.into_iter().map(|oid| oid.0).collect())
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(_) => {
|
||||||
|
panic!("{} unsupported by sqlx-sqlite", stringify!($type))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
QueryResultRow::Mock(row) => row.try_get_by_index(idx).map_err(|e| {
|
||||||
|
debug_print!("{:#?}", e.to_string());
|
||||||
|
err_null_idx_col(idx)
|
||||||
|
}),
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryGetableMany //
|
// TryGetableMany //
|
||||||
|
|
||||||
/// Perform a query on multiple columns
|
/// An interface to get a tuple value from the query result
|
||||||
pub trait TryGetableMany: Sized {
|
pub trait TryGetableMany: Sized {
|
||||||
/// THe method to perform a query on multiple columns
|
/// Get a tuple value from the query result with prefixed column name
|
||||||
fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError>;
|
fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError>;
|
||||||
|
|
||||||
|
/// Get a tuple value from the query result based on the order in the select expressions
|
||||||
|
fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError>;
|
||||||
|
|
||||||
/// ```
|
/// ```
|
||||||
/// # use sea_orm::{error::*, tests_cfg::*, *};
|
/// # use sea_orm::{error::*, tests_cfg::*, *};
|
||||||
/// #
|
/// #
|
||||||
@ -663,6 +1010,10 @@ where
|
|||||||
try_get_many_with_slice_len_of(1, cols)?;
|
try_get_many_with_slice_len_of(1, cols)?;
|
||||||
T::try_get(res, pre, &cols[0])
|
T::try_get(res, pre, &cols[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {
|
||||||
|
T::try_get_by_index(res, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> TryGetableMany for (T,)
|
impl<T> TryGetableMany for (T,)
|
||||||
@ -672,6 +1023,10 @@ where
|
|||||||
fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {
|
fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {
|
||||||
T::try_get_many(res, pre, cols).map(|r| (r,))
|
T::try_get_many(res, pre, cols).map(|r| (r,))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {
|
||||||
|
T::try_get_many_by_index(res).map(|r| (r,))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> TryGetableMany for (A, B)
|
impl<A, B> TryGetableMany for (A, B)
|
||||||
@ -686,6 +1041,10 @@ where
|
|||||||
B::try_get(res, pre, &cols[1])?,
|
B::try_get(res, pre, &cols[1])?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {
|
||||||
|
Ok((A::try_get_by_index(res, 0)?, B::try_get_by_index(res, 1)?))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, C> TryGetableMany for (A, B, C)
|
impl<A, B, C> TryGetableMany for (A, B, C)
|
||||||
@ -702,6 +1061,14 @@ where
|
|||||||
C::try_get(res, pre, &cols[2])?,
|
C::try_get(res, pre, &cols[2])?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {
|
||||||
|
Ok((
|
||||||
|
A::try_get_by_index(res, 0)?,
|
||||||
|
B::try_get_by_index(res, 1)?,
|
||||||
|
C::try_get_by_index(res, 2)?,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, C, D> TryGetableMany for (A, B, C, D)
|
impl<A, B, C, D> TryGetableMany for (A, B, C, D)
|
||||||
@ -720,6 +1087,15 @@ where
|
|||||||
D::try_get(res, pre, &cols[3])?,
|
D::try_get(res, pre, &cols[3])?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {
|
||||||
|
Ok((
|
||||||
|
A::try_get_by_index(res, 0)?,
|
||||||
|
B::try_get_by_index(res, 1)?,
|
||||||
|
C::try_get_by_index(res, 2)?,
|
||||||
|
D::try_get_by_index(res, 3)?,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, C, D, E> TryGetableMany for (A, B, C, D, E)
|
impl<A, B, C, D, E> TryGetableMany for (A, B, C, D, E)
|
||||||
@ -740,6 +1116,16 @@ where
|
|||||||
E::try_get(res, pre, &cols[4])?,
|
E::try_get(res, pre, &cols[4])?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {
|
||||||
|
Ok((
|
||||||
|
A::try_get_by_index(res, 0)?,
|
||||||
|
B::try_get_by_index(res, 1)?,
|
||||||
|
C::try_get_by_index(res, 2)?,
|
||||||
|
D::try_get_by_index(res, 3)?,
|
||||||
|
E::try_get_by_index(res, 4)?,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, C, D, E, F> TryGetableMany for (A, B, C, D, E, F)
|
impl<A, B, C, D, E, F> TryGetableMany for (A, B, C, D, E, F)
|
||||||
@ -762,6 +1148,17 @@ where
|
|||||||
F::try_get(res, pre, &cols[5])?,
|
F::try_get(res, pre, &cols[5])?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {
|
||||||
|
Ok((
|
||||||
|
A::try_get_by_index(res, 0)?,
|
||||||
|
B::try_get_by_index(res, 1)?,
|
||||||
|
C::try_get_by_index(res, 2)?,
|
||||||
|
D::try_get_by_index(res, 3)?,
|
||||||
|
E::try_get_by_index(res, 4)?,
|
||||||
|
F::try_get_by_index(res, 5)?,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_get_many_with_slice_len_of(len: usize, cols: &[String]) -> Result<(), TryGetError> {
|
fn try_get_many_with_slice_len_of(len: usize, cols: &[String]) -> Result<(), TryGetError> {
|
||||||
@ -825,6 +1222,45 @@ where
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_from_json_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
match &res.row {
|
||||||
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
|
QueryResultRow::SqlxMySql(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<sqlx::types::Json<Self>>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)).map(|json| json.0))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-postgres")]
|
||||||
|
QueryResultRow::SqlxPostgres(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<sqlx::types::Json<Self>>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)).map(|json| json.0))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
row.try_get::<Option<sqlx::types::Json<Self>>, _>(idx)
|
||||||
|
.map_err(|e| TryGetError::DbErr(crate::sqlx_error_to_query_err(e)))
|
||||||
|
.and_then(|opt| opt.ok_or(err_null_idx_col(idx)).map(|json| json.0))
|
||||||
|
}
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
QueryResultRow::Mock(row) => row
|
||||||
|
.try_get_by_index::<serde_json::Value>(idx)
|
||||||
|
.map_err(|e| {
|
||||||
|
debug_print!("{:#?}", e.to_string());
|
||||||
|
err_null_idx_col(idx)
|
||||||
|
})
|
||||||
|
.and_then(|json| {
|
||||||
|
serde_json::from_value(json)
|
||||||
|
.map_err(|e| TryGetError::DbErr(DbErr::Json(e.to_string())))
|
||||||
|
}),
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "with-json")]
|
#[cfg(feature = "with-json")]
|
||||||
@ -835,6 +1271,10 @@ where
|
|||||||
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
|
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {
|
||||||
T::try_get_from_json(res, pre, col)
|
T::try_get_from_json(res, pre, col)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
T::try_get_from_json_by_index(res, idx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryFromU64 //
|
// TryFromU64 //
|
||||||
|
@ -52,6 +52,14 @@ where
|
|||||||
model: PhantomData<T>,
|
model: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SelectGetableTuple<T>
|
||||||
|
where
|
||||||
|
T: TryGetableMany,
|
||||||
|
{
|
||||||
|
model: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Defines a type to get a Model
|
/// Defines a type to get a Model
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SelectModel<M>
|
pub struct SelectModel<M>
|
||||||
@ -84,6 +92,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> SelectorTrait for SelectGetableTuple<T>
|
||||||
|
where
|
||||||
|
T: TryGetableMany,
|
||||||
|
{
|
||||||
|
type Item = T;
|
||||||
|
|
||||||
|
fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {
|
||||||
|
T::try_get_many_by_index(&res).map_err(Into::into)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<M> SelectorTrait for SelectModel<M>
|
impl<M> SelectorTrait for SelectModel<M>
|
||||||
where
|
where
|
||||||
M: FromQueryResult + Sized,
|
M: FromQueryResult + Sized,
|
||||||
@ -253,6 +272,104 @@ where
|
|||||||
Selector::<SelectGetableValue<T, C>>::with_columns(self.query)
|
Selector::<SelectGetableValue<T, C>>::with_columns(self.query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ```
|
||||||
|
/// # use sea_orm::{error::*, tests_cfg::*, *};
|
||||||
|
/// #
|
||||||
|
/// # #[smol_potat::main]
|
||||||
|
/// # #[cfg(all(feature = "mock", feature = "macros"))]
|
||||||
|
/// # pub async fn main() -> Result<(), DbErr> {
|
||||||
|
/// #
|
||||||
|
/// # let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
/// # .append_query_results(vec![vec![
|
||||||
|
/// # maplit::btreemap! {
|
||||||
|
/// # "cake_name" => Into::<Value>::into("Chocolate Forest"),
|
||||||
|
/// # },
|
||||||
|
/// # maplit::btreemap! {
|
||||||
|
/// # "cake_name" => Into::<Value>::into("New York Cheese"),
|
||||||
|
/// # },
|
||||||
|
/// # ]])
|
||||||
|
/// # .into_connection();
|
||||||
|
/// #
|
||||||
|
/// use sea_orm::{entity::*, query::*, tests_cfg::cake};
|
||||||
|
///
|
||||||
|
/// let res: Vec<String> = cake::Entity::find()
|
||||||
|
/// .select_only()
|
||||||
|
/// .column(cake::Column::Name)
|
||||||
|
/// .into_tuple()
|
||||||
|
/// .all(&db)
|
||||||
|
/// .await?;
|
||||||
|
///
|
||||||
|
/// assert_eq!(
|
||||||
|
/// res,
|
||||||
|
/// vec!["Chocolate Forest".to_owned(), "New York Cheese".to_owned()]
|
||||||
|
/// );
|
||||||
|
///
|
||||||
|
/// assert_eq!(
|
||||||
|
/// db.into_transaction_log(),
|
||||||
|
/// vec![Transaction::from_sql_and_values(
|
||||||
|
/// DbBackend::Postgres,
|
||||||
|
/// r#"SELECT "cake"."name" FROM "cake""#,
|
||||||
|
/// vec![]
|
||||||
|
/// )]
|
||||||
|
/// );
|
||||||
|
/// #
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use sea_orm::{error::*, tests_cfg::*, *};
|
||||||
|
/// #
|
||||||
|
/// # #[smol_potat::main]
|
||||||
|
/// # #[cfg(all(feature = "mock", feature = "macros"))]
|
||||||
|
/// # pub async fn main() -> Result<(), DbErr> {
|
||||||
|
/// #
|
||||||
|
/// # let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
/// # .append_query_results(vec![vec![
|
||||||
|
/// # maplit::btreemap! {
|
||||||
|
/// # "cake_name" => Into::<Value>::into("Chocolate Forest"),
|
||||||
|
/// # "num_of_cakes" => Into::<Value>::into(2i64),
|
||||||
|
/// # },
|
||||||
|
/// # ]])
|
||||||
|
/// # .into_connection();
|
||||||
|
/// #
|
||||||
|
/// use sea_orm::{entity::*, query::*, tests_cfg::cake};
|
||||||
|
///
|
||||||
|
/// let res: Vec<(String, i64)> = cake::Entity::find()
|
||||||
|
/// .select_only()
|
||||||
|
/// .column(cake::Column::Name)
|
||||||
|
/// .column(cake::Column::Id)
|
||||||
|
/// .group_by(cake::Column::Name)
|
||||||
|
/// .into_tuple()
|
||||||
|
/// .all(&db)
|
||||||
|
/// .await?;
|
||||||
|
///
|
||||||
|
/// assert_eq!(res, vec![("Chocolate Forest".to_owned(), 2i64)]);
|
||||||
|
///
|
||||||
|
/// assert_eq!(
|
||||||
|
/// db.into_transaction_log(),
|
||||||
|
/// vec![Transaction::from_sql_and_values(
|
||||||
|
/// DbBackend::Postgres,
|
||||||
|
/// vec![
|
||||||
|
/// r#"SELECT "cake"."name", "cake"."id""#,
|
||||||
|
/// r#"FROM "cake" GROUP BY "cake"."name""#,
|
||||||
|
/// ]
|
||||||
|
/// .join(" ")
|
||||||
|
/// .as_str(),
|
||||||
|
/// vec![]
|
||||||
|
/// )]
|
||||||
|
/// );
|
||||||
|
/// #
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
pub fn into_tuple<T>(self) -> Selector<SelectGetableTuple<T>>
|
||||||
|
where
|
||||||
|
T: TryGetableMany,
|
||||||
|
{
|
||||||
|
Selector::<SelectGetableTuple<T>>::into_tuple(self.query)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get one Model from the SELECT query
|
/// Get one Model from the SELECT query
|
||||||
pub async fn one<'a, C>(self, db: &C) -> Result<Option<E::Model>, DbErr>
|
pub async fn one<'a, C>(self, db: &C) -> Result<Option<E::Model>, DbErr>
|
||||||
where
|
where
|
||||||
@ -402,7 +519,7 @@ impl<S> Selector<S>
|
|||||||
where
|
where
|
||||||
S: SelectorTrait,
|
S: SelectorTrait,
|
||||||
{
|
{
|
||||||
/// Create `Selector` from Statment and columns. Executing this `Selector`
|
/// Create `Selector` from Statement and columns. Executing this `Selector`
|
||||||
/// will return a type `T` which implement `TryGetableMany`.
|
/// will return a type `T` which implement `TryGetableMany`.
|
||||||
pub fn with_columns<T, C>(query: SelectStatement) -> Selector<SelectGetableValue<T, C>>
|
pub fn with_columns<T, C>(query: SelectStatement) -> Selector<SelectGetableValue<T, C>>
|
||||||
where
|
where
|
||||||
@ -418,6 +535,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn into_tuple<T>(query: SelectStatement) -> Selector<SelectGetableTuple<T>>
|
||||||
|
where
|
||||||
|
T: TryGetableMany,
|
||||||
|
{
|
||||||
|
Selector {
|
||||||
|
query,
|
||||||
|
selector: SelectGetableTuple { model: PhantomData },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn into_selector_raw<C>(self, db: &C) -> SelectorRaw<S>
|
fn into_selector_raw<C>(self, db: &C) -> SelectorRaw<S>
|
||||||
where
|
where
|
||||||
C: ConnectionTrait,
|
C: ConnectionTrait,
|
||||||
|
@ -29,6 +29,11 @@ impl TryGetable for StringVec {
|
|||||||
let json_str: String = res.try_get(pre, col).map_err(TryGetError::DbErr)?;
|
let json_str: String = res.try_get(pre, col).map_err(TryGetError::DbErr)?;
|
||||||
serde_json::from_str(&json_str).map_err(|e| TryGetError::DbErr(DbErr::Json(e.to_string())))
|
serde_json::from_str(&json_str).map_err(|e| TryGetError::DbErr(DbErr::Json(e.to_string())))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_by_index(res: &QueryResult, idx: usize) -> Result<Self, TryGetError> {
|
||||||
|
let json_str: String = res.try_get_by_index(idx).map_err(TryGetError::DbErr)?;
|
||||||
|
serde_json::from_str(&json_str).map_err(|e| TryGetError::DbErr(DbErr::Json(e.to_string())))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl sea_query::ValueType for StringVec {
|
impl sea_query::ValueType for StringVec {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user