Im trying to use sqlx to get data from a mysql db. I have the following:
#[derive(Debug, PartialEq, Eq, sqlx::FromRow)]
struct Room {
name: String
}
let mut stream = sqlx::query_as::<_, Room>(r#"SELECT name FROM rooms"#)
.fetch_all(&db.pool).await;
for row in stream {
println!("{:?}",row);
}
So in stream there is a vector and each index seems to hold the actual query results. So
stream[0] = [Room{name: "Room 1"}, Room{name: "Room 3"}, Room{name: "Room 2"}]
So in order to get at that data i have to loop through stream[0]. Is there a way to have that data on the value returned from the query without the explicit index?
Use Query::fetch() (this will return a stream of results, fetching the next one as needed) instead of Query::fetch_all() (this will return a vec of all results, fetching them all before hand), and then loop over the result stream.
Like so:
let mut stream = sqlx::query_as::<_, Room>(r#"SELECT name FROM rooms"#)
.fetch(&db.pool);
stream.for_each(|room| println!("{:#?}", room));
Alternatively, you can use a while loop to print, but you may need to Pin your stream before calling next().
while let Some(room) = stream.next().await {
println! ("{:#?}", room);
}
Related
Actually I'm returing a cloned struct
pub fn matrix_first_or_create(&self, schema: String, symbol: String) -> RewardMatrix {
....
let rewards = reward_matrix
.filter(state.eq(schema.clone()))
.filter(turn_symbol.eq(symbol.clone()))
.limit(1)
.load::<RewardMatrix>(&self.connection)
.expect("Error loading posts");
if rewards.len() > 0 {
return rewards.get(0).unwrap().clone();
}
....
}
Is this the right way to handle a result in Diesel? Can I "extract" and own the first and only result from this query?
What you need here is the .first() method of the RunQueryDsl trait.
Here is an example of how it works:
let reward: RewardMatrix = reward_matrix
.filter(state.eq(schema.clone()))
.filter(turn_symbol.eq(symbol.clone()))
.first(&self.connection)?;
But if your query may not return that row, it’s also good to use the .optional() method of QueryResult:
let reward: Option<RewardMatrix> = reward_matrix
.filter(state.eq(schema.clone()))
.filter(turn_symbol.eq(symbol.clone()))
.first(&self.connection)
.optional()?;
load returns a simple owned Vec<RewardMatrix>, so any solution for getting an owned element from a Vec works here:
if let Some(reward) = rewards.into_iter().next() {
return reward;
}
but Diesel also provides better-suited alternatives like get_result and first that don’t involve Vec at all (combine with optional as recommended in the documentation):
let reward = reward_matrix
.filter(state.eq(&schema))
.filter(turn_symbol.eq(&symbol))
.first::<RewardMatrix>(&self.connection)
.optional()
.expect("Error loading posts");
if let Some(reward) = reward {
return reward;
}
I am trying to write a mail filter in Rust using the milter crate. I built the example on a Linux VM and it all works fine. However, the example is using u32 as the type of context injected into their handlers, a quite simple example. I instead need to store a string from the handle_header callback through to the handle_eom handler so I can use an incoming header to set the envelope from.
If I log the value of the header in handle_header to console, it writes correctly but by the time it arrives in handle_eom, it has been corrupted/overwritten whatever. I thought that context was supposed to be specifically for this scenario but it seems weird that it uses type inference rather than e.g. a pointer to an object that you can just assign whatever you want to it.
Is my understanding of context wrong or is the code incorrect?
I tried using value and &value in handle_header and it behaves the same way.
use milter::*;
fn main() {
Milter::new("inet:3000#localhost")
.name("BounceRewriteFilter")
.on_header(header_callback)
.on_eom(eom_callback)
.on_abort(abort_callback)
.actions(Actions::ADD_HEADER | Actions::REPLACE_SENDER)
.run()
.expect("milter execution failed");
}
#[on_header(header_callback)]
fn handle_header<'a>(mut context: Context<&'a str>, header: &str, value: &'a str) -> milter::Result<Status> {
if header == "Set-Return-Path" {
match context.data.borrow_mut() {
Some(retpath) => *retpath = &value,
None => {
context.data.replace(value)?;
}
}
}
Ok(Status::Continue)
}
#[on_eom(eom_callback)]
fn handle_eom(mut context: Context<&str>) -> milter::Result<Status> {
match context.data.take() {
Ok(result) => {
println!("Set-return-path header is {}", result.unwrap());
context.api.replace_sender(result.unwrap(), None::<&str>)?;
}
Err(_error) => {}
}
Ok(Status::Continue)
}
Thanks to glts on Github, the author of the crate, the problem was that the string slices passed into the handle_header method were not borrowed by the external code that stores the data pointer so by the time that handle_eom is called, the memory has been reused for something else.
All I had to do was change Context<&str> to Context<String> and convert the strings using mystr.to_owned() and in the reverse direction val = &*mystring
i've created my first substrate project successful and the built pallet also works fine. Now i wanted to create tests for the flow and the provided functions.
My flow is to generate a random hash and store this hash associated to the sender of the transaction
let _sender = ensure_signed(origin)?;
let nonce = Nonce::get();
let _random_seed = <randomness_collective_flip::Module<T>>::random_seed();
let random_hash = (_random_seed, &_sender, nonce).using_encoded(T::Hashing::hash);
ensure!(!<Hashes<T>>::contains_key(random_hash), "This new id already exists");
let _now = <timestamp::Module<T>>::get();
let new_elem = HashElement {
id: random_hash,
parent: parent,
updated: _now,
created: _now
};
<Hashes<T>>::insert(random_hash, new_pid);
<HashOwner<T>>::insert(random_hash, &_sender);
Self::deposit_event(RawEvent::Created(random_hash, _sender));
Ok(())
works good so far, when now i want to test the flow with a written test, i want to check if the hash emitted in the Created event is also assigned in the HashOwner Map. For this i need to get the value out of the event back.
And this is my problem :D i'm not professional in rust and all examples i found are expecting all values emitted in the event like this:
// construct event that should be emitted in the method call directly above
let expected_event = TestEvent::generic_event(RawEvent::EmitInput(1, 32));
// iterate through array of `EventRecord`s
assert!(System::events().iter().any(|a| a.event == expected_event));
When debugging my written test:
assert_ok!(TemplateModule::create_hash(Origin::signed(1), None));
let events = System::events();
let lastEvent = events.last().unwrap();
let newHash = &lastEvent.event;
i see in VSCode that the values are available:
debug window of vs code
but i dont know how to get this Hash in a variable back... maybe this is only a one liner ... but my rust knowledge is damn too small :D
thank you for your help
Here's a somewhat generic example of how to parse and check events, if you only care about the last event that your module put in system and nothing else.
assert_eq!(
System::events()
// this gives you an EventRecord { event: ..., ...}
.into_iter()
// map into the inner `event`.
.map(|r| r.event)
// the inner event is like `OuterEvent::mdouleEvent(EventEnum)`. The name of the outer
// event comes from whatever you have placed in your `delc_event! {}` in test mocks.
.filter_map(|e| {
if let MetaEvent::templateModule(inner) = e {
Some(inner)
} else {
None
}
})
.last()
.unwrap(),
// RawEvent is defined and imported in the template.rs file.
// val1 and val2 are things that you want to assert against.
RawEvent::Created(val1, val2),
);
Indeed you can also omit the first map or do it in more compact ways, but I have done it like this so you can see it step by step.
Print the System::events(), this also helps.
I now got it from the response of kianenigma :)
I wanted to reuse the given data in the event:
let lastEvent = System::events()
// this gives you an EventRecord { event: ..., ...}
.into_iter()
// map into the inner `event`.
.map(|r| r.event)
// the inner event is like `OuterEvent::mdouleEvent(EventEnum)`. The name of the outer
// event comes from whatever you have placed in your `delc_event! {}` in test mocks.
.filter_map(|e| {
if let TestEvent::pid(inner) = e {
Some(inner)
} else {
None
}
})
.last()
.unwrap();
if let RawEvent::Created(newHash, initiatedAccount) = lastEvent {
// there are the values :D
}
this can maybe be written better but this helps me :)
I need to process a slice of bytes into fixed chunks, but the chunk pattern is only known at runtime:
pub fn process(mut message: &[u8], pattern: &[Pattern]) {
for element in pattern: {
match element {
(...) => {
let (chunk, message2) = message.split_at(element.size);
/* process chunk */
message = message2;
},
// ...
}
}
}
It feels awkward to have to use this message2. But if I do
let (chunk, message) = message.split_at(element.size);
Then it does not work, I assume because this actually creates a new messages binding that goes out of scope between loop iterations.
Is there a more elegant way to do this?
You are correct in your reasoning that let (chunk, message) = message.split_at(element.size); creates a new binding message within that scope and does not update the outer message value.
What you are looking for is a 'destructuring assignment' of the tuple. This would allow tuple elements to be assigned to existing variable bindings instead of creating new bindings, something like:
let chunk;
(chunk, message) = message.split_at(element.size);
Unfortunately this is currently not possible in Rust. You can see a pre-RFC which proposes to add destructuring assignment to the Rust language.
I believe what you currently have is a perfectly fine solution, perhaps rename message2 to something like rest_of_message or remaining_message.
I would like to parse a web page, insert anchors at certain positions and render the modified DOM out again in order to generate docsets for Dash. Is this possible?
From the examples included in html5ever, I can see how to read an HTML file and do a poor man's HTML output, but I don't understand how I can modify the RcDom object I retrieved.
I would like to see a snippet inserting an anchor element (<a name="foo"></a>) to an RcDom.
Note: this is a question regarding Rust and html5ever specifically ... I know how to do it in other languages or simpler HTML parsers.
Here is some code that parses a document, adds an achor to the link and prints the new document:
extern crate html5ever;
use html5ever::{ParseOpts, parse_document};
use html5ever::tree_builder::TreeBuilderOpts;
use html5ever::rcdom::RcDom;
use html5ever::rcdom::NodeEnum::Element;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;
fn main() {
let opts = ParseOpts {
tree_builder: TreeBuilderOpts {
drop_doctype: true,
..Default::default()
},
..Default::default()
};
let data = "<!DOCTYPE html><html><body></body></html>".to_string();
let dom = parse_document(RcDom::default(), opts)
.from_utf8()
.read_from(&mut data.as_bytes())
.unwrap();
let document = dom.document.borrow();
let html = document.children[0].borrow();
let body = html.children[1].borrow(); // Implicit head element at children[0].
{
let mut a = body.children[0].borrow_mut();
if let Element(_, _, ref mut attributes) = a.node {
attributes[0].value.push_tendril(&From::from("#anchor"));
}
}
let mut bytes = vec![];
serialize(&mut bytes, &dom.document, SerializeOpts::default()).unwrap();
let result = String::from_utf8(bytes).unwrap();
println!("{}", result);
}
This prints the following:
<html><head></head><body></body></html>
As you can see, we can navigate through the child nodes via the children attribute.
And we can change an attribute present in the vector of attributes of an Element.