[SOLVED] Need help with Rust & MySQL

hello!

Hopefully there is someone who can help me a bit with my program :slight_smile:
here is the code: mysql-rust-query/main.rs at main 路 jhjacobs81/mysql-rust-query 路 GitHub

basicly, it gets a set of data from a database, puts it into a json format and sends it off to a web API. It works.

BUT, it uses a hard coded token (which is unique to each costumer) so we modified the database to include a token in each row. So now i need to figure out a way to get the tokens from the database (say, i have 100 rows devided between 3 tokens) then, for each separate token get all the rows that have that token, and format the json of it.

unfortunately there is no way for me to modify the json (different company) so hopefully someone knows what i try to explain? I first thought i could do this with the SQL query but i havent found anything that looks similar to what i try to do, lots of things about inner joins and sub query's etc.

So then i figure, maybe i should write a function called GetToken and a function called CreateJson, where GetToken gets all the tokens from the database, loops through them and calls upon CreateJson(1234567890) which then selects all the rows "WHERE token = '123456789'" and sends it off to the API?

is this possible?

EDIT 1:
i found this: How to select unique value in MySQL?
so i could do: select distinct Token from auditresults;

now i need to figure out how to loop through that and do another select

not quite sure I understand the question. What column in your SQL table corresponds to the token? Do you want data for just one at a time or all at once?

1 Like

thank you for answering :slight_smile:

we have 4 different tokens in our DB, they are mapped to the colum token.
So for each of those 4 tokens, i want all the data (select * from table where token = '1234') to put it in the json. normally i would alter my little program to include the token in the current json, but i cant change what the other side expects :frowning:

So basicly:

LET TokenID = get token from table {
foreach TokenID ( get other other data where column token equals TokenID )
build json shizzle here();
send json shizzle off here();
}

something like that?

Looking at the GitHub link, I think you are trying to aggregate Auditdata structs by token. You could accumulate in a HashMap

struct DataRow {
    token: i32,
    audit_data: Auditdata
}

// Make the selected_auditresults mutable so you can drain it
let mut selected_auditresults = conn
    .query_map(
//         Notice the token has been added here
         "SELECT token, id, title, actualvalue, expectedvalue, ok, flowid, clientid, fqdn FROM auditresults where inserted_at > now() - interval 1 day;",
        |(token id, title, actualvalue, expectedvalue, ok, flowid, clientid, fqdn)| {
            DataRow {
                token: token,
                audit_data: Auditdata { id, title, actualvalue, expectedvalue, ok, flowid, clientid, fqdn },
            }
            
         },
    ).unwrap();

use std::vec::Vec;
use std::collections::HashMap;

let mut aggregated = HashMap::<i32,Vec<Auditdata>>; // THIS GROUPS RESULTS BY TOKEN
for datarow in selected_auditresults.drain(0) {
    let token = datarow.token;
    aggregated
        .entry(token)           // Get the list for this token...
        .or_insert(Vec::new())  // .. or create it if it is a new token
        .push(datarow.audit_data);
}
1 Like

Thank you :slight_smile:
i incorporated it, and managed to fix some errors as well :slight_smile:
At the moment the last error i'm stuck with:

error[E0277]: the trait bound `{integer}: RangeBounds<usize>` is not satisfied
  --> src/main.rs:68:44
   |
68 | for datarow in selected_auditresults.drain(0) {
   |                                            ^ the trait `RangeBounds<usize>` is not implemented for `{integer}`
   |
   = help: the following implementations were found:
             <(Bound<&'a T>, Bound<&'a T>) as RangeBounds<T>>
             <(Bound<T>, Bound<T>) as RangeBounds<T>>
             <RangeFrom<&T> as RangeBounds<T>>
             <RangeFrom<T> as RangeBounds<T>>
           and 10 others

For more information about this error, try `rustc --explain E0277`.
error: could not compile `sync-v2` due to previous error

i tried rustc --explain E0277 but its not very clear to me :frowning:

== edit
i came across: RangeBounds in std::ops - Rust
but adding

use std::ops::Bound::*;
use std::ops::RangeBounds;

didn't work either just yet :slight_smile:

Sorry .drain() might not have been the best choice. try selected_auditresults.iter() or just for datarow in selected_auditresults. You may need to .clone()

1 Like

both of them return errors, but im googling them :wink: will keep you updated!

actually, the "for datarow in selected_auditresults" works :slight_smile:
i have a problem in my database which i missed!

edit ==
works like a charm!
however, it returns: {"1234567890": [Auditdata { id: "14500", title: ........... }]}
istead of {"token": "1234567890": [Auditdata { id: "14500", title: ........... }]}

So i tried changing .entry to: .entry(""token:":"{}",token) but this obviously doesnt work :slight_smile:

edit 2 ==

insert(
        "\"Token\"".to_string(),
        ":".to_string()
        );
        .entry(token)           // Get the list for this token...
        .or_insert(Vec::new())  // .. or create it if it is a new token
        .push(datarow.audit_data);
}

doesnt work either :frowning:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.