fix: merge query with params

This commit is contained in:
Dmitriy Pleshevskiy 2021-02-19 22:17:01 +03:00
parent a7ab5572df
commit 7bd4f3d1f9
3 changed files with 45 additions and 26 deletions

View File

@ -4,6 +4,8 @@ pub trait ToSql {
fn to_sql(&self) -> String;
}
pub type ToSqlParams<'a> = &'a [&'a dyn ToSql];
impl ToSql for &str {
fn to_sql(&self) -> String {
format!("'{}'", self)
@ -21,11 +23,39 @@ pub trait OpenDatabaseConnection: Sized {
pub trait DatabaseConnection {
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>(
&mut self,
query: &str,
params: &'b [&'b dyn ToSql],
) -> StdResult<Vec<Vec<String>>>;
fn query<'b>(&mut self, query: &str, params: ToSqlParams<'b>) -> StdResult<Vec<Vec<String>>>;
}
pub(crate) fn merge_query_with_params(query: &str, params: ToSqlParams) -> 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'"
);
}
}

View File

@ -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()? {
SupportedDatabaseClient::Postgres => PostgresConnection::open(&connection_string)?,
};

View File

@ -1,4 +1,4 @@
use crate::database::{DatabaseConnection, OpenDatabaseConnection, ToSql};
use crate::database::*;
use crate::error::StdResult;
use postgres::{Client, NoTls};
@ -19,29 +19,15 @@ impl DatabaseConnection for PostgresConnection {
Ok(())
}
fn execute<'b>(&mut self, query: &str, params: &'b [&'b dyn ToSql]) -> StdResult<u64> {
let stmt = params
.iter()
.enumerate()
.fold(query.to_string(), |acc, (i, p)| {
str::replace(&acc, &format!("${}", i), &p.to_sql())
});
fn execute<'b>(&mut self, query: &str, params: ToSqlParams<'b>) -> StdResult<u64> {
let stmt = merge_query_with_params(query, params);
let res = self.client.execute(stmt.as_str(), &[])?;
Ok(res)
}
fn query<'b>(
&mut self,
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())
});
fn query<'b>(&mut self, query: &str, params: ToSqlParams<'b>) -> StdResult<Vec<Vec<String>>> {
let stmt = merge_query_with_params(query, params);
let res = self.client.query(stmt.as_str(), &[])?;