Working with crate postgres and r2d2_postgres

Here's my insert statement:

let insert_query: (&str, &[&str]) = (
                "INSERT INTO multicast_bgproute (cd_id, route, peer, age, net_mask, missing) VALUES ((select id from multicast_contentdevices WHERE ip_address= $1), $2, $3, $4, $5, $6) ON CONFLICT  (cd_id, route, peer, net_mask) DO UPDATE SET age = $7",
                &[&address, &route, &peer, &age, &netmask, &missing, &age]
            );

I pass it to here:

pub fn insert(&self, qs: (&'static str, &[&str])) {
            let mut tasks = vec![];
                for _ in 0..20 {
                    let mut pool = self.pool.clone();
                    let i = qs.0.clone();
                    let params = qs.1.clone();
                    let th = thread::spawn(move || {
                        let mut client = pool.get().unwrap();
                        client.execute(i, &[params]).unwrap();
                    });
                    tasks.push(th);
                }
            for th in tasks {
                let _ = th.join();
            }
        }

I just can't get the params to work.

error[E0277]: the trait bound `[&str]: ToSql` is not satisfied
  --> /home/mitch/CLionProjects/psql/src/lib.rs:45:45
   |
45 |                         client.execute(i, &[params]).unwrap();
   |                                             ^^^^^^ the trait `ToSql` is not implemented for `[&str]`
   |
   = help: the following implementations were found:
             <&'a [T] as ToSql>
             <&'a [u8] as ToSql>
   = note: required for the cast to the object type `dyn ToSql + Sync`

Also, I could use a time stamp in that query, but I don't know how to get time as a String/&str in Rust.

Have a look at the docs. It says that ToSql has been implemented for &str and String, among other types. params has a type of &[&str]. If you check the signature of execute here, it is as follows:

    pub fn execute<T>(&mut self, query: &T, 
                      params: &[&(dyn ToSql + Sync)]) 
                      -> Result<u64, Error>
    where
        T: ?Sized + ToStatement,

Thus, you need to pass params to execute, instead of &[params].
As for the timestamp, it too has a ToSql implementation, so I expect you can pass it directly. In general, good Rust libraries take parameters directly, not via conversion to String.
Also, since you seem to be using CLion, it will be very helpful to turn on inlay hints. Instructions can be found here.

Actually, I think I had several problems. Coming from a Python and duck typing is just one. So I thought I could just pass whatever type I wanted, such as an IP address as a &str, and it would work just fine. I ended up creating a struct for my parameters as that was the only container I know of that supports multiple types, as shown below. Worked like a champ! Thanks for the inlay hints tip.

    pub struct Route {
        pub address: IpAddr,
        pub prefix: IpAddr,
        pub net_mask: IpAddr,
        pub peer: IpAddr,
        pub age: i64,
        pub last_seen: std::time::SystemTime,
        pub missing: bool,
    }

pub fn insert(&self, insert: &'static str, params: Route) {
...
client.execute(i,
                                       &[&params.address,
                                                &params.prefix,
                                                &params.peer,
                                                &params.age,
                                                &params.net_mask,
                                                &params.last_seen,
                                                &params.missing,
                                                &params.last_seen,
                                                &params.age]).unwrap();

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.