Skip to content

Commit

Permalink
feat(query): add sql_display to show SQL (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
pravic authored Sep 24, 2024
1 parent b85d1df commit 75ce343
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 3 deletions.
6 changes: 6 additions & 0 deletions src/query.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use hyper::{header::CONTENT_LENGTH, Method, Request};
use serde::Deserialize;
use std::fmt::Display;
use url::Url;

use crate::headers::with_request_headers;
Expand Down Expand Up @@ -30,6 +31,11 @@ impl Query {
}
}

/// Display SQL query as string.
pub fn sql_display(&self) -> &impl Display {
&self.sql
}

/// Binds `value` to the next `?` in the query.
///
/// The `value`, which must either implement [`Serialize`] or be an
Expand Down
45 changes: 42 additions & 3 deletions src/sql/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::fmt::Display;
use std::fmt::{self, Display};

use crate::{
error::{Error, Result},
Expand All @@ -11,19 +11,38 @@ mod bind;
pub(crate) mod escape;
mod ser;

#[derive(Clone)]
#[derive(Debug, Clone)]
pub(crate) enum SqlBuilder {
InProgress(Vec<Part>),
Failed(String),
}

#[derive(Clone)]
#[derive(Debug, Clone)]
pub(crate) enum Part {
Arg,
Fields,
Text(String),
}

/// Display SQL query as string.
impl fmt::Display for SqlBuilder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SqlBuilder::InProgress(parts) => {
for part in parts {
match part {
Part::Arg => write!(f, "?")?,
Part::Fields => write!(f, "?fields")?,
Part::Text(text) => write!(f, "{text}")?,
}
}
}
SqlBuilder::Failed(err) => write!(f, "{err}")?,
}
Ok(())
}
}

impl SqlBuilder {
pub(crate) fn new(template: &str) -> Self {
let mut iter = template.split('?');
Expand Down Expand Up @@ -141,9 +160,29 @@ mod tests {
#[test]
fn bound_args() {
let mut sql = SqlBuilder::new("SELECT ?fields FROM test WHERE a = ? AND b < ?");
assert_eq!(
sql.to_string(),
"SELECT ?fields FROM test WHERE a = ? AND b < ?"
);

sql.bind_arg("foo");
assert_eq!(
sql.to_string(),
"SELECT ?fields FROM test WHERE a = 'foo' AND b < ?"
);

sql.bind_arg(42);
assert_eq!(
sql.to_string(),
"SELECT ?fields FROM test WHERE a = 'foo' AND b < 42"
);

sql.bind_fields::<Row>();
assert_eq!(
sql.to_string(),
"SELECT `a`,`b` FROM test WHERE a = 'foo' AND b < 42"
);

assert_eq!(
sql.finish().unwrap(),
r"SELECT `a`,`b` FROM test WHERE a = 'foo' AND b < 42"
Expand Down
11 changes: 11 additions & 0 deletions tests/it/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,3 +214,14 @@ async fn overrides_client_options() {
// should override the client options
assert_eq!(value, override_value);
}

#[tokio::test]
async fn prints_query() {
let client = prepare_database!();

let q = client.query("SELECT ?fields FROM test WHERE a = ? AND b < ?");
assert_eq!(
format!("{}", q.sql_display()),
"SELECT ?fields FROM test WHERE a = ? AND b < ?"
);
}

0 comments on commit 75ce343

Please sign in to comment.