diff --git a/examples/rdb-contract/src/lib.rs b/examples/rdb-contract/src/lib.rs index ce4bd5153..509cd1c91 100644 --- a/examples/rdb-contract/src/lib.rs +++ b/examples/rdb-contract/src/lib.rs @@ -202,16 +202,16 @@ mod tests { person_query.trusted = Some(true); let mut person_query_protocol: person::Protocol = person_query.into(); assert!(person_query_protocol.filter); - person_query_protocol.set_select_fields(vec!["age".to_string()]); + person_query_protocol.set_select_fields(vec!["id".to_string(), "age".to_string()]); // The expected result only return the age of the trusted person, // and other fields will be None - expect_output = vec![older_person].into(); + expect_output = vec![(1, older_person)].into(); expect_output.records[0].trusted = None; ewasm_auto_assert_eq!(person::get(person_query_protocol), expect_output); // Get the children by the customized handler - expect_output = vec![child].into(); + expect_output = vec![(2, child)].into(); ewasm_auto_assert_eq!(get_children(), expect_output); // Please Notice that protocol from the default instance may not be empty, diff --git a/sewup-derive/src/lib.rs b/sewup-derive/src/lib.rs index ec5edc2a3..4e0820c26 100644 --- a/sewup-derive/src/lib.rs +++ b/sewup-derive/src/lib.rs @@ -784,6 +784,7 @@ pub fn derive_table(item: TokenStream) -> TokenStream { let clone_field_names2 = field_names.clone(); let clone_field_names3 = field_names.clone(); let clone_field_names4 = field_names.clone(); + let clone_field_names5 = field_names.clone(); let field_types = fields_with_type.iter().map(|(_, t)| t); let protocol_name = Ident::new(&format!("{}Protocol", struct_name), Span::call_site()); @@ -829,6 +830,7 @@ pub fn derive_table(item: TokenStream) -> TokenStream { } } } + impl From<#struct_name> for #protocol_name { fn from(instance: #struct_name) -> Self { Self { @@ -839,6 +841,16 @@ pub fn derive_table(item: TokenStream) -> TokenStream { } } + impl From<(usize, #struct_name)> for #protocol_name { + fn from(instance: (usize, #struct_name)) -> Self { + Self { + select_fields: None, + filter: false, + records: vec![instance.into()] + } + } + } + impl From> for #protocol_name { fn from(instances: Vec<#struct_name>) -> Self { Self { @@ -848,6 +860,17 @@ pub fn derive_table(item: TokenStream) -> TokenStream { } } } + + impl From> for #protocol_name { + fn from(instances: Vec<(usize, #struct_name)>) -> Self { + Self { + select_fields: None, + filter: false, + records: instances.into_iter().map(|i| i.into()).collect::>() + } + } + } + impl From> for #protocol_name { fn from(records: Vec<#wrapper_name>) -> Self { Self { @@ -857,6 +880,7 @@ pub fn derive_table(item: TokenStream) -> TokenStream { } } } + pub mod #captal_name { use sewup_derive::ewasm_fn_sig; pub const GET_SIG: [u8; 4] = ewasm_fn_sig!(#struct_name::get()); @@ -869,6 +893,7 @@ pub fn derive_table(item: TokenStream) -> TokenStream { pub struct #wrapper_name { #(pub #wrapper_field_names: #wrapper_field_types,)* } + impl From<#struct_name> for #wrapper_name { fn from(instance: #struct_name) -> Self { Self { @@ -877,6 +902,16 @@ pub fn derive_table(item: TokenStream) -> TokenStream { } } } + + impl From<(usize, #struct_name)> for #wrapper_name { + fn from(t: (usize, #struct_name)) -> Self { + Self { + id: Some(t.0), + #(#clone_field_names5: Some(t.1.#clone_field_names5),)* + } + } + } + impl From<#wrapper_name> for #struct_name { fn from(wrapper: #wrapper_name) -> Self { Self { @@ -894,7 +929,7 @@ pub fn derive_table(item: TokenStream) -> TokenStream { let table = sewup::rdb::Db::load(None)?.table::<_InstanceType>()?; if proc.filter { let mut raw_output: Vec = Vec::new(); - for r in table.all_records()?.drain(..){ + for (idx, r) in table.all_records()?.drain(..).enumerate(){ let mut all_field_match = true; #( paste::paste! { @@ -913,17 +948,17 @@ pub fn derive_table(item: TokenStream) -> TokenStream { )* if all_field_match { - let mut wrapper: Wrapper = r.into(); - raw_output.push(wrapper); + raw_output.push((idx + 1, r).into()); } } if let Some(select_fields) = proc.select_fields { for w in raw_output.iter_mut() { #( - if ! select_fields.contains(stringify!(#clone_field_names3)) { + if (! select_fields.contains(stringify!(#clone_field_names3))) + && stringify!(#clone_field_names3) != "id" { w.#clone_field_names3 = None; } - )* + )* } } let p: #protocol_name = raw_output.into(); diff --git a/sewup/src/rdb/table.rs b/sewup/src/rdb/table.rs index 4b1a3fd9a..b163b3737 100644 --- a/sewup/src/rdb/table.rs +++ b/sewup/src/rdb/table.rs @@ -62,14 +62,14 @@ impl Table { #[allow(bare_trait_objects)] /// Filter the records - pub fn filter_records(&self, filter: &Fn(&T) -> bool) -> Result> { - let mut output: Vec = Vec::new(); - for r in self.data.iter() { + pub fn filter_records(&self, filter: &Fn(&T) -> bool) -> Result> { + let mut output: Vec<(usize, T)> = Vec::new(); + for (idx, r) in self.data.iter().enumerate() { let mut buffer_row = r.clone(); buffer_row.make_buffer(); if let Some(i) = T::from_row(&buffer_row) { if filter(&i) { - output.push(i); + output.push((idx + 1, i)); } } }