diff --git a/src/lib.rs b/src/lib.rs index 6df4a50..bf0ce12 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,8 @@ #[macro_use] extern crate static_assertions; -use self::{error::Result, http_client::HttpClient}; +use self::{error::Result, http_client::HttpClient, sql::Bind}; +use ::serde::Serialize; use std::{collections::HashMap, fmt::Display, sync::Arc}; pub use self::{compression::Compression, row::Row}; @@ -160,6 +161,12 @@ impl Client { self } + pub fn with_param(self, name: &str, value: impl Bind + Serialize) -> Result { + let mut param = String::from(""); + Bind::write(&value, &mut param)?; + Ok(self.with_option(format!("param_{name}"), param)) + } + /// Used to specify a header that will be passed to all queries. /// /// # Example diff --git a/src/query.rs b/src/query.rs index 926fdb5..7d02a60 100644 --- a/src/query.rs +++ b/src/query.rs @@ -1,5 +1,5 @@ use hyper::{header::CONTENT_LENGTH, Method, Request}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use std::fmt::Display; use url::Url; @@ -195,6 +195,12 @@ impl Query { self.client.add_option(name, value); self } + + pub fn with_param(self, name: &str, value: impl Bind + Serialize) -> Result { + let mut param = String::from(""); + Bind::write(&value, &mut param)?; + Ok(self.with_option(format!("param_{name}"), param)) + } } /// A cursor that emits rows. diff --git a/tests/it/query.rs b/tests/it/query.rs index 80e0158..5eb60ae 100644 --- a/tests/it/query.rs +++ b/tests/it/query.rs @@ -85,6 +85,31 @@ async fn fetch_one_and_optional() { assert_eq!(got_string, "bar"); } +#[tokio::test] +async fn server_side_param() { + let client = prepare_database!() + .with_param("val1", 42) + .expect("failed to bind 42"); + + let result = client + .query("SELECT plus({val1: Int32}, {val2: Int32}) AS result") + .with_param("val2", 144) + .expect("failed to bind 144") + .fetch_one::() + .await + .expect("failed to fetch u64"); + assert_eq!(result, 186); + + let result = client + .query("SELECT {val1: String} AS result") + .with_param("param_val1", "string") + .expect("failed to bind \"string\"") + .fetch_one::() + .await + .expect("failed to fetch string"); + assert_eq!(result, "string"); +} + // See #19. #[tokio::test] async fn long_query() {