Search code examples
postgresqlrustrust-diesel

How to add multiple sql_query binds at once?


I am using diesel crate to comunicate with a PostgreSQL database. I have a use case where i want to get data from table preferences into struct Preferences. I want the output from databse to be filterd by tow fields in the table, to have a specific value in column org_id and to be in group of values in column team_id which i store their values in unknown length array, so i can't do sql_query(raw_sql).bind::<>().execute() because i don't know the number of bind::<>() then I tried to use collect_binds but it didn't work, itried to do the following

let mut filter = "".to_string();
let mut params:Vec<i64> = vec![];
let mut c =1;
let org_id = 10;

filter.push_str("(org_id=$1 AND team_id IN (");
params.push(org_id);
for team_id in get_needed_teams_id(){
     c = c +1;
     filter.push_str(&*format!("${}", c));
     params.push(team_id );
}
filter.push_str("))");


let raw_sql = format!("SELECT * FROM preferences WHERE {} ORDER BY user_id ASC, team_id ASC", filter);

let preferences:Vec<Preferences> = vec![];
let sql_res = sql_query(raw_sql).collect_binds(&mut param, &preferences);

Error returned :

error[E0284]: type annotations needed: cannot satisfy `<_ as Backend>::BindCollector == Vec<i64>`
   --> src\db\preference_db.rs:146:38
    |
146 |     let sql_res = sql_query(raw_sql).collect_binds(&mut params, &preferences);
    |                                      ^^^^^^^^^^^^^ cannot satisfy `<_ as Backend>::BindCollector == Vec<i64>`

Solution

  • There is currently no way in diesel to bind multiple parameters at once in a loop. collect_binds is entirely unconnected to this and exported by the QueryFragment trait. It can be used by the database connection implementation to receive a list of bind parameters for a given query, not to construct a query.