Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions codegen/src/name_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ impl WorktableNameGenerator {
)
}

pub fn get_column_range_type_ident(&self) -> Ident {
Ident::new(
format!("{}ColumnRange", self.name).as_str(),
Span::mixed_site(),
)
}

pub fn get_work_table_ident(&self) -> Ident {
Ident::new(
format!("{}WorkTable", self.name).as_str(),
Expand Down
9 changes: 7 additions & 2 deletions codegen/src/worktable/generator/queries/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@ impl Generator {
fn gen_select_all(&mut self) -> TokenStream {
let name_generator = WorktableNameGenerator::from_table_name(self.name.to_string());
let row_ident = name_generator.get_row_type_ident();
let column_range_type = name_generator.get_column_range_type_ident();

quote! {
pub fn select_all<'a>(&'a self) -> SelectQueryBuilder<'a, #row_ident, Self> {
SelectQueryBuilder::new(&self)
pub fn select_all(&self) -> SelectQueryBuilder<#row_ident, impl DoubleEndedIterator<Item = #row_ident> + '_ + Sized, #column_range_type> {
let iter = self.0.pk_map
.iter()
.filter_map(|(_, link)| self.0.data.select(*link).ok());

SelectQueryBuilder::new(iter)
}
}
}
Expand Down
144 changes: 11 additions & 133 deletions codegen/src/worktable/generator/table/index_fns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ impl Generator {
let name_generator = WorktableNameGenerator::from_table_name(self.name.to_string());
let ident = name_generator.get_work_table_ident();
let row_ident = name_generator.get_row_type_ident();
let column_range_type = name_generator.get_column_range_type_ident();

let fn_defs = self
.columns
Expand All @@ -26,6 +27,7 @@ impl Generator {
idx,
&self.columns.columns_map,
row_ident.clone(),
&column_range_type,
)
}
})
Expand Down Expand Up @@ -63,6 +65,7 @@ impl Generator {
idx: &Index,
columns_map: &HashMap<Ident, TokenStream>,
row_ident: Ident,
column_range_type: &Ident,
) -> syn::Result<TokenStream> {
let type_ = columns_map
.get(i)
Expand All @@ -71,139 +74,14 @@ impl Generator {
let field_ident = &idx.name;

Ok(quote! {
pub fn #fn_name(&self, by: #type_) -> core::result::Result<SelectResult<#row_ident, Self>, WorkTableError> {
let rows = {
self.0.indexes.#field_ident.get(&by)
.map(|kv| *kv.1)
.collect::<Vec<_>>()
}.iter().map(|link| {
self.0.data.select(*link).map_err(WorkTableError::PagesError)
})
.collect::<Result<Vec<_>, _>>()?;
core::result::Result::Ok(SelectResult::<#row_ident, Self>::new(rows))
}
})
}

pub fn gen_select_where_fns(&self) -> syn::Result<TokenStream> {
let name_generator = WorktableNameGenerator::from_table_name(self.name.to_string());
let ident = name_generator.get_work_table_ident();
let row_ident = name_generator.get_row_type_ident();

let fn_defs = self
.columns
.indexes
.iter()
.map(|(i, idx)| {
let type_ = self
.columns
.columns_map
.get(i)
.ok_or(syn::Error::new(i.span(), "Row not found"))?;
if type_.to_string() == "String" {
return Ok(quote! {});
}
if idx.is_unique {
Self::gen_unique_select_where_fn(
i,
idx,
&self.columns.columns_map,
row_ident.clone(),
)
} else {
Self::gen_non_unique_select_where_fn(
i,
idx,
&self.columns.columns_map,
row_ident.clone(),
)
}
})
.collect::<Result<Vec<_>, syn::Error>>()?;

Ok(quote! {
impl #ident {
#(#fn_defs)*
}
})
}

