From e83cf0145d08e6270ce886ae3986075afdfecc16 Mon Sep 17 00:00:00 2001 From: gammelalf Date: Tue, 2 Jul 2024 21:00:08 +0200 Subject: [PATCH] Moved alias creation entirely into runtime --- src/internal/const_concat.rs | 40 ----------------------------- src/internal/query_context/mod.rs | 26 +++++++++++-------- src/internal/relation_path/impls.rs | 11 +++----- src/internal/relation_path/mod.rs | 11 +++----- 4 files changed, 22 insertions(+), 66 deletions(-) diff --git a/src/internal/const_concat.rs b/src/internal/const_concat.rs index e9aec9f..5a8ee55 100644 --- a/src/internal/const_concat.rs +++ b/src/internal/const_concat.rs @@ -91,46 +91,6 @@ impl ConstString<1024> { } } -impl ConstString<2048> { - pub(crate) const OOM_ERROR: Self = { - match ConstString::new().push_str("The error message is longer than 1024 bytes. Try using shorter names or contact the library authors.") { - Some(ok) => ok, - None => unreachable!(), // The error message is less than 2048 bytes - } - }; - - pub(crate) const fn join_alias(mut strings: &[&str]) -> Self { - let mut string = Self::new(); - - let [head, tail @ ..] = strings else { - return string; - }; - strings = tail; - match string.push_str(head) { - Some(some) => { - string = some; - } - None => { - return Self::OOM_ERROR; - } - } - - sugar! { - for slice in strings { - match string.push_str("__") { - Some(some) => match some.push_str(slice) { - Some(some) => {string = some;}, - None => return Self::OOM_ERROR, - } - None => return Self::OOM_ERROR, - } - - } - } - string - } -} - /// A contiguous growable array type for const expressions. /// /// ## Required invariant diff --git a/src/internal/query_context/mod.rs b/src/internal/query_context/mod.rs index 00d1875..950f739 100644 --- a/src/internal/query_context/mod.rs +++ b/src/internal/query_context/mod.rs @@ -38,8 +38,11 @@ impl<'v> QueryContext<'v> { /// Add a field to select returning its index and alias pub fn select_field(&mut self) -> (usize, String) { - P::add_to_context(self); - let alias = format!("{path}__{field}", path = P::ALIAS, field = F::NAME); + let alias = format!( + "{path}__{field}", + path = P::add_to_context(self), + field = F::NAME + ); self.selects.push(Select { table_name: PathId::of::

(), column_name: F::NAME, @@ -51,10 +54,9 @@ impl<'v> QueryContext<'v> { /// Add a field to aggregate returning its index and alias pub fn select_aggregation(&mut self) -> (usize, String) { - P::add_to_context(self); let alias = format!( "{path}__{field}___{func}", - path = P::ALIAS, + path = P::add_to_context(self), field = F::NAME, func = A::NAME, ); @@ -217,10 +219,11 @@ impl<'v> QueryContext<'v> { /// **Use [`Path::add_to_context`], this method is its impl detail!** /// /// Add the origin model to the builder - pub(crate) fn add_origin_path(&mut self) { + pub(crate) fn add_origin_path(&mut self) -> &'static str { self.join_aliases .entry(PathId::of::()) .or_insert_with(|| M::TABLE.to_string()); + M::TABLE } /// **Use [`Path::add_to_context`], this method is its impl detail!** @@ -228,17 +231,19 @@ impl<'v> QueryContext<'v> { /// Recursively add a relation path to the builder /// /// The generic parameters are the parameters defining the outer most [PathStep]. - pub(crate) fn add_relation_path(&mut self) + pub(crate) fn add_relation_path(&mut self) -> &str where F: Field + PathField<::Type>, P: Path::Model>, { let path_id = PathId::of::>(); if !self.join_aliases.contains_key(&path_id) { - P::add_to_context(self); - - let join_alias = as Path>::ALIAS; - self.join_aliases.insert(path_id, join_alias.to_string()); + let alias = format!( + "{field}__{path}", + field = F::NAME, + path = P::add_to_context(self) + ); + self.join_aliases.insert(path_id, alias); self.joins.push({ Join { table_name: <>::ChildField as Field>::Model::TABLE, @@ -252,6 +257,7 @@ impl<'v> QueryContext<'v> { FlatCondition::Column(PathId::of::

(), >::ParentField::NAME), ]); } + self.join_aliases.get(&path_id).unwrap() } } diff --git a/src/internal/relation_path/impls.rs b/src/internal/relation_path/impls.rs index 4328c4e..42edbeb 100644 --- a/src/internal/relation_path/impls.rs +++ b/src/internal/relation_path/impls.rs @@ -1,4 +1,3 @@ -use crate::internal::const_concat::ConstString; use crate::internal::field::foreign_model::{ForeignModelField, ForeignModelTrait}; use crate::internal::field::{Field, SingleColumnField}; use crate::internal::query_context::QueryContext; @@ -20,11 +19,9 @@ impl Path for M { F: Field + PathField<::Type>, F::ParentField: Field; - fn add_to_context(context: &mut QueryContext) { + fn add_to_context<'ctx>(context: &'ctx mut QueryContext) -> &'ctx str { context.add_origin_path::() } - - const ALIAS: &'static str = M::TABLE; } impl Path for (F, P) @@ -43,11 +40,9 @@ where F2: Field + PathField<::Type>, F2::ParentField: Field; - fn add_to_context(context: &mut QueryContext) { - context.add_relation_path::(); + fn add_to_context<'ctx>(context: &'ctx mut QueryContext) -> &'ctx str { + context.add_relation_path::() } - - const ALIAS: &'static str = ConstString::join_alias(&[P::ALIAS, F::NAME]).as_str(); } impl PathField> for F diff --git a/src/internal/relation_path/mod.rs b/src/internal/relation_path/mod.rs index 0b9d396..1ca9fa2 100644 --- a/src/internal/relation_path/mod.rs +++ b/src/internal/relation_path/mod.rs @@ -2,11 +2,9 @@ mod impls; -use crate::internal::field::Field; -use crate::internal::field::SingleColumnField; +use crate::internal::field::{Field, SingleColumnField}; use crate::internal::query_context::QueryContext; -use crate::sealed; -use crate::Model; +use crate::{sealed, Model}; /// Trait to store a relation path in generics /// @@ -82,10 +80,7 @@ pub trait Path: 'static { // SubPath: Path; /// Add all joins required to use this path to the query context - fn add_to_context(context: &mut QueryContext); - - /// Unique join alias - const ALIAS: &'static str; + fn add_to_context<'ctx>(context: &'ctx mut QueryContext) -> &'ctx str; } /// A field representing a db relation which can be used to construct paths.