fix: merge query with params
This commit is contained in:
parent
a7ab5572df
commit
7bd4f3d1f9
3 changed files with 45 additions and 26 deletions
|
@ -4,6 +4,8 @@ pub trait ToSql {
|
||||||
fn to_sql(&self) -> String;
|
fn to_sql(&self) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type ToSqlParams<'a> = &'a [&'a dyn ToSql];
|
||||||
|
|
||||||
impl ToSql for &str {
|
impl ToSql for &str {
|
||||||
fn to_sql(&self) -> String {
|
fn to_sql(&self) -> String {
|
||||||
format!("'{}'", self)
|
format!("'{}'", self)
|
||||||
|
@ -21,11 +23,39 @@ pub trait OpenDatabaseConnection: Sized {
|
||||||
pub trait DatabaseConnection {
|
pub trait DatabaseConnection {
|
||||||
fn batch_execute(&mut self, query: &str) -> StdResult<()>;
|
fn batch_execute(&mut self, query: &str) -> StdResult<()>;
|
||||||
|
|
||||||
fn execute<'b>(&mut self, query: &str, params: &'b [&'b dyn ToSql]) -> StdResult<u64>;
|
fn execute<'b>(&mut self, query: &str, params: ToSqlParams<'b>) -> StdResult<u64>;
|
||||||
|
|
||||||
fn query<'b>(
|
fn query<'b>(&mut self, query: &str, params: ToSqlParams<'b>) -> StdResult<Vec<Vec<String>>>;
|
||||||
&mut self,
|
}
|
||||||
query: &str,
|
|
||||||
params: &'b [&'b dyn ToSql],
|
pub(crate) fn merge_query_with_params(query: &str, params: ToSqlParams) -> String {
|
||||||
) -> StdResult<Vec<Vec<String>>>;
|
params
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.fold(query.to_string(), |acc, (i, p)| {
|
||||||
|
str::replace(&acc, &format!("${}", i + 1), &p.to_sql())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn merge_query_with_params_successfully() {
|
||||||
|
assert_eq!(
|
||||||
|
merge_query_with_params("SELECT $1", &[&"foo"]),
|
||||||
|
"SELECT 'foo'"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
merge_query_with_params("SELECT $1, $2", &[&"foo", &"bar"]),
|
||||||
|
"SELECT 'foo', 'bar'"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
merge_query_with_params("SELECT $1, $1", &[&"foo"]),
|
||||||
|
"SELECT 'foo', 'foo'"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,10 @@ impl DatabaseConnectionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connect_with_string(&self, connection_string: &str) -> StdResult<Box<dyn DatabaseConnection>> {
|
pub fn connect_with_string(
|
||||||
|
&self,
|
||||||
|
connection_string: &str,
|
||||||
|
) -> StdResult<Box<dyn DatabaseConnection>> {
|
||||||
let conn = match self.config.client()? {
|
let conn = match self.config.client()? {
|
||||||
SupportedDatabaseClient::Postgres => PostgresConnection::open(&connection_string)?,
|
SupportedDatabaseClient::Postgres => PostgresConnection::open(&connection_string)?,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::database::{DatabaseConnection, OpenDatabaseConnection, ToSql};
|
use crate::database::*;
|
||||||
use crate::error::StdResult;
|
use crate::error::StdResult;
|
||||||
use postgres::{Client, NoTls};
|
use postgres::{Client, NoTls};
|
||||||
|
|
||||||
|
@ -19,29 +19,15 @@ impl DatabaseConnection for PostgresConnection {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute<'b>(&mut self, query: &str, params: &'b [&'b dyn ToSql]) -> StdResult<u64> {
|
fn execute<'b>(&mut self, query: &str, params: ToSqlParams<'b>) -> StdResult<u64> {
|
||||||
let stmt = params
|
let stmt = merge_query_with_params(query, params);
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.fold(query.to_string(), |acc, (i, p)| {
|
|
||||||
str::replace(&acc, &format!("${}", i), &p.to_sql())
|
|
||||||
});
|
|
||||||
|
|
||||||
let res = self.client.execute(stmt.as_str(), &[])?;
|
let res = self.client.execute(stmt.as_str(), &[])?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn query<'b>(
|
fn query<'b>(&mut self, query: &str, params: ToSqlParams<'b>) -> StdResult<Vec<Vec<String>>> {
|
||||||
&mut self,
|
let stmt = merge_query_with_params(query, params);
|
||||||
query: &str,
|
|
||||||
params: &'b [&'b dyn ToSql],
|
|
||||||
) -> StdResult<Vec<Vec<String>>> {
|
|
||||||
let stmt = params
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.fold(query.to_string(), |acc, (i, p)| {
|
|
||||||
str::replace(&acc, &format!("${}", i), &p.to_sql())
|
|
||||||
});
|
|
||||||
|
|
||||||
let res = self.client.query(stmt.as_str(), &[])?;
|
let res = self.client.query(stmt.as_str(), &[])?;
|
||||||
|
|
||||||
|
|
Reference in a new issue