fn gen_unique_select_where_fn(
i: &Ident,
idx: &Index,
columns_map: &HashMap<Ident, TokenStream>,
row_ident: Ident,
) -> syn::Result<TokenStream> {
let type_ = columns_map
.get(i)
.ok_or(syn::Error::new(i.span(), "Row not found"))?;
let fn_name = Ident::new(format!("select_where_{i}").as_str(), Span::mixed_site());
let field_ident = &idx.name;

Ok(quote! {
pub fn #fn_name(&self, range: impl std::ops::RangeBounds<#type_>) -> Option<Vec<#row_ident>> {

let start = match range.start_bound() {
std::ops::Bound::Included(val) => *val,
std::ops::Bound::Excluded(val) => *val + 1,
std::ops::Bound::Unbounded => #type_::MIN,
};

let end = match range.end_bound() {
std::ops::Bound::Included(val) => *val,
std::ops::Bound::Excluded(val) => *val - 1,
std::ops::Bound::Unbounded => #type_::MAX,
};

let rows = self.0.indexes.#field_ident
.range::<#type_, _>((std::ops::Bound::Included(&start), std::ops::Bound::Included(&end)))
.map(|(_key, link)| self.0.data.select(*link))
.collect::<Result<Vec<_>, _>>()
.ok()?;

if !rows.is_empty() {
Some(rows)
} else {
None
}
}
})
}

fn gen_non_unique_select_where_fn(
i: &Ident,
idx: &Index,
columns_map: &HashMap<Ident, TokenStream>,
row_ident: Ident,
) -> syn::Result<TokenStream> {
let type_ = columns_map
.get(i)
.ok_or(syn::Error::new(i.span(), "Row not found"))?;
let fn_name = Ident::new(format!("select_where_{i}").as_str(), Span::mixed_site());
let field_ident = &idx.name;

Ok(quote! {
pub fn #fn_name(&self, range: impl std::ops::RangeBounds<#type_>) -> core::result::Result<SelectResult<#row_ident, Self>, WorkTableError> {

let start = match range.start_bound() {
std::ops::Bound::Included(val) => *val,
std::ops::Bound::Excluded(val) => *val + 1,
std::ops::Bound::Unbounded => #type_::MIN,
};

let end = match range.end_bound() {
std::ops::Bound::Included(val) => *val,
std::ops::Bound::Excluded(val) => *val - 1,
std::ops::Bound::Unbounded => #type_::MAX,
};

let rows = self.0.indexes.#field_ident
.range((std::ops::Bound::Included(&start), std::ops::Bound::Included(&end)))
.map(|(_key, link)| { self.0.data.select(*link).map_err(WorkTableError::PagesError)
}).collect::<Result<Vec<_>, _>>()?;

core::result::Result::Ok(SelectResult::<#row_ident, Self>::new(rows))

pub fn #fn_name(&self, by: #type_) -> SelectQueryBuilder<#row_ident, impl DoubleEndedIterator<Item = #row_ident> + '_, #column_range_type> {
let rows: Vec<#row_ident> = self.0.indexes.#field_ident
.get(&by)
.into_iter()
.filter_map(|(_, link)| self.0.data.select(*link).ok())
.collect();

SelectQueryBuilder::new(rows.into_iter())
}
})
}
Expand Down
12 changes: 4 additions & 8 deletions codegen/src/worktable/generator/table/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,17 @@ impl Generator {
let default = self.gen_table_default();
let impl_ = self.gen_table_impl();
let index_fns = self.gen_table_index_fns()?;
let select_executor_impl = self.gen_table_select_executor_impl();
let select_result_executor_impl = self.gen_table_select_result_executor_impl();

let range = self.gen_select_where_fns()?;
let select_query_executor_impl = self.gen_table_select_query_executor_impl();
let column_range_type = self.gen_table_column_range_type();

Ok(quote! {
#page_size_consts
#type_
#default
#impl_
#index_fns
#select_executor_impl
#select_result_executor_impl

#range
#select_query_executor_impl
#column_range_type
})
}

Expand Down
Loading
Loading