Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Query builder #1780

Merged
merged 6 commits into from
Apr 8, 2022

Conversation

crajcan
Copy link
Contributor

@crajcan crajcan commented Apr 4, 2022

#291

I'm not sure how close this is to what was wanted.

Would love some feedback!

:)

* Make query_builder.rs in sqlx-core

* Add QueryBuilder::new()

* Add QueryBuilder::push()

* Define questions for documentation

* Get new, push, push_bind working with types

* Handle postgres' numbered bind varaibles

* Add a test for QueryBuilder#build

* Move arguments into Option

* Refactor query builder

* Finish testing QueryBuilder#build

* Remove design doc

* Add a test for pushing strings with push_bind

* Integration test green

* Adjust some tests

* Make query builder generic about placeholder segmenent ('$N' or '?')
Copy link
Collaborator

@abonander abonander left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a decent starting point but I have some nits.

@@ -16,6 +16,10 @@ pub trait Arguments<'q>: Send + Sized + Default {
fn add<T>(&mut self, value: T)
where
T: 'q + Send + Encode<'q, Self::Database> + Type<Self::Database>;

fn place_holder(&self, _argument_count: u16) -> String {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: argument_count shouldn't be necessary as the Arguments impl should already know how many arguments have been pushed. Personally, I also think "placeholder" should be one word, not two.

The intermediate String is also a wasted allocation. An alternative signature might look like this:

use std::fmt::{Self, Write};

fn format_placeholder<W: Write>(&self, mut writer: W) -> fmt::Result {
    writer.write_str("?")
}

and the Postgres implementation would look like this:

fn format_placeholder<W: Write>(&self, mut writer: W) -> fmt::Result {
    write!(writer, "${}", self.count)
}

QueryBuilder would then simply invoke it like:

// This is highly unlikely to return an error so panicking is fine.
arguments.format_placeholder(&mut self.query).expect("error in format_placeholder")

}

pub fn push(&mut self, sql: impl Display) -> &mut Self {
self.query.push_str(&format!(" {}", sql));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.query.push_str(&format!(" {}", sql));
// An error here is also highly unlikely but ignoring it is a code smell.
write!(self.query, " {}", sql).expect("error formatting `sql`");

It is a bit weird to insert a space automatically, though. What if someone is trying to concatenate an identifier using this method, or is building a string literal where formatting matters? This violates the principle of least surprise.

sqlx-core/src/query_builder.rs Show resolved Hide resolved
@crajcan crajcan requested a review from abonander April 8, 2022 20:08
Copy link
Collaborator

@abonander abonander left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks much better! I think this is a decent place to start.

@abonander
Copy link
Collaborator

Something that is missing though is some documentation. I can add that myself after merging unless you want to take a shot at it.

@crajcan
Copy link
Contributor Author

crajcan commented Apr 8, 2022

Something that is missing though is some documentation. I can add that myself after merging unless you want to take a shot at it.

If you feel motivated to do it, go ahead. I probably won't get to it until at least Monday otherwise.

@abonander abonander merged commit a470682 into launchbadge:master Apr 8, 2022
abonander added a commit that referenced this pull request Apr 9, 2022
elaborates on the API introduced in #1780
@OskarPersson
Copy link
Contributor

This doesn't seem to get passed through the compile time checks, is that correct?

@abonander
Copy link
Collaborator

@OskarPersson the latest commit is on a different feature branch for PR #1790, when this PR was merged it was passing CI.

@OskarPersson
Copy link
Contributor

@abonander Does that PR add compile time checks for queries created using this builder? (I'm not able to test that myself at the moment)

@abonander
Copy link
Collaborator

No, that's more in the purview of #1491 which may end up as a separate crate.

abonander added a commit that referenced this pull request Apr 11, 2022
elaborates on the API introduced in #1780
abonander added a commit that referenced this pull request Apr 11, 2022
elaborates on the API introduced in #1780
abonander added a commit that referenced this pull request Apr 11, 2022
elaborates on the API introduced in #1780
abonander added a commit that referenced this pull request Apr 11, 2022
elaborates on the API introduced in #1780
abonander added a commit that referenced this pull request Apr 11, 2022
elaborates on the API introduced in #1780
abonander added a commit that referenced this pull request Apr 11, 2022
elaborates on the API introduced in #1780
abonander added a commit that referenced this pull request Apr 11, 2022
elaborates on the API introduced in #1780
abonander added a commit that referenced this pull request Apr 11, 2022
elaborates on the API introduced in #1780
abonander added a commit that referenced this pull request Apr 11, 2022
elaborates on the API introduced in #1780
abonander added a commit that referenced this pull request Apr 12, 2022
elaborates on the API introduced in #1780
abonander added a commit that referenced this pull request Apr 12, 2022
elaborates on the API introduced in #1780
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants