Skip to content

Refactor paginating queries to a trait #751

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

Merged
merged 1 commit into from
Jul 7, 2017

Conversation

sgrif
Copy link
Contributor

@sgrif sgrif commented Jun 5, 2017

This pattern gets duplicated quite a bit (and it should be duplicated
even more since we still have places where we're doing more than one
query to paginate). Additionally, using the sql function will cause a
query to be removed from the prepared statement cache (since Diesel
doesn't know if the string was generated dynamically or not).

This moves it out into a trait, and represents a paginated query in a
bit more of an abstract form from the SQL point of view. This will
slightly change the SQL in the places that it's being used, so that it
looks more like what we have in src/krate_reverse_dependencies.sql,
applying the limit/offset as late as possible. This will not affect the
query plan unless they are using distinct, or if limit/offset are
called prior to paginate. Even if those cases do happen, this query is
probably what we meant anyway.

@sgrif sgrif force-pushed the sg-paginate-trait branch 2 times, most recently from a0a168a to f2ab630 Compare July 5, 2017 17:35
This pattern gets duplicated quite a bit (and it should be duplicated
even more since we still have places where we're doing more than one
query to paginate). Additionally, using the `sql` function will cause a
query to be removed from the prepared statement cache (since Diesel
doesn't know if the string was generated dynamically or not).

This moves it out into a trait, and represents a paginated query in a
bit more of an abstract form from the SQL point of view. This will
slightly change the SQL in the places that it's being used, so that it
looks more like what we have in `src/krate_reverse_dependencies.sql`,
applying the limit/offset as late as possible. This will not affect the
query plan unless they are using `distinct`, or if `limit`/`offset` are
called prior to `paginate`. Even if those cases do happen, this query is
probably what we meant anyway.
@sgrif sgrif force-pushed the sg-paginate-trait branch from f2ab630 to 6d7ab2e Compare July 6, 2017 00:29

if sort == "crates" {
query = query.order(keywords::crates_cnt.desc());
} else {
query = query.order(keywords::keyword.asc());
}

let data = query.load::<(Keyword, i64)>(&*conn)?;
let data = query.paginate(limit, offset).load::<(Keyword, i64)>(&*conn)?;
Copy link
Member

Choose a reason for hiding this comment

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

It's a little unfortunate that selecting the total number of results is now gone from this location, but we have to still remember to include the i64 type in the load type here. Not sure what to do differently though, maybe if we made a paginated_load that only took the types this code knows about and inserts the i64?

Not a huge deal, this PR is still a huge improvement for factoring out duplication and raw SQL everywhere, just a thought for a possible next step and/or if pagination becomes a more general diesel thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I doubt I'd add it to Diesel, but this could definitely be extracted to a crate. I have considered adding a method that lets you specify the type you're going to deserialize to outside of load. (The primary motivation is that Version::belonging_to(&crate).load::<Version> bugs me) If that were present, we could definitely have this be .paginate::<Keyword> and have the paginate method call that with (T, i64). I haven't explored how much work it'd be to add that method though

@carols10cents carols10cents merged commit e41e388 into rust-lang:master Jul 7, 2017
@sgrif sgrif deleted the sg-paginate-trait branch July 8, 2017 11:50
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