-
Notifications
You must be signed in to change notification settings - Fork 645
Port crates#index
to use Diesel
#609
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
Conversation
} | ||
|
||
impl<'a> NewCrate<'a> { | ||
pub fn create_or_update( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the same functionality as find_or_insert
, but with a more clear name, and using Diesel. It's only used in tests currently.
src/krate.rs
Outdated
let (offset, limit) = req.pagination(10, 100)?; | ||
let query = req.query(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend using split diff here.
One thing that I didn't do here, but would be pretty easy to add if we want it is the ability to compose the branches in And by pretty easy I mean that it's literally just removing the |
f635d52
to
d9bfcdd
Compare
I decided to tackle this one next since we have an N+1 queries bug on the max versions, it's a relatively high traffic endpoint, and the code benefitted the most from Diesel. There was probably more code added to support migrating the tests over than to support the actual `index` function, but all those pieces will start to get used as more endpoints are ported over. There were a few tests that were hitting the followings and owners endpoints which I have temporarily changed to hit the database directly instead. Porting those endpoints would mean porting over more tests, which might mean porting over more endpoints, etc. We didn't lose any coverage overall, but we should still go back to hitting the endpoints directly in tests when we can.
All the methods which do >1 query which modifies data should be wrapped in a transaction
We should do this all over the application, as there's tons of endpoints which are doing a separate query for the count when a window function would achieve the same thing more efficiently.
d9bfcdd
to
8d5b143
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the tests that are hitting the database instead of the endpoints, but it looks to me like they're not really testing the same things? I could be convinced that this is ok if it's going to be temporary, just wanted to check that it's what you were intending.
@@ -0,0 +1 @@ | |||
ALTER TABLE versions ALTER COLUMN yanked SET NOT NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just checked to be sure: 0 records in production versions have yanked IS NULL
src/krate.rs
Outdated
let max_version = krate.max_version(conn)?; | ||
crates.push(krate.minimal_encodable(max_version, Some(badges))); | ||
let mut query = crates_query(¶ms, req.user())?; | ||
let sort = params.get("sort").map(|s| &**s).unwrap_or("alpha"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love how the sorting is all in one place now 😻
.with_query(&query))); | ||
assert_eq!(::json::<CrateList>(&mut response).crates.len(), 1); | ||
// FIXME: Once owner endpoints use diesel, go back to hitting the real endpoint | ||
assert_eq!(1, req.tx().unwrap().query("SELECT COUNT(*) FROM crate_owners |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this FIXME test is still doing an assertion...
req.with_path("/api/v1/crates/foo_following/following") | ||
.with_method(Method::Get); | ||
let mut response = ok_resp!(middle.call(&mut req)); | ||
assert!(::json::<F>(&mut response).following); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... but this assertion looks commented out....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So basically this endpoint is tested elsewhere, and I'm assuming that ?following=1
is enough to generally verify this behavior, especially since I'm planning on hitting the following endpoints next after this is merged.
// FIXME: Go back to hitting the actual endpoint once it's using Diesel | ||
req.db_conn().unwrap() | ||
.execute("TRUNCATE TABLE follows") | ||
.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test that's hitting the database instead of the endpoint looks like it's doing a lot more than the endpoint does...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm assuming that the table was empty when the test started running.
req.with_path("/api/v1/crates/foo_following/following") | ||
.with_method(Method::Get); | ||
let mut response = ok_resp!(middle.call(&mut req)); | ||
assert!(!::json::<F>(&mut response).following); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...and this assertion looks commented out...
|
||
let perfect_match = crates::name.eq(q_string).desc(); | ||
if sort == "downloads" { | ||
query = query.order((perfect_match, crates::downloads.desc())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I guess sorting isn't in one place anymore, but I guess that's ok. This is better than it was!
I'm guessing later calls to order
override earlier ones, like in activerecord?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, calls to order
override the earlier ones. It's actually unlike Active Record (.reorder
replaces earlier ones, .order
appends). The only method in Diesel which doesn't override earlier calls is .filter
.
Yeah I do want to do that eventually, but I think we also need to put some thought into which ordering takes precedence when, and how we convey what's going on in the UI as well. So it's not quite literally just that, but I'm glad to know the backend is closer at least :) |
Ok, fair enough :) |
Hopefully this will be the largest one. ❤️ |
I decided to tackle this one next since we have an N+1 queries bug on
the max versions, it's a relatively high traffic endpoint, and the code
benefitted the most from Diesel.
There was probably more code added to support migrating the tests over
than to support the actual
index
function, but all those pieces willstart to get used as more endpoints are ported over. There were a few
tests that were hitting the followings and owners endpoints which I have
temporarily changed to hit the database directly instead.
Porting those endpoints would mean porting over more tests, which might
mean porting over more endpoints, etc. We didn't lose any coverage
overall, but we should still go back to hitting the endpoints directly
in tests when we can.