use super::*;
pub trait BelongsTo<Parent>: Sized
where
Parent: FromRow,
{
fn into_query(self) -> QueryOf<Parent>;
fn query(self) -> Option<QueryOf<Parent>> {
Some(self.into_query())
}
fn all(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Vec<Parent>>> {
async move { self.into_query().all(exec).await }
}
fn one(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Parent>> {
async move { self.into_query().one(exec).await }
}
fn optional(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Option<Parent>>> {
async move { self.into_query().optional(exec).await }
}
fn filter<E>(self, expr: E) -> QueryOf<Parent>
where
E: query::LowerFilter,
{
self.into_query().filter(expr)
}
fn or_filter<E>(self, expr: E) -> QueryOf<Parent>
where
E: query::LowerFilter,
{
self.into_query().or_filter(expr)
}
fn order_by<T>(self, by: T) -> QueryOf<Parent>
where
T: LowerOrderBy,
{
self.into_query().order_by(by)
}
fn order_by_random(self) -> QueryOf<Parent> {
self.into_query().order_by_random()
}
fn limit<E>(self, expr: E) -> QueryOf<Parent>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().limit(expr)
}
fn offset<E>(self, expr: E) -> QueryOf<Parent>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().offset(expr)
}
fn distinct(self) -> QueryOf<Parent> {
self.into_query().distinct()
}
fn not_distinct(self) -> QueryOf<Parent> {
self.into_query().not_distinct()
}
fn with<C>(self, ctes: C) -> QueryOf<Parent>
where
C: IntoCtes,
{
self.into_query().with(ctes)
}
fn with_recursive<C>(self, ctes: C) -> QueryOf<Parent>
where
C: IntoCtes,
{
self.into_query().with_recursive(ctes)
}
fn untyped(self) -> Query {
self.into_query().untyped()
}
fn to_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_sql::<D>()
}
fn to_debug_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_debug_sql::<D>()
}
}
pub trait NullableBelongsTo<Parent>: Sized
where
Parent: FromRow,
{
fn into_optional_query(self) -> OptionalQuery<Parent>;
fn query(self) -> Option<QueryOf<Parent>> {
self.into_optional_query().into_option()
}
fn optional(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Option<Parent>>> {
async move { self.into_optional_query().optional(exec).await }
}
fn filter<E>(self, expr: E) -> OptionalQuery<Parent>
where
E: query::LowerFilter,
{
self.into_optional_query().filter(expr)
}
fn or_filter<E>(self, expr: E) -> OptionalQuery<Parent>
where
E: query::LowerFilter,
{
self.into_optional_query().or_filter(expr)
}
fn order_by<T>(self, by: T) -> OptionalQuery<Parent>
where
T: LowerOrderBy,
{
self.into_optional_query().order_by(by)
}
fn order_by_random(self) -> OptionalQuery<Parent> {
self.into_optional_query().order_by_random()
}
fn limit<E>(self, expr: E) -> OptionalQuery<Parent>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_optional_query().limit(expr)
}
fn offset<E>(self, expr: E) -> OptionalQuery<Parent>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_optional_query().offset(expr)
}
fn distinct(self) -> OptionalQuery<Parent> {
self.into_optional_query().distinct()
}
fn not_distinct(self) -> OptionalQuery<Parent> {
self.into_optional_query().not_distinct()
}
fn with<C>(self, ctes: C) -> OptionalQuery<Parent>
where
C: IntoCtes,
{
self.into_optional_query().with(ctes)
}
fn with_recursive<C>(self, ctes: C) -> OptionalQuery<Parent>
where
C: IntoCtes,
{
self.into_optional_query().with_recursive(ctes)
}
fn untyped(self) -> Option<Query> {
self.into_optional_query().untyped()
}
fn to_sql<D: crate::HasDialect>(self) -> Option<String> {
self.into_optional_query().to_sql::<D>()
}
fn to_debug_sql<D: crate::HasDialect>(self) -> Option<String> {
self.into_optional_query().to_debug_sql::<D>()
}
}
pub trait BelongsToMut<Parent>: BelongsTo<Parent>
where
Parent: FromRow,
{
type Child: Draftable;
fn associate<'a>(self, parent: &Parent) -> <Self::Child as Draftable>::Draft<'a>
where
Self: 'a;
}
pub trait NullableBelongsToMut<Parent>: NullableBelongsTo<Parent>
where
Parent: FromRow,
{
type Child: Draftable;
fn associate<'a>(self, parent: &Parent) -> <Self::Child as Draftable>::Draft<'a>
where
Self: 'a;
fn dissociate<'a>(self) -> <Self::Child as Draftable>::Draft<'a>
where
Self: 'a;
}
pub trait MorphTo: Sized {
fn as_morph<Parent>(self) -> OptionalQuery<Parent>
where
Parent: Qrafting + FromRow + ModelKey + 'static;
}
pub trait MorphToMut: MorphTo {
type Child: Draftable;
fn associate<'a, Parent>(self, parent: &Parent) -> <Self::Child as Draftable>::Draft<'a>
where
Parent: Qrafting + FromRow + ModelKey + 'static,
Self: 'a;
}
#[doc(hidden)]
pub struct BelongsToManyActionState<Related, Pivot, ParentMeta: crate::TypeMeta, ParentKey>
where
Related: ModelKey,
<Related as ModelKey>::Key: crate::DefaultMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta: Comparable + crate::Nullability,
{
pub(super) pivot_table: query::Table<Pivot>,
pub(super) parent_column: expression::Column<Pivot, ParentMeta>,
pub(super) related_column:
expression::Column<Pivot, <<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
pub(super) parent_key: ParentKey,
}
#[doc(hidden)]
pub trait BelongsToManyActionStateExt<Related>
where
Related: Qrafting + FromRow + ModelKey,
<Related as ModelKey>::Key: crate::DefaultMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta: Comparable + crate::Nullability,
{
type Pivot: Qrafting;
type ParentMeta: Comparable + crate::Nullability;
type ParentKey: Clone + crate::LowerCompatible<Self::ParentMeta>;
fn into_parts(
self,
) -> (
query::Table<Self::Pivot>,
expression::Column<Self::Pivot, Self::ParentMeta>,
expression::Column<Self::Pivot, <<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
Self::ParentKey,
);
fn into_detach_action(
self,
related: &Related,
) -> DetachBelongsToMany<
Self::Pivot,
Self::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
Self::ParentKey,
<Related as ModelKey>::Key,
>
where
<Related as ModelKey>::Key: Clone
+ crate::LowerCompatible<<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>;
}
impl<Related, Pivot, ParentMeta, ParentKey> BelongsToManyActionStateExt<Related>
for BelongsToManyActionState<Related, Pivot, ParentMeta, ParentKey>
where
Related: Qrafting + FromRow + ModelKey,
<Related as ModelKey>::Key: crate::DefaultMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta: Comparable + crate::Nullability,
crate::BinaryType<crate::NullOf<ParentMeta>, crate::NullOf<ParentMeta>>: crate::PredicateType,
crate::BinaryType<
crate::NullOf<<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
crate::NullOf<<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
>: crate::PredicateType,
Pivot: Qrafting,
ParentMeta: Comparable + crate::Nullability,
ParentKey: Clone + crate::LowerCompatible<ParentMeta>,
{
type Pivot = Pivot;
type ParentMeta = ParentMeta;
type ParentKey = ParentKey;
fn into_parts(
self,
) -> (
query::Table<Self::Pivot>,
expression::Column<Self::Pivot, Self::ParentMeta>,
expression::Column<Self::Pivot, <<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
Self::ParentKey,
) {
(
self.pivot_table,
self.parent_column,
self.related_column,
self.parent_key,
)
}
fn into_detach_action(
self,
related: &Related,
) -> DetachBelongsToMany<
Self::Pivot,
Self::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
Self::ParentKey,
<Related as ModelKey>::Key,
>
where
<Related as ModelKey>::Key: Clone
+ crate::LowerCompatible<<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
{
let (pivot_table, parent_column, related_column, parent_key) = self.into_parts();
DetachBelongsToMany {
pivot_table,
parent_column,
related_column,
parent_key,
related_key: <Related as ModelKey>::__qraft_key(related).clone(),
}
}
}
pub struct DetachBelongsToMany<
Pivot,
ParentMeta: crate::TypeMeta,
RelatedMeta: crate::TypeMeta,
ParentKey,
RelatedKey,
> {
pivot_table: query::Table<Pivot>,
parent_column: expression::Column<Pivot, ParentMeta>,
related_column: expression::Column<Pivot, RelatedMeta>,
parent_key: ParentKey,
related_key: RelatedKey,
}
impl<Pivot, ParentMeta, RelatedMeta, ParentKey, RelatedKey>
DetachBelongsToMany<Pivot, ParentMeta, RelatedMeta, ParentKey, RelatedKey>
where
Pivot: Qrafting,
ParentMeta: Comparable + crate::Nullability,
RelatedMeta: Comparable + crate::Nullability,
ParentKey: Clone + crate::LowerCompatible<ParentMeta>,
RelatedKey: Clone + crate::LowerCompatible<RelatedMeta>,
crate::BinaryType<crate::NullOf<ParentMeta>, crate::NullOf<ParentMeta>>: crate::PredicateType,
crate::BinaryType<crate::NullOf<RelatedMeta>, crate::NullOf<RelatedMeta>>: crate::PredicateType,
{
fn into_delete(self) -> crate::builder::Delete<Pivot> {
crate::builder::delete::delete_from(self.pivot_table)
.filter(self.parent_column.eq(self.parent_key))
.filter(self.related_column.eq(self.related_key))
}
pub async fn execute<E>(self, exec: E) -> quex::Result<quex::ExecResult>
where
E: crate::quex::Executor,
{
self.into_delete().execute(exec).await
}
pub fn to_sql<D: crate::HasDialect>(self) -> String {
self.into_delete().to_sql::<D>()
}
pub fn to_debug_sql<D: crate::HasDialect>(self) -> String {
self.into_delete().to_debug_sql::<D>()
}
}
pub trait BelongsToMany<Related>: Sized
where
Related: Qrafting + FromRow + ModelKey,
<Related as ModelKey>::Key: crate::DefaultMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta: Comparable + crate::Nullability,
{
type Pivot: Qrafting;
#[doc(hidden)]
type ActionState: BelongsToManyActionStateExt<Related, Pivot = Self::Pivot>;
fn into_query(self) -> QueryOf<Related>;
#[doc(hidden)]
fn into_action_state(self) -> Self::ActionState;
fn query(self) -> QueryOf<Related> {
self.into_query()
}
fn all(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Vec<Related>>> {
async move { self.into_query().all(exec).await }
}
fn one(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Related>> {
async move { self.into_query().one(exec).await }
}
fn optional(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Option<Related>>> {
async move { self.into_query().optional(exec).await }
}
fn filter<E>(self, expr: E) -> QueryOf<Related>
where
E: query::LowerFilter,
{
self.into_query().filter(expr)
}
fn or_filter<E>(self, expr: E) -> QueryOf<Related>
where
E: query::LowerFilter,
{
self.into_query().or_filter(expr)
}
fn order_by<T>(self, by: T) -> QueryOf<Related>
where
T: LowerOrderBy,
{
self.into_query().order_by(by)
}
fn order_by_random(self) -> QueryOf<Related> {
self.into_query().order_by_random()
}
fn limit<E>(self, expr: E) -> QueryOf<Related>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().limit(expr)
}
fn offset<E>(self, expr: E) -> QueryOf<Related>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().offset(expr)
}
fn distinct(self) -> QueryOf<Related> {
self.into_query().distinct()
}
fn not_distinct(self) -> QueryOf<Related> {
self.into_query().not_distinct()
}
fn lock_for_update(self) -> query::LockedQueryOf<Related> {
self.into_query().lock_for_update()
}
fn shared_lock(self) -> query::LockedQueryOf<Related> {
self.into_query().shared_lock()
}
fn with<C>(self, ctes: C) -> QueryOf<Related>
where
C: IntoCtes,
{
self.into_query().with(ctes)
}
fn with_recursive<C>(self, ctes: C) -> QueryOf<Related>
where
C: IntoCtes,
{
self.into_query().with_recursive(ctes)
}
fn untyped(self) -> Query {
self.into_query().untyped()
}
fn scalar<T: TypeMeta>(self) -> expression::Scalar<T> {
self.into_query().scalar::<T>()
}
fn to_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_sql::<D>()
}
fn to_debug_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_debug_sql::<D>()
}
fn attach<'b, Input>(
self,
related: Input,
) -> AttachBelongsToMany<
Self::Pivot,
<Self::ActionState as BelongsToManyActionStateExt<Related>>::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
<Self::ActionState as BelongsToManyActionStateExt<Related>>::ParentKey,
<Related as ModelKey>::Key,
>
where
Self::ActionState: BelongsToManyActionStateExt<Related>,
Input: AttachInput<'b, Related, <Related as ModelKey>::Key>,
Related: 'b,
{
let (pivot_table, parent_column, related_column, parent_key) =
self.into_action_state().into_parts();
AttachBelongsToMany {
pivot_table,
parent_column,
related_column,
parent_key,
related_keys: related
.into_related_keys(|item| <Related as ModelKey>::__qraft_key(item).clone()),
}
}
fn detach(
self,
related: &Related,
) -> DetachBelongsToMany<
Self::Pivot,
<Self::ActionState as BelongsToManyActionStateExt<Related>>::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
<Self::ActionState as BelongsToManyActionStateExt<Related>>::ParentKey,
<Related as ModelKey>::Key,
>
where
Self::ActionState: BelongsToManyActionStateExt<Related>,
<Related as ModelKey>::Key: Clone
+ crate::LowerCompatible<<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
{
self.into_action_state().into_detach_action(related)
}
fn sync<'b, I>(
self,
related: I,
) -> SyncBelongsToMany<
Self::Pivot,
<Self::ActionState as BelongsToManyActionStateExt<Related>>::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
<Self::ActionState as BelongsToManyActionStateExt<Related>>::ParentKey,
<Related as ModelKey>::Key,
>
where
Self::ActionState: BelongsToManyActionStateExt<Related>,
I: IntoIterator<Item = &'b Related>,
Related: 'b,
<Related as ModelKey>::Key: Clone,
{
let (pivot_table, parent_column, related_column, parent_key) =
self.into_action_state().into_parts();
SyncBelongsToMany {
pivot_table,
parent_column,
related_column,
parent_key,
related_keys: related
.into_iter()
.map(|item| <Related as ModelKey>::__qraft_key(item).clone())
.collect(),
}
}
fn toggle<'b, Input>(
self,
related: Input,
) -> ToggleBelongsToMany<
Self::Pivot,
<Self::ActionState as BelongsToManyActionStateExt<Related>>::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
<Self::ActionState as BelongsToManyActionStateExt<Related>>::ParentKey,
<Related as ModelKey>::Key,
>
where
Self::ActionState: BelongsToManyActionStateExt<Related>,
Input: AttachInput<'b, Related, <Related as ModelKey>::Key>,
Related: 'b,
{
let (pivot_table, parent_column, related_column, parent_key) =
self.into_action_state().into_parts();
ToggleBelongsToMany {
pivot_table,
parent_column,
related_column,
parent_key,
related_keys: related
.into_related_keys(|item| <Related as ModelKey>::__qraft_key(item).clone()),
}
}
fn sync_without_detaching<'b, Input>(
self,
related: Input,
) -> SyncWithoutDetachingBelongsToMany<
Self::Pivot,
<Self::ActionState as BelongsToManyActionStateExt<Related>>::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
<Self::ActionState as BelongsToManyActionStateExt<Related>>::ParentKey,
<Related as ModelKey>::Key,
>
where
Self::ActionState: BelongsToManyActionStateExt<Related>,
Input: AttachInput<'b, Related, <Related as ModelKey>::Key>,
Related: 'b,
{
let (pivot_table, parent_column, related_column, parent_key) =
self.into_action_state().into_parts();
SyncWithoutDetachingBelongsToMany {
pivot_table,
parent_column,
related_column,
parent_key,
related_keys: related
.into_related_keys(|item| <Related as ModelKey>::__qraft_key(item).clone()),
}
}
}
#[doc(hidden)]
pub struct MorphToManyActionState<Related, Pivot, ParentMeta: crate::TypeMeta, ParentKey>
where
Related: ModelKey,
<Related as ModelKey>::Key: crate::DefaultMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta: Comparable + crate::Nullability,
{
pub(super) pivot_table: query::Table<Pivot>,
pub(super) parent_column: expression::Column<Pivot, ParentMeta>,
pub(super) type_column: expression::Column<Pivot, crate::Text>,
pub(super) related_column:
expression::Column<Pivot, <<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
pub(super) parent_key: ParentKey,
pub(super) morph_name: &'static str,
}
#[doc(hidden)]
pub trait MorphToManyActionStateExt<Related>
where
Related: Qrafting + FromRow + ModelKey,
<Related as ModelKey>::Key: crate::DefaultMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta: Comparable + crate::Nullability,
{
type Pivot: Qrafting;
type ParentMeta: Comparable + crate::Nullability;
type ParentKey: Clone + crate::LowerCompatible<Self::ParentMeta>;
fn into_parts(
self,
) -> (
query::Table<Self::Pivot>,
expression::Column<Self::Pivot, Self::ParentMeta>,
expression::Column<Self::Pivot, crate::Text>,
expression::Column<Self::Pivot, <<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
Self::ParentKey,
&'static str,
);
fn into_detach_action(
self,
related: &Related,
) -> DetachMorphToMany<
Self::Pivot,
Self::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
Self::ParentKey,
<Related as ModelKey>::Key,
>
where
<Related as ModelKey>::Key: Clone
+ crate::LowerCompatible<<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>;
}
impl<Related, Pivot, ParentMeta, ParentKey> MorphToManyActionStateExt<Related>
for MorphToManyActionState<Related, Pivot, ParentMeta, ParentKey>
where
Related: Qrafting + FromRow + ModelKey,
<Related as ModelKey>::Key: crate::DefaultMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta: Comparable + crate::Nullability,
crate::BinaryType<crate::NullOf<ParentMeta>, crate::NullOf<ParentMeta>>: crate::PredicateType,
crate::BinaryType<
crate::NullOf<<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
crate::NullOf<<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
>: crate::PredicateType,
Pivot: Qrafting,
ParentMeta: Comparable + crate::Nullability,
ParentKey: Clone + crate::LowerCompatible<ParentMeta>,
{
type Pivot = Pivot;
type ParentMeta = ParentMeta;
type ParentKey = ParentKey;
fn into_parts(
self,
) -> (
query::Table<Self::Pivot>,
expression::Column<Self::Pivot, Self::ParentMeta>,
expression::Column<Self::Pivot, crate::Text>,
expression::Column<Self::Pivot, <<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
Self::ParentKey,
&'static str,
) {
(
self.pivot_table,
self.parent_column,
self.type_column,
self.related_column,
self.parent_key,
self.morph_name,
)
}
fn into_detach_action(
self,
related: &Related,
) -> DetachMorphToMany<
Self::Pivot,
Self::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
Self::ParentKey,
<Related as ModelKey>::Key,
>
where
<Related as ModelKey>::Key: Clone
+ crate::LowerCompatible<<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
{
let (pivot_table, parent_column, type_column, related_column, parent_key, morph_name) =
self.into_parts();
DetachMorphToMany {
pivot_table,
parent_column,
type_column,
related_column,
parent_key,
morph_name,
related_key: <Related as ModelKey>::__qraft_key(related).clone(),
}
}
}
pub struct DetachMorphToMany<
Pivot,
ParentMeta: crate::TypeMeta,
RelatedMeta: crate::TypeMeta,
ParentKey,
RelatedKey,
> {
pivot_table: query::Table<Pivot>,
parent_column: expression::Column<Pivot, ParentMeta>,
type_column: expression::Column<Pivot, crate::Text>,
related_column: expression::Column<Pivot, RelatedMeta>,
parent_key: ParentKey,
morph_name: &'static str,
related_key: RelatedKey,
}
impl<Pivot, ParentMeta, RelatedMeta, ParentKey, RelatedKey>
DetachMorphToMany<Pivot, ParentMeta, RelatedMeta, ParentKey, RelatedKey>
where
Pivot: Qrafting,
ParentMeta: Comparable + crate::Nullability,
RelatedMeta: Comparable + crate::Nullability,
ParentKey: Clone + crate::LowerCompatible<ParentMeta>,
RelatedKey: Clone + crate::LowerCompatible<RelatedMeta>,
&'static str: crate::LowerCompatible<crate::Text>,
crate::BinaryType<crate::NullOf<ParentMeta>, crate::NullOf<ParentMeta>>: crate::PredicateType,
crate::BinaryType<crate::NullOf<RelatedMeta>, crate::NullOf<RelatedMeta>>: crate::PredicateType,
crate::BinaryType<crate::NullOf<crate::Text>, crate::NullOf<crate::Text>>: crate::PredicateType,
{
fn into_delete(self) -> crate::builder::Delete<Pivot> {
crate::builder::delete::delete_from(self.pivot_table)
.filter(self.parent_column.eq(self.parent_key))
.filter(self.type_column.eq(self.morph_name))
.filter(self.related_column.eq(self.related_key))
}
pub async fn execute<E>(self, exec: E) -> quex::Result<quex::ExecResult>
where
E: crate::quex::Executor,
{
self.into_delete().execute(exec).await
}
pub fn to_sql<D: crate::HasDialect>(self) -> String {
self.into_delete().to_sql::<D>()
}
pub fn to_debug_sql<D: crate::HasDialect>(self) -> String {
self.into_delete().to_debug_sql::<D>()
}
}
pub trait MorphToMany<Related>: Sized
where
Related: Qrafting + FromRow + ModelKey,
<Related as ModelKey>::Key: crate::DefaultMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta: Comparable + crate::Nullability,
{
type Pivot: Qrafting;
#[doc(hidden)]
type ActionState: MorphToManyActionStateExt<Related, Pivot = Self::Pivot>;
fn into_query(self) -> QueryOf<Related>;
#[doc(hidden)]
fn into_action_state(self) -> Self::ActionState;
fn query(self) -> QueryOf<Related> {
self.into_query()
}
fn all(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Vec<Related>>> {
async move { self.into_query().all(exec).await }
}
fn one(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Related>> {
async move { self.into_query().one(exec).await }
}
fn optional(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Option<Related>>> {
async move { self.into_query().optional(exec).await }
}
fn filter<E>(self, expr: E) -> QueryOf<Related>
where
E: query::LowerFilter,
{
self.into_query().filter(expr)
}
fn or_filter<E>(self, expr: E) -> QueryOf<Related>
where
E: query::LowerFilter,
{
self.into_query().or_filter(expr)
}
fn order_by<T>(self, by: T) -> QueryOf<Related>
where
T: LowerOrderBy,
{
self.into_query().order_by(by)
}
fn order_by_random(self) -> QueryOf<Related> {
self.into_query().order_by_random()
}
fn limit<E>(self, expr: E) -> QueryOf<Related>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().limit(expr)
}
fn offset<E>(self, expr: E) -> QueryOf<Related>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().offset(expr)
}
fn distinct(self) -> QueryOf<Related> {
self.into_query().distinct()
}
fn not_distinct(self) -> QueryOf<Related> {
self.into_query().not_distinct()
}
fn lock_for_update(self) -> query::LockedQueryOf<Related> {
self.into_query().lock_for_update()
}
fn shared_lock(self) -> query::LockedQueryOf<Related> {
self.into_query().shared_lock()
}
fn with<C>(self, ctes: C) -> QueryOf<Related>
where
C: IntoCtes,
{
self.into_query().with(ctes)
}
fn with_recursive<C>(self, ctes: C) -> QueryOf<Related>
where
C: IntoCtes,
{
self.into_query().with_recursive(ctes)
}
fn untyped(self) -> Query {
self.into_query().untyped()
}
fn scalar<T: TypeMeta>(self) -> expression::Scalar<T> {
self.into_query().scalar::<T>()
}
fn to_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_sql::<D>()
}
fn to_debug_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_debug_sql::<D>()
}
fn attach<'b, Input>(
self,
related: Input,
) -> AttachMorphToMany<
Self::Pivot,
<Self::ActionState as MorphToManyActionStateExt<Related>>::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
<Self::ActionState as MorphToManyActionStateExt<Related>>::ParentKey,
<Related as ModelKey>::Key,
>
where
Self::ActionState: MorphToManyActionStateExt<Related>,
Input: AttachInput<'b, Related, <Related as ModelKey>::Key>,
Related: 'b,
{
let (pivot_table, parent_column, type_column, related_column, parent_key, morph_name) =
self.into_action_state().into_parts();
AttachMorphToMany {
pivot_table,
parent_column,
type_column,
related_column,
parent_key,
morph_type: morph_name,
related_keys: related
.into_related_keys(|item| <Related as ModelKey>::__qraft_key(item).clone()),
}
}
fn detach(
self,
related: &Related,
) -> DetachMorphToMany<
Self::Pivot,
<Self::ActionState as MorphToManyActionStateExt<Related>>::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
<Self::ActionState as MorphToManyActionStateExt<Related>>::ParentKey,
<Related as ModelKey>::Key,
>
where
Self::ActionState: MorphToManyActionStateExt<Related>,
<Related as ModelKey>::Key: Clone
+ crate::LowerCompatible<<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta>,
{
self.into_action_state().into_detach_action(related)
}
fn sync<'b, I>(
self,
related: I,
) -> SyncMorphToMany<
Self::Pivot,
<Self::ActionState as MorphToManyActionStateExt<Related>>::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
<Self::ActionState as MorphToManyActionStateExt<Related>>::ParentKey,
<Related as ModelKey>::Key,
>
where
Self::ActionState: MorphToManyActionStateExt<Related>,
I: IntoIterator<Item = &'b Related>,
Related: 'b,
<Related as ModelKey>::Key: Clone,
{
let (pivot_table, parent_column, type_column, related_column, parent_key, morph_name) =
self.into_action_state().into_parts();
SyncMorphToMany {
pivot_table,
parent_column,
type_column,
related_column,
parent_key,
morph_type: morph_name,
related_keys: related
.into_iter()
.map(|item| <Related as ModelKey>::__qraft_key(item).clone())
.collect(),
}
}
fn toggle<'b, Input>(
self,
related: Input,
) -> ToggleMorphToMany<
Self::Pivot,
<Self::ActionState as MorphToManyActionStateExt<Related>>::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
<Self::ActionState as MorphToManyActionStateExt<Related>>::ParentKey,
<Related as ModelKey>::Key,
>
where
Self::ActionState: MorphToManyActionStateExt<Related>,
Input: AttachInput<'b, Related, <Related as ModelKey>::Key>,
Related: 'b,
{
let (pivot_table, parent_column, type_column, related_column, parent_key, morph_name) =
self.into_action_state().into_parts();
ToggleMorphToMany {
pivot_table,
parent_column,
type_column,
related_column,
parent_key,
morph_type: morph_name,
related_keys: related
.into_related_keys(|item| <Related as ModelKey>::__qraft_key(item).clone()),
}
}
fn sync_without_detaching<'b, Input>(
self,
related: Input,
) -> SyncWithoutDetachingMorphToMany<
Self::Pivot,
<Self::ActionState as MorphToManyActionStateExt<Related>>::ParentMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta,
<Self::ActionState as MorphToManyActionStateExt<Related>>::ParentKey,
<Related as ModelKey>::Key,
>
where
Self::ActionState: MorphToManyActionStateExt<Related>,
Input: AttachInput<'b, Related, <Related as ModelKey>::Key>,
Related: 'b,
{
let (pivot_table, parent_column, type_column, related_column, parent_key, morph_name) =
self.into_action_state().into_parts();
SyncWithoutDetachingMorphToMany {
pivot_table,
parent_column,
type_column,
related_column,
parent_key,
morph_type: morph_name,
related_keys: related
.into_related_keys(|item| <Related as ModelKey>::__qraft_key(item).clone()),
}
}
}
pub trait MorphedByMany<Related>: MorphToMany<Related>
where
Related: Qrafting + FromRow + ModelKey,
<Related as ModelKey>::Key: crate::DefaultMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta: Comparable + crate::Nullability,
{
}
impl<T, Related> MorphedByMany<Related> for T
where
T: MorphToMany<Related>,
Related: Qrafting + FromRow + ModelKey,
<Related as ModelKey>::Key: crate::DefaultMeta,
<<Related as ModelKey>::Key as crate::DefaultMeta>::Meta: Comparable + crate::Nullability,
{
}
pub trait HasMany<Child>: Sized
where
Child: FromRow,
{
fn into_query(self) -> QueryOf<Child>;
fn query(self) -> QueryOf<Child> {
self.into_query()
}
fn all(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Vec<Child>>> {
async move { self.into_query().all(exec).await }
}
fn one(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Child>> {
async move { self.into_query().one(exec).await }
}
fn optional(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Option<Child>>> {
async move { self.into_query().optional(exec).await }
}
fn filter<E>(self, expr: E) -> QueryOf<Child>
where
E: query::LowerFilter,
{
self.into_query().filter(expr)
}
fn or_filter<E>(self, expr: E) -> QueryOf<Child>
where
E: query::LowerFilter,
{
self.into_query().or_filter(expr)
}
fn order_by<T>(self, by: T) -> QueryOf<Child>
where
T: LowerOrderBy,
{
self.into_query().order_by(by)
}
fn order_by_random(self) -> QueryOf<Child> {
self.into_query().order_by_random()
}
fn limit<E>(self, expr: E) -> QueryOf<Child>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().limit(expr)
}
fn offset<E>(self, expr: E) -> QueryOf<Child>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().offset(expr)
}
fn distinct(self) -> QueryOf<Child> {
self.into_query().distinct()
}
fn not_distinct(self) -> QueryOf<Child> {
self.into_query().not_distinct()
}
fn with<C>(self, ctes: C) -> QueryOf<Child>
where
C: IntoCtes,
{
self.into_query().with(ctes)
}
fn with_recursive<C>(self, ctes: C) -> QueryOf<Child>
where
C: IntoCtes,
{
self.into_query().with_recursive(ctes)
}
fn untyped(self) -> Query {
self.into_query().untyped()
}
fn to_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_sql::<D>()
}
fn to_debug_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_debug_sql::<D>()
}
fn associate<'a>(self, child: &'a mut Child) -> <Child as Draftable>::Draft<'a>
where
Child: Draftable;
fn create<V>(self, values: V) -> Insert<Child>
where
Child: Qrafting,
V: Insertable<Child>;
fn max_by<SortField, SortValue, SortMeta>(
self,
column: SortField,
) -> MaxByOfMany<Self, Child, SortMeta>
where
Self: Sized,
Child: Qrafting + Draftable + ModelKey,
SortField: ReadableField<Child, SortValue, SortMeta>,
SortMeta: Orderable,
<Child as ModelKey>::Key: crate::DefaultMeta,
ModelField<
Child,
<Child as ModelKey>::Key,
<<Child as ModelKey>::Key as crate::DefaultMeta>::Meta,
>: PrimaryKeyOrderFields<Child>,
{
MaxByOfMany {
relation: self,
column: column.column(),
_marker: PhantomData,
}
}
fn min_by<SortField, SortValue, SortMeta>(
self,
column: SortField,
) -> MinByOfMany<Self, Child, SortMeta>
where
Self: Sized,
Child: Qrafting + Draftable + ModelKey,
SortField: ReadableField<Child, SortValue, SortMeta>,
SortMeta: Orderable,
<Child as ModelKey>::Key: crate::DefaultMeta,
ModelField<
Child,
<Child as ModelKey>::Key,
<<Child as ModelKey>::Key as crate::DefaultMeta>::Meta,
>: PrimaryKeyOrderFields<Child>,
{
MinByOfMany {
relation: self,
column: column.column(),
_marker: PhantomData,
}
}
fn latest_by<SortField, SortValue, SortMeta>(
self,
column: SortField,
) -> MaxByOfMany<Self, Child, SortMeta>
where
Self: Sized,
Child: Qrafting + Draftable + ModelKey,
SortField: ReadableField<Child, SortValue, SortMeta>,
SortMeta: Orderable,
<Child as ModelKey>::Key: crate::DefaultMeta,
ModelField<
Child,
<Child as ModelKey>::Key,
<<Child as ModelKey>::Key as crate::DefaultMeta>::Meta,
>: PrimaryKeyOrderFields<Child>,
{
self.max_by(column)
}
fn oldest_by<SortField, SortValue, SortMeta>(
self,
column: SortField,
) -> MinByOfMany<Self, Child, SortMeta>
where
Self: Sized,
Child: Qrafting + Draftable + ModelKey,
SortField: ReadableField<Child, SortValue, SortMeta>,
SortMeta: Orderable,
<Child as ModelKey>::Key: crate::DefaultMeta,
ModelField<
Child,
<Child as ModelKey>::Key,
<<Child as ModelKey>::Key as crate::DefaultMeta>::Meta,
>: PrimaryKeyOrderFields<Child>,
{
self.min_by(column)
}
}
pub trait HasOne<Child>: Sized
where
Child: FromRow,
{
fn into_query(self) -> QueryOf<Child>;
fn query(self) -> QueryOf<Child> {
self.into_query()
}
fn one(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Child>> {
async move { self.into_query().one(exec).await }
}
fn optional(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Option<Child>>> {
async move { self.into_query().optional(exec).await }
}
fn filter<E>(self, expr: E) -> QueryOf<Child>
where
E: query::LowerFilter,
{
self.into_query().filter(expr)
}
fn or_filter<E>(self, expr: E) -> QueryOf<Child>
where
E: query::LowerFilter,
{
self.into_query().or_filter(expr)
}
fn order_by<T>(self, by: T) -> QueryOf<Child>
where
T: LowerOrderBy,
{
self.into_query().order_by(by)
}
fn order_by_random(self) -> QueryOf<Child> {
self.into_query().order_by_random()
}
fn limit<E>(self, expr: E) -> QueryOf<Child>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().limit(expr)
}
fn offset<E>(self, expr: E) -> QueryOf<Child>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().offset(expr)
}
fn distinct(self) -> QueryOf<Child> {
self.into_query().distinct()
}
fn not_distinct(self) -> QueryOf<Child> {
self.into_query().not_distinct()
}
fn with<C>(self, ctes: C) -> QueryOf<Child>
where
C: IntoCtes,
{
self.into_query().with(ctes)
}
fn with_recursive<C>(self, ctes: C) -> QueryOf<Child>
where
C: IntoCtes,
{
self.into_query().with_recursive(ctes)
}
fn untyped(self) -> Query {
self.into_query().untyped()
}
fn to_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_sql::<D>()
}
fn to_debug_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_debug_sql::<D>()
}
fn associate<'a>(self, child: &'a mut Child) -> <Child as Draftable>::Draft<'a>
where
Child: Draftable;
fn create<V>(self, values: V) -> Insert<Child>
where
Child: Qrafting,
V: Insertable<Child>;
}
pub trait MorphMany<Child>: Sized
where
Child: FromRow,
{
fn into_query(self) -> QueryOf<Child>;
fn query(self) -> QueryOf<Child> {
self.into_query()
}
fn all(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Vec<Child>>> {
async move { self.into_query().all(exec).await }
}
fn one(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Child>> {
async move { self.into_query().one(exec).await }
}
fn optional(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Option<Child>>> {
async move { self.into_query().optional(exec).await }
}
fn filter<E>(self, expr: E) -> QueryOf<Child>
where
E: query::LowerFilter,
{
self.into_query().filter(expr)
}
fn or_filter<E>(self, expr: E) -> QueryOf<Child>
where
E: query::LowerFilter,
{
self.into_query().or_filter(expr)
}
fn order_by<T>(self, by: T) -> QueryOf<Child>
where
T: LowerOrderBy,
{
self.into_query().order_by(by)
}
fn order_by_random(self) -> QueryOf<Child> {
self.into_query().order_by_random()
}
fn limit<E>(self, expr: E) -> QueryOf<Child>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().limit(expr)
}
fn offset<E>(self, expr: E) -> QueryOf<Child>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().offset(expr)
}
fn distinct(self) -> QueryOf<Child> {
self.into_query().distinct()
}
fn not_distinct(self) -> QueryOf<Child> {
self.into_query().not_distinct()
}
fn with<C>(self, ctes: C) -> QueryOf<Child>
where
C: IntoCtes,
{
self.into_query().with(ctes)
}
fn with_recursive<C>(self, ctes: C) -> QueryOf<Child>
where
C: IntoCtes,
{
self.into_query().with_recursive(ctes)
}
fn untyped(self) -> Query {
self.into_query().untyped()
}
fn to_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_sql::<D>()
}
fn to_debug_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_debug_sql::<D>()
}
fn associate<'a>(self, child: &'a mut Child) -> <Child as Draftable>::Draft<'a>
where
Child: Draftable;
fn create<V>(self, values: V) -> Insert<Child>
where
Child: Qrafting,
V: Insertable<Child>;
}
pub trait MorphOne<Child>: Sized
where
Child: FromRow,
{
fn into_query(self) -> QueryOf<Child>;
fn query(self) -> QueryOf<Child> {
self.into_query()
}
fn one(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Child>> {
async move { self.into_query().one(exec).await }
}
fn optional(
self,
exec: impl crate::quex::Executor,
) -> impl std::future::Future<Output = quex::Result<Option<Child>>> {
async move { self.into_query().optional(exec).await }
}
fn filter<E>(self, expr: E) -> QueryOf<Child>
where
E: query::LowerFilter,
{
self.into_query().filter(expr)
}
fn or_filter<E>(self, expr: E) -> QueryOf<Child>
where
E: query::LowerFilter,
{
self.into_query().or_filter(expr)
}
fn order_by<T>(self, by: T) -> QueryOf<Child>
where
T: LowerOrderBy,
{
self.into_query().order_by(by)
}
fn order_by_random(self) -> QueryOf<Child> {
self.into_query().order_by_random()
}
fn limit<E>(self, expr: E) -> QueryOf<Child>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().limit(expr)
}
fn offset<E>(self, expr: E) -> QueryOf<Child>
where
E: crate::LowerCompatible<BigInt>,
{
self.into_query().offset(expr)
}
fn distinct(self) -> QueryOf<Child> {
self.into_query().distinct()
}
fn not_distinct(self) -> QueryOf<Child> {
self.into_query().not_distinct()
}
fn with<C>(self, ctes: C) -> QueryOf<Child>
where
C: IntoCtes,
{
self.into_query().with(ctes)
}
fn with_recursive<C>(self, ctes: C) -> QueryOf<Child>
where
C: IntoCtes,
{
self.into_query().with_recursive(ctes)
}
fn untyped(self) -> Query {
self.into_query().untyped()
}
fn to_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_sql::<D>()
}
fn to_debug_sql<D: crate::HasDialect>(self) -> String {
self.into_query().to_debug_sql::<D>()
}
fn associate<'a>(self, child: &'a mut Child) -> <Child as Draftable>::Draft<'a>
where
Child: Draftable;
fn create<V>(self, values: V) -> Insert<Child>
where
Child: Qrafting,
V: Insertable<Child>;
}