Skip to content

Commit 624ab10

Browse files
committed
controllers/krate/search: Build query ordering based on direction
1 parent 84f9152 commit 624ab10

File tree

1 file changed

+47
-16
lines changed

1 file changed

+47
-16
lines changed

src/controllers/krate/search.rs

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,18 @@ pub async fn list_crates(
116116
.left_join(versions::table.on(default_versions::version_id.eq(versions::id)))
117117
.select(selection);
118118

119+
let pagination: PaginationOptions = PaginationOptions::builder()
120+
.limit_page_numbers()
121+
.enable_seek(true)
122+
.gather(&req)?;
123+
let is_forward = !matches!(pagination.page, Page::SeekBackward(_));
124+
119125
if let Some(q_string) = &filter_params.q_string {
120126
if !q_string.is_empty() {
121127
let q_string = q_string.as_str();
122128

123129
let sort = sort.unwrap_or("relevance");
124130

125-
query = query.order(Crate::with_name(q_string).desc());
126-
127131
if sort == "relevance" {
128132
let q =
129133
plainto_tsquery_with_search_config(TsConfigurationByName("english"), q_string);
@@ -139,7 +143,11 @@ pub async fn list_crates(
139143
default_versions::num_versions.nullable(),
140144
));
141145
seek = Some(Seek::Relevance);
142-
query = query.then_order_by(rank.desc())
146+
query = if is_forward {
147+
query.order((Crate::with_name(q_string).desc(), rank.desc()))
148+
} else {
149+
query.order((Crate::with_name(q_string).asc(), rank.asc()))
150+
}
143151
} else {
144152
query = query.select((
145153
ALL_COLUMNS,
@@ -152,6 +160,11 @@ pub async fn list_crates(
152160
default_versions::num_versions.nullable(),
153161
));
154162
seek = Some(Seek::Query);
163+
query = if is_forward {
164+
query.order(Crate::with_name(q_string).desc())
165+
} else {
166+
query.order(Crate::with_name(q_string).asc())
167+
}
155168
}
156169
}
157170
}
@@ -163,31 +176,49 @@ pub async fn list_crates(
163176
// to ensure predictable pagination behavior.
164177
if sort == Some("downloads") {
165178
seek = Some(Seek::Downloads);
166-
query = query.order((crate_downloads::downloads.desc(), crates::id.desc()))
179+
query = if is_forward {
180+
query.order((crate_downloads::downloads.desc(), crates::id.desc()))
181+
} else {
182+
query.order((crate_downloads::downloads.asc(), crates::id.asc()))
183+
};
167184
} else if sort == Some("recent-downloads") {
168185
seek = Some(Seek::RecentDownloads);
169-
query = query.order((
170-
recent_crate_downloads::downloads.desc().nulls_last(),
171-
crates::id.desc(),
172-
))
186+
query = if is_forward {
187+
query.order((
188+
recent_crate_downloads::downloads.desc().nulls_last(),
189+
crates::id.desc(),
190+
))
191+
} else {
192+
query.order((
193+
recent_crate_downloads::downloads.asc().nulls_first(),
194+
crates::id.asc(),
195+
))
196+
};
173197
} else if sort == Some("recent-updates") {
174198
seek = Some(Seek::RecentUpdates);
175-
query = query.order((crates::updated_at.desc(), crates::id.desc()));
199+
query = if is_forward {
200+
query.order((crates::updated_at.desc(), crates::id.desc()))
201+
} else {
202+
query.order((crates::updated_at.asc(), crates::id.asc()))
203+
};
176204
} else if sort == Some("new") {
177205
seek = Some(Seek::New);
178-
query = query.order((crates::created_at.desc(), crates::id.desc()));
206+
query = if is_forward {
207+
query.order((crates::created_at.desc(), crates::id.desc()))
208+
} else {
209+
query.order((crates::created_at.asc(), crates::id.asc()))
210+
};
179211
} else {
180212
seek = seek.or(Some(Seek::Name));
181213
// Since the name is unique value, the inherent ordering becomes naturally unique.
182214
// Therefore, an additional auxiliary ordering column is unnecessary in this case.
183-
query = query.then_order_by(crates::name.asc())
215+
query = if is_forward {
216+
query.then_order_by(crates::name.asc())
217+
} else {
218+
query.then_order_by(crates::name.desc())
219+
};
184220
}
185221

186-
let pagination: PaginationOptions = PaginationOptions::builder()
187-
.limit_page_numbers()
188-
.enable_seek(true)
189-
.gather(&req)?;
190-
191222
let explicit_page = matches!(pagination.page, Page::Numeric(_));
192223

193224
// To avoid breaking existing users, seek-based pagination is only used if an explicit page has

0 commit comments

Comments
 (0)